LISP Scheme

このエントリーをはてなブックマークに追加
1デフォルトの名無しさん
'(hello world)
2デフォルトの名無しさん:2001/04/13(金) 23:46
ちょっと質問なんですが、
(lambda (init)
(let loop ((var init))
...(if (...) x)
... (loop (- var 1))))
こういうループをxの時点で中断したいんだけど、何か良い手段はありますか?
32:2001/04/14(土) 00:15
書き忘れましたが言語はSchemeです。
4デフォルトの名無しさん:2001/04/14(土) 00:27
山本和彦氏の「リスト遊び」を読んで、Lispに興味を持ったんだけど、
次に読むべき本を教えてください。
本屋に逝って探してみたけど、Lisp系の本って少ないねー。
5デフォルトの名無しさん:2001/04/14(土) 00:37
>>2
(lambda (init)
(let loop ((var init))
(if (...)
x
(loop (- var 1)))))
(display "上のようにすると(...)が#tだとループを抜けて
xが返されるけど。")
(newline)
6デフォルトの名無しさん:2001/04/14(土) 00:37
>>4
今だと図書館とかの方が揃うと思います。大学や専門の購買とか。
ちょっと前、〜(なんとか)LISP言語 第3版 (上・下2冊 緑色の表紙)
っての借りて読んだけど、CommonLispも含めてかなり詳しく載っていました。
下巻(応用)は難しくて良く分かんなかったけど(汗
7デフォルトの名無しさん:2001/04/14(土) 00:42
>>4
Schemeでよければ、
「プログラミング言語の構造と解釈 第2版」は?
82:2001/04/14(土) 00:43
>>5
なるほど。loopをifスコープ(?)の中で書いても良かったんですね。
有難うございます。
SchemeにはC言語でいうbreak/continueとかが無いみたいなんで困ってました。
(継続使えとか言われそうですが)
92:2001/04/14(土) 01:07
;継続を使ったbreak/continue
(define for (lambda (start end body)
  (call/cc (lambda (break)
    (letrec
     (
      (loop
       (lambda (i)
        (if (< i end)
         (begin
          (call/cc
           (lambda (continue)
            (body i break continue)))
          (loop (+ 1 i))))))
     )
     (loop start))))))
102:2001/04/14(土) 01:08
;>>9の使い方
(for 0 10
 ;body
 (lambda (i break continue)
  (cond
   ((= i 7) (break))
   ((odd? i) (printf "i=%d o" i))
   (else (printf "i=%d e" i))
  )
  (if (= i 3)
   (continue))
  (newline)))
112:2001/04/14(土) 01:11
ってのが見つかったんですが、なんか難しいですね。
(まだインデントの付け方もよくわからない・・)
12デフォルトの名無しさん:2001/04/14(土) 02:19
lisp 文法的に valid なアスキーアート気盆
13>12:2001/04/14(土) 02:52
まずおまえがやってみせろ
14>4:2001/04/14(土) 14:01
Lisp入門 中西正和 近代科学社 ISBN4-7649-0107-2
昔、古本屋で300円だったんで買ったんだけど。
あんまり良い本じゃないかも
Lispプログラミング 中山隆 杉山武司 オーム社 ISBN4-274-07377-7
これも古本屋で450円だったんで買ったんだけど。
あんまり良い本じゃない
どっちもCommonLisp以前の時代の本みたい。

大きい図書館いった方が早いかもね。

それと、Schemeならインターネットで日本語の資料結構揃いますよ。R
15>4:2001/04/14(土) 14:04
プログラミング言語Scheme
http://www.sci.toyama-u.ac.jp/~iwao/Scheme/scheme.html
こっから色々収集できます。
1615:2001/04/14(土) 14:11
LISPの日本語のポータルサイトってあります?>>15みたいな所
Schemeは(比較的)良く見つかるんだけど
17デフォルトの名無しさん:2001/04/14(土) 23:58
ポータルサイトじゃないけど
Lisper への道
http://www.geocities.co.jp/SiliconValley-Oakland/1680/rakup.html
18デフォルトの名無しさん:2001/04/15(日) 18:14
LISPってインデントってどういう風にするものなんでしょう
いまいち読みやすくなりません。
本とかで見かける、
(expr ()
 (let
  ((var...
   ))
  ))) ;←この最後にまとめて閉じ括弧付けるのも納得いかないし。
やっぱ中括弧'(' ')'だけだから読みづらいでしょうね。
なんとかならないもんでしょうか
19デフォルトの名無しさん:2001/04/17(火) 04:23
>16
まったく同感です。情報も少なすぎです。

Windowsでも動くFreeソフトのCommonLISPはありませんか?
日本語がきちんと動く奴。

(reverse '(あ いうえ おか))→(おか いうえ あ)

と文字化けしないで、きちんと評価される奴。
チェックボックスなどのコントロールも容易に操作できる奴があるといいんですが?
どこへ行っても無さそうなので、今はXLISP-STATを使っています。
Schemeは一応パソコンに積んで有りますが、defunの使い方がLISPと違うようなので使っていません。
20デフォルトの名無しさん:2001/04/17(火) 09:50
>>19
xyzzyはいかがですか?
21デフォルトの名無しさん:2001/04/17(火) 20:07
>20

ありがとう。早速、試してみます。
VBのエディタにもなっているらしいので結構いいかも。
22#f:2001/04/17(火) 20:44
>>18 視覚的にはかなりつらいね。
つーことで、emacsを使わないと lispは読めない体に。
M-C-f とかないと。

括弧を入れ子ごとに色変えてくれるのとかあったけど、今一つ..
23デフォルトの名無しさん:2001/04/17(火) 21:56
>>19
GNU Common LISPは、元々日本人が作った処理系(らしい)なので
シンボル名に日本語が使えるような気がします。(未確認です・・)
24デフォルトの名無しさん:2001/04/17(火) 22:01
今から学習するならCommonLispが乗っかってるxyzzyが良さそうですね。
MLもあるみたいだし。
http://www.jsdlab.co.jp/~kei/xyzzy/
http://www.netlaputa.ne.jp/~henmi/lisp/xyzzy/
25デフォルトの名無しさん:2001/04/17(火) 22:08
26デフォルトの名無しさん:2001/04/17(火) 22:22
>>19
SchemeのdefineはLISPのdefunとたいして変わらないと思います。
(define proc (lambda (param...) body)または
(define (proc param...) body)
(define sym body)
LISPにあるauxとかoptやらはありませんけど。
その他、LISPの(setq 〜)の代わりに(define 〜)、
破壊操作は(〜!)とか。
rplaca→set-car!
rplacd→set-cdr!
(〜p )→(〜? )
progn→begin
など
27デフォルトの名無しさん:2001/04/18(水) 01:34
>>23
試したところ日本語シンボルOKだった。GCL 2.2.1。
もとになったKyoto Common LISPを作った萩谷先生の文章が
他のスレで紹介されてた。
28デフォルトの名無しさん:2001/04/18(水) 09:33
>>26
setqの代わりはset!……
29デフォルトの名無しさん:2001/04/19(木) 20:55
LISP/Schemeでの双方向リストの実装について質問なんですが、
(item next prev)というリンクを作ると、リストが巡回構造になって
このままだとリストがまともに表示されなくて困ってます。
こういう場合、どういう風に作るのが良いんでしょうか。
次にSchemeのソース載せます。
3029:2001/04/19(木) 20:56
(define-macro create-que (lambda (l)
 (list 'define (cadr l) ''(() ()))))
(define (que-createitem item next prev)
 (cons item (cons next prev)))
(define (que-front list) (car list))
(define (que-back list) (cadr list))
(define (que-setfront list link) (set-car! list link))
(define (que-setback list link) (set-car! (cdr list) link))
(define (que-next link) (if (null? link) '() (cadr link)))
(define (que-prev link) (if (null? link) '() (cddr link)))
(define (que-setnext link next) (set-car! (cdr link) next))
(define (que-setprev link prev) (set-cdr! (cdr link) prev))
3129:2001/04/19(木) 20:57
(define (que-push list item)
 (let
  ( (old (que-front list))
   (new (que-createitem item '() '()))
  )
  (que-setprev new old)
  (if (null? old)
   (que-setback list new)
   (que-setnext old new))
  (que-setfront list new)
  (car new)))

(define (que-pop list) ; as item
 (let ((old (que-front list)))
  (if (null? old)
   #f
   (begin
    (if (eq? old (que-back list))
     (que-setback list '()))
    (que-setfront list (que-prev old))
    (if (not (null? (que-prev old)))
     (que-setnext (que-prev old) '()))
    (car old) ;item
   ))))
3229:2001/04/19(木) 21:01
pushback,popbackは30の逆操作なので省略します。
で、
(create-que dlist)
=>dlist
(que-push dlist 'a)
=>a
(que-push dlist 'b)
=>b
;ここでdlistをうっかり表示させてしまうと出力の無限ループ
;になってしまう。
dlist
=>(b () a (b () a (b () a (b () a (b () a (b () a (b ....
これをなんとかしたいんです。
3329:2001/04/19(木) 21:03
あ、データ構造は
dlist : (front back)
link : (item (next . prev))
です。
34Sage:2001/04/20(金) 02:58
Schemeって「すきーむ」って読むんですか。
「しぇーめ」だと思ってた……。
http://www.stdio.h.kyoto-u.ac.jp/~hioki/gairon-enshuu/SchemeNotes/scheme.html
35いつでもどこでも名無しさん:2001/04/20(金) 04:48
表示させなきゃいいんじゃ.>>29
つーか普通の処理系は表示するとき nest levelで制限してない?
3629>35:2001/04/20(金) 19:48
やっぱそれしかないですか・・。
自作物なのでなんの制限もかけてなかったり(汗
37デフォルトの名無しさん:2001/04/20(金) 22:00
閉じ括弧の対応をいちいち調べるのが面倒なんで色々調べてみたら、
シンタックスシュガー(?)として'[' ']'を使う書き方がある様ですね。
正式名称知りませんが。

・[a]は(a)と同じ意味。
・[は(と同じ様にネストできる。'(a (b (c [d (e [f]]] => (a (b (c (d (e (f))))))
・[を置いておくと、)が閉じてない場合]の位置で強制的に[に対応するまで閉じる。
・対応しない]がある場合、閉じてない'('括弧を全て閉じる。
って解釈でいいのかな。(自身なし
3837:2001/04/20(金) 22:00
例えば31のque-popを[]を使う書き方に書き換えると、
(define (que-pop list) ; as item
 (let [(old (que-front list]
  (if (null? old)
   #f
   (begin
    [if [eq? old (que-back list]
     (que-setback list '()]
    [que-setfront list (que-prev old]
    [if [not (null? (que-prev old]
     (que-setnext (que-prev old) '()]
    (car old]
うーん、括弧の対応付けが判って多少は良くなったかな?
ただ、初めて見る人にとっては、「なんじゃこりゃ?」って印象でしょうね・・(汗
39デフォルトの名無しさん:2001/04/20(金) 23:12
スーパー括弧 [] はコードを入力するときには使うけど、
pp するときには普通の表示が良いなあ。
4037:2001/04/20(金) 23:29
「スーパー括弧」
ttp://www.asahi-net.or.jp/~LI6S-YSMR/argovent/argove14.html
「超括弧」
ttp://plaza10.mbn.or.jp/~lisp/intro.htm
検索でそれぞれ一件づつ引っかかりました。
あんまりないのかな
英語だとsuper brace?(でも見つかりませんでした

>>39
ppというか、readの段階で普通の()に変換されれば問題無いかと。
41デフォルトの名無しさん:2001/04/21(土) 05:40
[]挟むだけでなんかメリハリが付く感じで良いですね>38
正直()だけだと見づらい。
こういうの突き詰めてくとM言語っぽくなる?
42デフォルトの名無しさん:2001/04/22(日) 06:35
age
43デフォルトの名無しさん:2001/04/22(日) 10:58
>今から学習するならCommonLispが乗っかってるxyzzyが良さそうですね

さっそく、使ってみました。うーむ。これは、かなり強力なエディタですね。
日本版Emacsといった感じ。どうもありがとう>20、24
44デフォルトの名無しさん:2001/04/24(火) 01:49
だれかマクロの使い方教えてちょ
45デフォルトの名無しさん:2001/04/24(火) 16:53
Scheme,List
線形リストをバランス木(AVL木など)に変換する方法を考えています。
英語のホームページを片っ端から調べてみても見つかりませんでした。
お分かりになる方はよろしくお願いします。

46デフォルトの名無しさん:2001/04/24(火) 18:35
なんて読むんだ>xyzzy
臭い爺?
47デフォルトの名無しさん:2001/04/24(火) 19:10
>なんて読むんだ>xyzzy

妻子と読むのですといいですね。
4844:2001/04/24(火) 21:19
誰も乗ってくれないので色々と思考錯誤した結果
マクロってこういうことだったのね。
リスト生成→生成したリストを再評価

(define-macro マクロ定義 (lambda (l) (cons 'define-macro (cdr l]
(マクロ定義 λ (lambda (l) (cons 'lambda (cdr l]
(マクロ定義 もしもだよ (λ (l)
 (list 'if (cadr l) (caddr l) (cadddr l]

(もしもだよ (< 0 1) #t #f)
=>#t
49>45:2001/04/24(火) 21:30
バランス木かどうかわかりませんが、SLIBっていうライブラリの中にあった様なきがします。
あとは、
http://www.cs.indiana.edu/scheme-repository/SRhome.html
http://www.cs.cmu.edu/afs/cs.cmu.edu/project/ai-repository/ai/lang/scheme/0.html
この辺にコードが大量にある様です。(B-Treeとか見かけました)
50>45:2001/04/24(火) 21:32
あと、有名なサイトは>>15のサイトから辿れます。
51デフォルトの名無しさん:2001/04/24(火) 22:24
>48
Cの#defineと同じだよ。
機能がむちゃ強力なだけ。
FORTRAN表記をLispに直せちゃうくらい強力だが…
5244>51:2001/04/24(火) 23:10
ですねー。
マクロの引数の解釈に手間取りましたが(汗
(car l) => もしもだよ
(cadr) =>(< 0 1)
(caddr) =>$t
(cadddr) =>$t
構文拡張した気分になれます。

if->もしもだよみたいな単純なsyntax名の置き換えなら
(マクロ定義 もしもだよ (lambda (l) (cons 'if (cdr l]
で良いみたいですが。
5344:2001/04/24(火) 23:20
処理系が日本語に対応してれば、
日本語Schemeなんかも無理なく作れますね(汗

(マクロ スタック生成 (λ (仮引数)
 (リスト '定義 (かあだ 仮引数) ''()]

(マクロ 積む
 (λ (仮引数)
  (リスト '更新! (かあだだ 仮引数)
   (リスト 'コンス (かあだ 仮引数) (かあだだ 仮引数]

(マクロ 捨て
 (λ (仮引数)
  (リスト '並列レット
   [リスト (リスト '捨てるモノ (かあだ 仮引数]
   (リスト 'もしもだよ (リスト 'ぬる? '捨てるモノ) 偽
    (リスト '複文
     [リスト '更新! (かあだ 仮引数) (リスト 'くだ '捨てるモノ]
     (リスト 'かあ '捨てるモノ]
;test
(表示 'スタックのテスト)(改行)
(スタック生成 a)
(表示 a)(改行)
(表示 (積む 'x a))(改行)
(表示 (積む 'y a))(改行)
(表示 (積む 'z a))(改行)
(表示 (捨て a))(改行)
(表示 (捨て a))(改行)
(表示 (捨て a))(改行)
(表示 (捨て a))(改行)
(表示 a)(改行)
54デフォルトの名無しさん:2001/04/24(火) 23:45
>>52
マクロではないですが、単純なsyntax名の置き換えなら
define文でもできます。(あたりまえかな)

(define 定義します define)
(定義します もしもだよ if)
5544>54:2001/04/25(水) 00:11
うちの処理系ではclosureやprimtiveはdefine置き換えできますが、
ifやletみたいなsyntaxだとエラー吐いちゃうんでマクロにしてます。
Iispのfexpr型の様なlambdaがあればできそうですが。
5654>55:2001/04/25(水) 00:26
Linux上のguileとSTkではエラーになりません。
R5RSとかではどうなってるんだろう。
5755>56:2001/04/25(水) 01:54
あ、
(define もしもだよ if)
がエラーになるってのは、単に↓を評価した場合
if
=>error:Unbound symbol 'if
これがインプリメントされてないからです。
いいかげんに作ってあるので・・(環境を返す様にすれば直る)
R5RSみても良く判りませんでした(→多分マクロが返る)
「形式的シンタックス」とか、後ろの方意味不明・・(汗
58デフォルトの名無しさん:2001/04/25(水) 22:38
あげ
59デフォルトの名無しさん:2001/04/25(水) 22:50
かあだだってなんだよ(w
caddrか。
そういやこれ日本語にするとなにになるんだっけ?
60デフォルトの名無しさん:2001/04/25(水) 23:02
頭体体
61デフォルトの名無しさん:2001/04/25(水) 23:08
顔駄目体体
62>61:2001/04/25(水) 23:28
三原じゅうんこ!!
63デフォルトの名無しさん:2001/04/26(木) 02:28
「三番目」か?>>59
LISPはcaxxrの代わりに
first second third forth fifth sixth seventh eighth ninth tenth
がある。
じゃあ、cdxxrとかは何よ、って思うけど。
64デフォルトの名無しさん:2001/04/26(木) 02:55
car かー
cdr くだー
cadr かだー
cdar くだあー
caar かあー
cddr くだだー
65デフォルトの名無しさん:2001/04/26(木) 03:30
まともに印字可能なリスト表現が
(a b c d) => (a .(b .(c .(d .()))))
の様になってることから、
普通car側のネストってしないものなんでしょうか。
(((((). d). c). b). a)
こうなるんですが。見ずらい・・
66デフォルトの名無しさん:2001/04/26(木) 17:22
アクセス用の関数も同時に作ってやるだろ、そういうときは。
67デフォルトの名無しさん:2001/04/26(木) 19:19
Lispはきれいだとか、意味論的にクリアだとか聞いたことがありますが,
構造化されたある程度大きなプログラムを書けるのでしょうか?

僕は結構OOPについては詳しいつもりでなんですが、
OOPとLISP系(関数型)ってどっちが美しいですか?
ぼくは
LISPの美しさがよく分かりません、っていってもぱっと見の印象もあるんだけど
68デフォルトの名無しさん:2001/04/26(木) 19:30
>>67
自己スレです
意味論的にクリアなのはSchemeか?
69>66:2001/04/26(木) 23:17
やっぱりそういった方法でやるしかないですか。
画面出力の時だけcdrネストに直せばいいかな
70>67:2001/04/26(木) 23:25
美しいかわかりませんが、
データと関数の相互変換が自然に行なえるのは良いと思います。
それと、破壊操作やprimitive以外は全てlambda式で表現できるとか。
(define-macro compound-statement :複文のマクロ定義
 (lambda (l)
  (list (cons 'lambda (cons '() (cdr l)]

(compound-statement '式1 '式2 ...)
71>67:2001/04/26(木) 23:35
あと大きなプログラムについては、型付けが弱い部類の言語なので、
モジュール毎に分けたり単体テストなどをちゃんとやらないと
直ぐに破綻すると思います。(型は実行時に判定するしか無いので。)
また、ネストする括弧は人間にはかなり見ずらいので、
なんらかの対策をする必要を感じると思います。
(超括弧[]やエディタの機能を使うとか、構文の単純化など)
72>67:2001/04/26(木) 23:40
幸い、マクロ機能が強力なので、工夫すればOO風の記述も
可能になると思います。
(実際、ほとんどの処理系は初めからOO拡張している様です)
73>68:2001/04/27(金) 00:35
Schemeでは末尾再帰のループ展開が言語側で正式にサポートされています。
これはlispには無い様です。(lispでは普通whileなどの制御構文などを使う)
よってSchemeでの外部ループは再帰呼出しで記述するのが一般的らしいです。
また、制御構造自体は>>70の様にlambdaで置き換える事ができます。
lispにある脱出系制御文(大域goto、catch/throw/break/returnなど)は
*継続*という概念で定義できるみたいです。(反則的な気がしますが)
74デフォルトの名無しさん:2001/04/27(金) 00:52
(call-with-current-continuation
75デフォルトの名無しさん:2001/04/27(金) 02:11
lispって関数型っていわれるといやーん。
CLOSなんて object systemもあるんだし。
Smalltalk並みに柔軟な、自分自身に手を入れられる環境が魅力では。
と言うことで単なる schemeはあまり触ってなかったり。
仕様的に美しいのは納得するんだけどねえ。
76デフォルトの名無しさん:2001/04/27(金) 02:27
オンライン上で読める文献
アルゴリズム言語Schemeに関する第五改訂報告書(R5RS)
http://www.sci.toyama-u.ac.jp/~iwao/Scheme/r5rsj/html/r5rsj_toc.html

Common Lisp the Language, 2nd Edition(英語)
http://www.cs.cmu.edu/afs/cs.cmu.edu/project/ai-repository/ai/html/cltl/cltl2.html

Structure and Interpretation of Computer Programs(SICP)(英語)
http://mitpress.mit.edu/sicp/full-text/sicp/book/book.html
7774:2001/04/27(金) 04:32
)
78デフォルトの名無しさん:2001/04/27(金) 07:26
>>73
Common Lispでも普通はコンパイラが末尾再帰を処理してくれる。
コンパイルしないとスタックオーバーフローになってもコンパイルすればOKな事が多い。
79デフォルトの名無しさん:2001/04/27(金) 23:37
call/cc>74
80Be名無しさん:2001/04/27(金) 23:37
Scheme使ってる人で「計算機プログラムの構造と解釈」を読んだことある人います?
これよんで感動しました。お勧めです。
81デフォルトの名無しさん:2001/04/27(金) 23:55
>>76の3番目のリンクがそれのオンラインで読めるやつだよ>>80
英語だけど。
訳本はなかなか図書館にも置いてないなあ。
82デフォルトの名無しさん:2001/04/28(土) 00:08
LispやSchemeで複数行のコメント付けるにはどうしたらいいですか?
;←しかないですか?
8382:2001/04/28(土) 00:12
あと、C言語の
#ifdef __UNIX__
;
#else
;
#endif
の様な物は無いでしょうか。
84デフォルトの名無しさん:2001/04/28(土) 01:29
>>80
というか「読んだ人が使っている」というくらい普通に読んでると思うが。
85デフォルトの名無しさん:2001/04/28(土) 01:35
Scheme Requests for Implementation(SRFI)
http://srfi.schemers.org/
86>82:2001/04/28(土) 01:41
例えばですが、/*〜*/を解釈する様にreadを上書きするとかはできる様です。
SLIBのtrnscrpt.scmを見ていてそう思いました。
87>82:2001/04/28(土) 01:46
がんばれば#ifdef〜#endifも自分で作れるんじゃないかと思います。
88デフォルトの名無しさん:2001/04/28(土) 03:40
>>83 CommonLispにはあったよ。でも忘れてるのでsage
89デフォルトの名無しさん:2001/04/30(月) 03:39
Schemeで構造体とかって作れるでしょうか。

(define-struct hoge '(method1 member1 member2))
=>hoge ;構造体の定義
(define hoge1 (make-struct hoge))
=>hoge1 ;インスタンスの生成
(member-set! hoge1 member1 'member1-value)
(member-get hoge1 member1) ;メンバのアクセサ
=>member1-value
(method-call hoge1 method1 param)
とか。これぐらいならマクロで作れそうですが、classとなると・・
(define-class
 hage ;hageクラス
 (super hoge . ()) ;hogeから単一継承
 '(method1 member1 member2)) ;hageのメンバ
(define-method
 (hage method1 msg) ;method1の定義 msgは引数
 (display (member-get self member1)) ;member1の値の表示
)
(member-set! hoge1 member1 member1-value)
(method-call hage1 method1 param)
こんな感じでしょうか。やっぱり構造体とあんまし変わらないのかな。
それにしても、なんか読みにくいなあ・・
90デフォルトの名無しさん:2001/04/30(月) 23:56
>89
MITの授業内容のサイトらしいけど、OOPのサンプルがある。(SICP参照)
http://www.ai.mit.edu/courses/6.001-99Spring/lectures/lec15/lec-oops-duane/lec-oops-duane.html
91デフォルトの名無しさん:2001/05/01(火) 00:47
多態までのサンプル。結構短い・・。
http://www.angelfire.com/tx4/cus/shapes/scheme.html
92デフォルトの名無しさん:2001/05/01(火) 01:05
初心者の質問です。
LISPって大学や研究機関、あるいは個人の趣味以外で
仕事で利用されたりしてるのでしょうか?

sawfish,emacsは除いて。
9389:2001/05/01(火) 01:15
ありがとうございます。 >91-92
Schemeの標準的な構文で実現できるとは思いませんでした。

でも疑問に思ったんですが、↓のletで生成されるxとyの
入れ物の継続期間が謎なんですけど・・
↓のmake-shapeはclosure(lambda以降)を返すんですよね?
こんなことして平気なんでしょうか。
(>>91のサンプル)
(define (make-shape newx newy)
 (let (
  (x newx)
  (y newy))
  (lambda (method parms)
   (cond ; accessors for x & y
   ((eq? method 'getx) x)
   ((eq? method 'gety) y)
   ((eq? method 'setx) (set! x parms))
   ((eq? method 'sety) (set! y parms)) ; move the x & y coordinates
   ((eq? method 'moveto)
     (set! x (car parms))
     (set! y (car (cdr parms))))
   ((eq? method 'rmoveto)
     (set! x (+ x (car parms)))
     (set! y (+ y (car (cdr parms))))))
   )))

(define s (make-shape 640 480))
(s 'getx '())
=>640
(s 'gety '())
=>480
94デフォルトの名無しさん:2001/05/01(火) 01:29
ACLを買った人いる?いくらなんだろ?
9589>92:2001/05/01(火) 01:32
わたしは残念ながら聞いたこと無いです。
LispやSchemeのコード納品する様な仕事ってどんなのでしょう(汗
cgiの部品としてperl/Pythonコードとかはある様ですが。
まあScheme->Cとか、変換ツールは結構出回ってる様なので、
元がLisp/Schemeって事例はあるかもしれません。
9689:2001/05/01(火) 01:56
>>90のMIT風の書き方の方
(cond->caseしただけですが)
(define (make-shape newx newy)
 (let (
  (x newx)
  (y newy))
  (lambda (method parms)
   (case method ; accessors for x & y
    ((getx) x)
    ((gety) y)
    ((setx) (set! x parms))
    ((sety) (set! y parms)) ; move the x & y coordinates
    ((moveto)
     (set! x (car parms))
     (set! y (car (cdr parms))))
    ((rmoveto)
     (set! x (+ x (car parms)))
     (set! y (+ y (car (cdr parms)))))
    (else (no-method))))))
letの辺りはよく分かりませんが、これをマクロでテンプレートにしたら
結構使えそうです。
9789:2001/05/02(水) 00:26
反応が無くて寂しい
98デフォルトの名無しさん:2001/05/02(水) 06:34
self(this)を使いたい場合
(define (make-shape newx newy)
 (let* (
  (x newx)
  (y newy)
  (self
  (lambda (method parms)
   (case method
    ((disp)
     (display*
      (self 'getx ())
      " "
      (self 'gety ())
      "\n"))
    ((self) self)
    ((getx) x)
    ((gety) y)
    ((setx) (set! x parms))
    ((sety) (set! y parms))
    ; :
    (else (no-method))))))
  self))
(define shape (make-shape 640 400))
(shape 'disp ())
640 400
99デフォルトの名無しさん:2001/05/02(水) 10:31
>>94
Professional版が414,750円,Enterprise版が1,092,000円です.
ちょっと高いね.
100>99:2001/05/03(木) 00:25
ショック!個人で買うには辛いわ。
でも情報サンキュー>99
101デフォルトの名無しさん:2001/05/03(木) 00:41
lisp/schemeとかのインデントってどうやるのが定説なんですか?
CならK&R、BSD、GNUと色々ある様ですが・・
とりあえずわたしは下の様な感じで落ち着きました。
(↓は全角空白=半角空白2文字)
(define (func param)
 (let (
  (var1 init1)
  (var2 init2))
  (cond ;condはテスト式が複数あるので字下げする
   ((eq? var1) (set! var1 var2)) ;一文で画面に収まるならそのまま書く
   ((eq? var1) ;複数行なら下げる
    (set! var1 var2)
    (set! var1 var2))
   (else ;#t
    (set! var1 var2)
    (set! var1 var2)
    )) ;condはelseでかならず終るので括弧をまとめる
  ;←letブロックは、まだなにか付け足すかも知れないので
  ;括弧を下げる
 )) ;let
#ネタ不足です(汗
#hashテーブルでも作ろうかなあ・・
102デフォルトの名無しさん:2001/05/03(木) 00:42
>>100
100おめでとうございます〜。
103デフォルトの名無しさん:2001/05/03(木) 00:54
>>99
高いですね(汗
需要があんまりないからかも。(汗だく
速度とかを問題にしない限り、自作できちゃうからかな・・
104デフォルトの名無しさん:2001/05/03(木) 01:19
>>96 のletの意味がようやくわかりました。
Schemeには環境リストというものが存在します。
(環境リストは(interaction-environment)などのプリミティブで参照可能)
変数や関数の

>>96 の (lambda (method parms)〜) に入った時点で、
環境リストの状態は(処理系にもよりますが)下の様になります。

`( ;↓closureの環境…(1)
 ((method . methodの実引数) (parms . parmsの実引数))
  ;↓letの環境
 ((x . ,newx) (y . ,newy)))
  ;↓グローバルな環境
 (...
 (car #<PRIMITIVE >)))

これを踏まえると、つまりmake-shapeを呼出した時に返るclosureの
環境は(1)の地点にあるので、そのままletの環境も巻き込まれると
言う事です。巻き込んだ環境はclosureへ一緒に束縛されます。

(Cで同じ事をしようとすると、子関数のスタック変数のアドレスを
保持したポインタを返す様な形になり意味が無い。
子関数のスタックフレームを持ち帰るような事なので、Cの仕様では無理。)
105104:2001/05/03(木) 01:23
補足
>変数や関数の
→無視
>Cの仕様では無理
→Cでも処理系依存な方法ですがスタックアドレスを取得して、
フレームをコピーすれば可能です。
106104:2001/05/03(木) 01:26
つまり継続が使えるScheme独特のコードと言うことです。
(LispだとCと同様な事が起る。)
107104:2001/05/03(木) 01:27
ああ、
>(LispだとCと同様な事が起る。)
これは確認したわけでは無いので違ってたらすいません。
108104:2001/05/03(木) 01:33
これがあるお陰で、Lispでは専用の構文が用意されている構造体、
クラスも、Scehmeでは限られた言語仕様の中で表現できます。
109デフォルトの名無しさん:2001/05/03(木) 03:06
110デフォルトの名無しさん:2001/05/03(木) 12:55
>>108
少なくともCommon Lispならできるよ。
111104>110:2001/05/03(木) 19:20
なんのことですか?
letの環境の辺りの事かな?
112104>110:2001/05/03(木) 19:42
一応、GUY L.STEELE JR.のCommonLISP第2版 (日本語訳)の本は
持ってるんですが、この本に書いてあります?
SchemeのR5RSだと抽象的すぎて書いてあったとしても
意味がつかめないんで・・
113デフォルトの名無しさん:2001/05/04(金) 03:22
ネタが無いんでhashテーブルでも

(define (hash obj) (object->number obj))
(define (hash-iter cmp obj tbl) ; as number or #f
 (let* (
  (num (vector-length tbl))
  (value (% (hash obj) num)))
  (if (cmp (vector-ref tbl value))
   value
   (let loop ((pos (+ value 1)) (neg (- value 1)))
    (cond
     ((and (>= pos num) (< neg 0)) #f)
     ((and (< pos num) (cmp (vector-ref tbl pos))) pos)
     ((and (>= neg 0) (cmp (vector-ref tbl neg))) neg)
     (else (loop (+ pos 1) (- neg 1))))
   ))
 ))

(define (find-hash-sub obj tbl)
  (hash-iter
   (lambda (pair) (or (null? pair) (eqv? (car pair) obj))) obj tbl))
114デフォルトの名無しさん:2001/05/04(金) 03:22
(define (make-hash num) (make-vector num))
(define (hash-length tbl) (vector-length tbl))

(define (add-hash-pair pair tbl)
 (let ((value (find-hash-sub (car pair) tbl)))
  (if (and (number? value) (null? (vector-ref tbl value)))
   (vector-set! tbl value pair)
   #f)
 ))

(define (add-hash obj data tbl)
 (add-hash-pair (cons obj data) tbl))

(define (find-hash obj tbl)
 (let ((value (find-hash-sub obj tbl)))
  (if (and (number? value) (not (null? (vector-ref tbl value))))
   (vector-ref tbl value) #f)
 ))
115デフォルトの名無しさん:2001/05/04(金) 03:23
(define-macro prog1
 (lambda (l)
  (list 'let (list (list 'r (cadr l)))
   (cons 'begin (cddr l))
   'r)))

(define (remove-hash obj tbl)
 (let ((value (find-hash-sub obj tbl)))
  (if (and (number? value) (not (null? (vector-ref tbl value))))
   (prog1
    (vector-ref tbl value)
    (vector-set! tbl value ()))
   #f)
 ))
116デフォルトの名無しさん:2001/05/04(金) 03:23
(define (rehash num tbl)
 (let (
  (v (make-hash num))
  (old (vector-length tbl)))
  (let loop ((n 0))
   (cond
    ((>= n old) v)
    ((or (null? (vector-ref tbl n))
       (add-hash-pair (vector-ref tbl n) v))
     (loop (+ n 1)))
    (else v))
  )))

(define (hash-count tbl)
 (let loop ((c 0) (n (- (vector-length tbl) 1)))
  (cond
   ((< n 0) c)
   ((null? (vector-ref tbl n)) (loop c (- n 1)))
   (else (loop (+ c 1) (- n 1))
   ))
 ))
117デフォルトの名無しさん:2001/05/04(金) 03:24
;テスト
(define h (make-hash 32))
(add-hash 'add add-hash h)
(add-hash 'remove remove-hash h)
(add-hash 'find find-hash h)
(add-hash 'rehash rehash h)
(add-hash 'make-hash make-hash h)
(define h (rehash (hash-count h) h))
(display* h "\n")
118デフォルトの名無しさん:2001/05/04(金) 03:27
補足
・hash表はvectorで、各要素はpairなのでvector->listすればassoc系が使えます。
・使う場合object->numberは自作してください。
119デフォルトの名無しさん:2001/05/04(金) 12:28
LISPの数少ない商用利用例
http://jp.franz.com/base/success_main.html
120118:2001/05/04(金) 21:09
バグ
・removeはaddの逆の順番で呼ばないと、あるパターンでうまく削除されない。
また削除できても後の要素ができなくなる可能性がある。
・rehashを行なうとaddした順番が失われるので正常に削除できくなる。
よってremoveはそのままでは使えません。
removeの時に近隣の要素のhash値を調べて適当な場所に移動させていく必要があります。
(※ここで言う「適当」とは「デタラメ」の事ではない)
121118:2001/05/04(金) 21:21
修正方法1
・rehashのロジックで削除要素以外を登録し直す。
→rehash分のコストが掛かる。実装は簡単。
修正方法2
>>120の「近隣の〜」を実装する。
→最悪、全ての要素を走査する必要がある。実装は面倒。

オープンアドレス法での要素の削除は、
あまり良い案が浮かびませんでした。
122118:2001/05/04(金) 23:52
修正版remove-hash
(define (vector-ncopy dst src num)
  (let loop ((i 0))
   (cond
    ((< i num)
     (vector-set! dst i (vector-ref src i))
     (loop (+ i 1)))
    (else dst))
  ))

(define (remove-hash obj tbl)
 (let (
  (i (find-hash-sub obj tbl))
  (num (vector-length tbl)))
  (if (and (number? i) (pair? (vector-ref tbl i)))
   (prog1
    (vector-ref tbl i)
    (vector-set! tbl i ())
    (vector-ncopy tbl (rehash num tbl) num))
   #f)
 ))
123デフォルトの名無しさん:2001/05/05(土) 01:00
>>119
AutoLisp(AutoCADの) や Cakewalk CAL は?
124>123:2001/05/05(土) 01:14
そういやCakewalkも内蔵スクリプト入ってましたね。
持ってるけど忘れてた。
125デフォルトの名無しさん:2001/05/05(土) 03:51
SchemeのObject指向のやり方については、ここに日本語で解説がありました。
(がいしゅつリンクですが。)

Schemeへの道(トップ)
ttp://www.stdio.h.kyoto-u.ac.jp/~hioki/gairon-enshuu/SchemeNotes/scheme.html
クロージャとオブジェクト
ttp://www.stdio.h.kyoto-u.ac.jp/~hioki/gairon-enshuu/SchemeNotes/closure-object.html
126デフォルトの名無しさん:2001/05/05(土) 04:04
>>123
AutoLISPは固有の関数も多いし、ここでは話題になりにくいかもね。
127デフォルトの名無しさん:2001/05/05(土) 20:05
age
128デフォルトの名無しさん:2001/05/05(土) 23:40
call/cc (call-with-current-continuation) の使い方でも

return文
(return-scope ... (return ... result) ...end )
return-scopeはbeginと同じ様に働くが、
途中にreturnを置く事でブロックを抜けられる点で異なる。
returnを抜けた場合、resultがreturn-scopeの返り値となる。
129デフォルトの名無しさん:2001/05/05(土) 23:41
;実装方法
(define-macro return-scope
 (lambda (l) `(call/cc (lambda (return) ,@(cdr l)))))
;または、
(define-macro return-scope
 (lambda (l)
   (list 'call/cc (cons 'lambda (cons (list 'return) (cdr l))))))

;;前者と後者は同じ意味。
;;`(backquote/quasiquote)の探索/展開が遅い処理系では、
;;後者の形式を使用する。
130デフォルトの名無しさん:2001/05/05(土) 23:44
;;return-scopeのテスト
(define (return-test)
 (return-scope
  (define (f i) (return (display* 'return i "\n") #t))
  (display* 1 "\n")
  (display* 2 "\n")
  (if #t #t
    (return (display* 'return 3 "\n") #f))
  (f 4)
  (display* 5 "\n")
 )
 (display* 6 "\n")
 #t
)
(return-test)
1
2
return 4
6
=>#t
131デフォルトの名無しさん:2001/05/05(土) 23:46
;;おまけ
(define (display* . l)
 (let loop ((x l))
  (cond
   ((pair? x)
    (display (car x))
    (loop (cdr x)))
   (else #t)
  )))
132デフォルトの名無しさん:2001/05/05(土) 23:49
>>128-130の(return-scope(return))は、
恐らくcall/ccの使い方としては一番単純な物です。
133デフォルトの名無しさん:2001/05/06(日) 00:01
call/ccの定義はそのまま書くと混乱するので、
上の様にマクロなどで隠蔽する事が推薦されます。
134デフォルトの名無しさん:2001/05/06(日) 06:33
格調高いね、ここ。
135デフォルトの名無しさん:2001/05/06(日) 08:47
厨房臭いねここ。
136デフォルトの名無しさん:2001/05/06(日) 21:56
age
137デフォルトの名無しさん:2001/05/06(日) 21:58
>>135-134
きみらもな
138デフォルトの名無しさん:2001/05/06(日) 22:09
lispにしてもschemeにしても、この板で使ってる人どれぐらいいる?
139デフォルトの名無しさん:2001/05/06(日) 22:26
確かにプログラマ板のlispスレと比べると雰囲気違うね。(w
140デフォルトの名無しさん:2001/05/06(日) 22:47
call/cc (call-with-current-continuation) の使い方その2

catch - throw文
(catch 'tag ... (throw 'tag ...) ... )
(catch 'tag ... (throw-value 'tag value) ... )

catch文にはtagというラベルが存在する以外はbeginと同じように働きます。
途中にthrow文を置くことで、tagと一致するcatchブロックを抜けることができます。
catchブロックは、先に実装したreturnブロックとは異なり、
複数のcatchブロック階層を一気に抜ける事ができます。
また、throwだけの記述をした関数に対して、呼出し側でcatahを行なう事もできます。
(throw 'tag ... ) を呼出すと、最後に評価した結果がcatchから返されます。
(throw-value 'tag value) はvalueを評価した結果がcatchから返されます。
141140:2001/05/07(月) 00:39
;実装方法
(define *catch-handler-stack* '())

(define (throw-value tag value)
 (let ((cont (assq tag *catch-handler-stack*))) ; as (tag . cont) or #f
  (cond
   (cont
    (set! *catch-handler-stack* (cdr (memq cont *catch-handler-stack*)))
    (apply (cdr cont) (list value)) ;; ((cdr cont) value))
   (else (error "cannot throw tag:" tag)))
 ))

(define-macro throw
 (lambda (l)
  `(throw-value ,(cadr l) (cons 'begin ,(cddr l)))))
142140:2001/05/07(月) 00:44
(define-macro catch
 (lambda (l)
  (let ((throw-cont (gensym)))
   `(call/cc
    (lambda ( ,throw-cont)
     (set! *catch-handler-stack*
      (cons (cons ,(cadr l) ,throw-cont) *catch-handler-stack*))
     (throw-value ,(cadr l) ,@(cddr l))
    )))))
143140:2001/05/07(月) 00:46
補足
・(gensym)は、環境に存在しないユニークなシンボルを生成する関数。
・*catch-handler-stack*の存在する場所は、
グローバル/ローカル環境どちらでも良い。
144140:2001/05/07(月) 00:49
;;おまけ
(define-macro throw1
 (lambda (l)
  `(throw-value ,(cadr l) (cons 'prog1 ,(cddr l)))))
145140:2001/05/07(月) 00:55
;;おまけ2
(define-macro catch1
 (lambda (l)
  (let ((throw-cont (gensym)))
   `(call/cc
    (lambda ( ,throw-cont)
     (set! *catch-handler-stack*
      (cons (cons ,(cadr l) ,throw-cont) *catch-handler-stack*))
     (throw-value ,(cadr l) (prog1 ,@(cddr l)))
    )))))
146140:2001/05/07(月) 00:58
おまけのthrow1、catch1 は、最初の評価結果を返す。
147140:2001/05/07(月) 01:00
>>134-139
ネタを何か書込んでください。
>>138
少なくともわたしは使ってます。
148デフォルトの名無しさん:2001/05/07(月) 21:34
age
149デフォルトの名無しさん:2001/05/09(水) 05:21
150デフォルトの名無しさん:2001/05/09(水) 23:57
151デフォルトの名無しさん:2001/05/10(木) 03:31
scheme :
(obj 'message param)
or (class_message obj param)
C
dispatch(obj, message, param)
or class_message(obj, param);
C++
obj->message(param);
or obj->receive(message, param);
考察
class_message形式や、
obj->messageは何を表してるのかわかりにくい。
152デフォルトの名無しさん:2001/05/10(木) 03:53
>>151
まあ確かに。
矢印を使うって発想はいいんだけど。逆の意味を連想する。
せめて、obj<-message(param);
だったらいいのにね。(と、なにかの本にも書いてあった)
153デフォルトの名無しさん:2001/05/10(木) 04:04
矢印は方向を表すためだけに使いたい。>152
obj <- message param
message param -> obj
とか。
154デフォルトの名無しさん:2001/05/10(木) 04:15
>>153
152はそういうこと言ってるんじゃないのか?
155デフォルトの名無しさん:2001/05/10(木) 04:26
>>152
'->'は元々、構造体メンバへのポインタアクセスっつう意味しかない、
低レベルな発想だからねえ・・
思わずこうしたくなるね。
obj.receive(message, param);
156153:2001/05/10(木) 04:31
なるほど>154
157デフォルトの名無しさん:2001/05/10(木) 05:08
>>82
#|〜|#というのがあった気が。処理系毎の独自拡張みたいだけど。

#|ここからコメント

ここまでこめんと|#
158デフォルトの名無しさん:2001/05/10(木) 09:25
小なり→単項演算子マイナスと紛らわしいから、
パースできないね。残念だったね。
個人的今のでいいやって感じだけど。
159デフォルトの名無しさん:2001/05/10(木) 14:26
>>151
(class_message obj param) はわかるんですが (obj 'message param)
は可能なんですか?LISPでも可能ですか?
160デフォルトの名無しさん:2001/05/10(木) 20:10
age
161デフォルトの名無しさん:2001/05/10(木) 21:39
>>159

151じゃないけど……

・schemeなら関数呼び出しフォームの先頭要素を普通に評価してその値を関数
として使うから、可能

・common lispだとあくまで((lambda ()) foo ...)と(symbol foo...)が関数
呼び出しフォームなだけだから、ムリ

です。この辺もschemeが普通のlispと比べて美しいところのひとつ。
162デフォルトの名無しさん:2001/05/10(木) 22:14
Scheme VS Lispな話も聞きたいなぁ。
どっちが優れてるかで言ったらやっぱりSchemeの圧勝?
163さすがMIT:2001/05/10(木) 23:16
>>7
古くてスマソ。「計算機プログラムの構造と解釈 第二版」
確かに名著。ただし非常に高度。読むときは本気で取り組まんとツライ。
164159:2001/05/10(木) 23:19
>>161 サンクス、クレクレでスマソだが気が向いたら

(obj set_hoge "foo")
(obj hoge) => foo
(obj set_hoge "bar")
(obj hoge) => bar

となるような obj を簡単に定義してみてもらえないだろか。

漏れは、schemeで継続を使いこなすとカッコイイと聞いてschemeに興味
を持ったモンで、Schemeは厨房以下、emacs-lispは厨房、ほんとは
Ruby好きかも。
165159:2001/05/10(木) 23:25
>>164 はちょと訂正

(obj 'set_hoge "foo")
(obj 'hoge) => foo
(obj 'set_hoge "bar")
(obj 'hoge) => bar
166デフォルトの名無しさん:2001/05/10(木) 23:45
>>164
(define (make-hoge init)
 (let ((hoge init))

  ;; method set-hoge
  (define (set-hoge parms)
   (cond
    ((null? parms) #f)
    ((string? (car parms))
     (set! hoge (string->symbol (car parms))))
     hoge ;; hogeを返す
    (else
     (set! hoge (car parms))
     hoge ;; hogeを返す
    ))) ; set-hoge

  ;; message dispatcher
  (lambda (message . parms)
   (case message
    ((hoge) hoge) ; hogeを返す
    ((set_hoge) (set-hoge parms))
   ))
 ))

(define hoge_instance (make-hoge 'hoge))
(hoge_instance 'set_hoge "foo")
(hoge_instance 'hoge) ;=> foo
(hoge_instance 'set_hoge "bar")
(hoge_instance 'hoge) ;=> bar
167166:2001/05/11(金) 00:16
すいません。正しくはこうでした。
 ;; method set-hoge
  (define (set-hoge parms)
   (cond
    ((null? parms) #f)
    ((string? (car parms))
     (set! hoge (string->symbol (car parms)))
     hoge ; hogeを返す
    )
    (else
     (set! hoge (car parms))
     hoge ; hogeを返す
    ))) ; set-hoge

ちなみに、
(hoge_instance 'set_hoge 'a 'b 'c)
としてたとき、各引数は
(car parms) ; =>a
(cadr parms) ; =>b
(caddr parms) ; =>c
で拾えます。(わかってるかもしれないけど一応)
168166:2001/05/11(金) 00:46
(make-hoge 'hoge)
=>#<closure>
としたときに返されるのはclosureですが、
closure定義自体のコピーは行われません。(だった筈)
よって、make-hogeの中身を動的に変更する手段(メタクラス化)を
作っておくと、既に作成されたinstanceにも影響します。
インスタンス毎にコピー(というか保存)されるのは、
(make-hoge 'hoge)を実行した時のローカル環境letのhoge
だけです。
C++の一時変数の様な使い方(↓)をする場合は
defineする必要はありません。
C++
func(CHoge(hoge));
scheme
;hogeインスタkンスを作成し、
;そのインスタンスににhogeメッセージを送って
;その結果をfuncに渡す。
;hogeインスタンスは以降使われない。(後にgcで回収される)
(func ((make-hoge 'hoge) 'hoge))
169166:2001/05/11(金) 00:58
過去レスにありますが、
C++のthis参照の様な事をしたい場合、
message dispatcherをthisという名前などで保存しておけば、
同様の事ができます。
>>166のmessage dispatcherの部分を下の様に書き換える。
(define this (lambda (message . params) ...))
this ; make-hogeの結果としてthisを返す。

これで、make-hogeの中でもthis経由でメッセージ式が使えます。
(this 'message params)
170159:2001/05/11(金) 02:19
>>166
漏れは厨房過ぎてすぐに全ては飲み込めないが、OOP的な書き方も
ばっちりできそうだという匂いは伝わった。ありがとう!
171デフォルトの名無しさん:2001/05/12(土) 06:08
>>166
(define (make-hoge init)
 (let ((hoge init))

(define (make-hoge hoge)
にすればletは必要ない。
lambdaパラメータも環境の一つなんで。
(make-hoge init)
これを実行した時点でhogeがinitに初期化される。

hogeインスタンスから見えるローカルフレームの環境リスト
((set-hoge . #<closure>)
(this . #<closure>)
(hoge . init))

さらにmessage dispatcher 実行時に追加される環境リスト
; 'hoge メッセージ呼出し時
((parms . ()) (message . hoge))

; 'set_hoge メッセージ呼出し時
((parms . "bar") (message . set_hoge))
172デフォルトの名無しさん:2001/05/12(土) 06:24
(define (make-hoge hoge super)
と書き直して、message dispatcherの最後に下を追加すると、
(else
 (if (procedure? super)
  (apply super (cons message parms))
  #f)
単一継承モデルとかも作れる。
caseはeqv?の線形探索だからmessageが多くなると時間がかかるんで、
alistやvectorにして自己組織化探索やhashとかにした方がいいかも。
173デフォルトの名無しさん:2001/05/12(土) 07:25
schemeばっかでlispの話題がでないね。
174デフォルトの名無しさん:2001/05/12(土) 10:50
cons-streamとか、delay/forceって
有効に使ったことある人います?
無限ストリームとか、概念はカコイイんだけど、
いまいち使い道が・・
175デフォルトの名無しさん:2001/05/12(土) 14:00
SICPに載ってるよ>174
訳はわかりずらいが。
176デフォルトの名無しさん:2001/05/13(日) 02:03
なんでLispのコードを見ると関数がやたらグローバルなんだろう・・・。不思議だ。
177デフォルトの名無しさん:2001/05/13(日) 05:41
>>176
やたらグローバルな本来の理由はわかりませんが、
こういう使い方はよくされる様です。
例えばcar cdrを再定義して、car cdrの入力のobjを呼ばれる度に
表示させたいとか、オリジナルを上書きした方が都合の良い場合。

;オリジナルのcar cdrを保存
(define orgcar car)
(define orgcdr cdr)
;car cdrを再定義
(define (car obj) (display* 'car ': " " obj "\n") (orgcar obj))
(define (cdr obj) (display* 'cdr ': " " obj "\n") (orgcdr obj))
;新しいcar cdrを使う
(car '(a b c))   ;=> car: a
(cdr '(a b c))   ;=> cdr: (b c)
; ....

;使い終わったらcar cdrを元に戻す
(set! car orgcar)
(set! cdr orgcdr)
178デフォルトの名無しさん:2001/05/13(日) 08:04
;display*がcar/cdrを使うclosureの場合、
;>>177ではうまくいかない処理系があるかも
;つーわけで、
(define (car obj)
 (display 'car)
 (display ':)
 (display " ")
 (display obj)
 (display "\n")
 (orgcar obj))
(define (cdr obj)
 (display 'cdr)
 (display ':)
 (display " ")
 (display obj)
 (display "\n")
 (orgcdr obj))
179デフォルトの名無しさん:2001/05/13(日) 08:07
;テスト
(map + '(1 2 3) '(4 5 6))
car: ((1 2 3) (4 5 6))
car: (1 2 3)
cdr: ((1 2 3) (4 5 6))
car: ((4 5 6))
car: (4 5 6)
cdr: ((4 5 6))
car: ((1 2 3) (4 5 6))
cdr: (1 2 3)
cdr: ((1 2 3) (4 5 6))
car: ((4 5 6))
cdr: (4 5 6)
cdr: ((4 5 6))
car: ((2 3) (5 6))
car: (2 3)
cdr: ((2 3) (5 6))
car: ((5 6))
car: (5 6)
cdr: ((5 6))
car: ((2 3) (5 6))
cdr: (2 3)
cdr: ((2 3) (5 6))
car: ((5 6))
cdr: (5 6)
cdr: ((5 6))
car: ((3) (6))
car: (3)
cdr: ((3) (6))
car: ((6))
car: (6)
cdr: ((6))
car: ((3) (6))
cdr: (3)
cdr: ((3) (6))
car: ((6))
cdr: (6)
cdr: ((6))
=>(5 7 9)
こうなります。traceがあればいらんけどね
180デフォルトの名無しさん:2001/05/13(日) 10:54
>>174
delay/forceは、schemeで正規順序(ふつーのschemeの評価は作用的順序。)で
評価できる様にするもの。cons-streamはその応用。
(と、SICPに書いてありました)
有効な使い方は知りません(汗

(define (stream-car s) (car s) )
(define (stream-cdr s) (force (cdr s)))
(define (stream-ref s n)
 (if (= n 0)
  (stream-car s)
  (stream-ref (stream-cdr s) (- n 1))))

例)
無限に1が続くstream
(define ones (cons-stream 1 ones))
nをいくつにしても1が返る
(stream-ref ones n)

フィボナッチ数の無限ストリーム
(define (fibgen a b)
 (cons-stream a (fibgen b (+ a b))))
(define fibs (fibgen 0 1))

(stream-ref fibs 15)
=>610
(stream-ref fibs 30)
=>832040
181デフォルトの名無しさん:2001/05/13(日) 11:00
>>177-178を適用した時のfibs 30の出力
(stream-ref fibs 30)
cdr: (0 . #<closure>)
cdr: (1 . #<closure>)
cdr: (1 . #<closure>)
cdr: (2 . #<closure>)
cdr: (3 . #<closure>)
cdr: (5 . #<closure>)
cdr: (8 . #<closure>)
cdr: (13 . #<closure>)
cdr: (21 . #<closure>)
cdr: (34 . #<closure>)
cdr: (55 . #<closure>)
cdr: (89 . #<closure>)
cdr: (144 . #<closure>)
cdr: (233 . #<closure>)
cdr: (377 . #<closure>)
cdr: (610 . #<closure>)
cdr: (987 . #<closure>)
cdr: (1597 . #<closure>)
cdr: (2584 . #<closure>)
cdr: (4181 . #<closure>)
cdr: (6765 . #<closure>)
cdr: (10946 . #<closure>)
cdr: (17711 . #<closure>)
cdr: (28657 . #<closure>)
cdr: (46368 . #<closure>)
cdr: (75025 . #<closure>)
cdr: (121393 . #<closure>)
cdr: (196418 . #<closure>)
cdr: (317811 . #<closure>)
cdr: (514229 . #<closure>)
car: (832040 . #<closure>)
=>832040
182デフォルトの名無しさん:2001/05/13(日) 16:47
ウザイ。
183デフォルトの名無しさん:2001/05/14(月) 03:05
schemeマンセー
184デフォルトの名無しさん:2001/05/15(火) 04:45
構文の変換について質問なんですが、
(let ((a b) (c d)) e f)

((lambda (a c) e f) b d)
に書き換えられる事がわかったんですが、
ループ用の名前付きlet
(let loop ((a b) (c d)) (loop e f) )

((lambda () (define (loop a c) (name e f)) (loop b d)))
これよりもっと単純に置き換える事は可能でしょうか。
(define使わない方法とか)
185デフォルトの名無しさん:2001/05/15(火) 04:46
まちがえました
((lambda () (define (loop a c) (loop e f)) (loop b d)))
186デフォルトの名無しさん:2001/05/15(火) 17:00
lambdaの bodyにある defineは letrecの syntactic sugarにすぎないよな..

(letrec ((loop (lambda (a c) (loop e f)))) (loop a c)) か?

letrecはどうすんだろ。 lambda と set! で置き換えはできるけど。
187デフォルトの名無しさん:2001/05/15(火) 18:22
>>186
逆だと思うのですが。
letrecがdefineとlambdaのsyntactic sugarと理解してます。
>>184
defeinは必ず必要だと思う。
188184:2001/05/15(火) 22:14
>>186-187
無理ですかねぇ。
loopのclosureを引数にするとかでできないか、
もう少し考えてみます。

schemeはもしかすると、lambda(closure束縛)といくつかの
(syntax sugarではないset!とかの)特殊形式、if制御構文、
primitiveだけに変換できるのでは?〜と思ったんで。

#例えばconsやcar/cdrもlambda、if、eq?だけで表現できる。(効率は悪そうですが)
(下のcondはifのネストで変換)
;;;;cons
(lambda (l r)
(lambda (m)
(cond ((eq? m 'car) l)
((eq? m 'cdr) l)
(else (error "cons:" m)))
))
;;;;car
(lambda (z) (z 'car))
;;;;cdr
(lambda (z) (z 'cdr))
189186:2001/05/15(火) 22:57
>>187 http://www.sci.toyama-u.ac.jp/~iwao/Scheme/r5rsj/html/r5rsj.html#SEC47
まあ構文糖とははっきり書かれてないけど。

http://www.sci.toyama-u.ac.jp/~iwao/Scheme/r5rsj/html/r5rsj.html#SEC81
に letrecを展開する macroとか書いてあるから、原理的に okだが。
macroわすれた。
190184:2001/05/15(火) 23:16
>>199
なるほど、named-let->letrec->let->lambdaって風に
変換するみたいですね。手変換できるかも。ありがとうございます。
マクロはlispのdefine-macro形式ならわかるけど、
let-syntaxとかの構文はいまだに謎・・。
なんであれがschemeの標準マクロなのか不思議です。
191184:2001/05/16(水) 00:04
とりあえず手変換ですがなんとか出来ました。
やっぱりclosureを引数に取る方法でいけました。
(1)、(2)でclosureを呼出してると同時に、自分自身の束縛も引数に入れてるのが肝です。
これを形式変換するには、(1)はテンプレート変換で良いとして、
(2)は、named-let中に置かれた(loop ...)呼出しを探して、
(loop loop ...)形式に置き換えないといけないから、環境生成の監視
を伴うので結構面倒そうです。(シンボルがバッティングしない様にしたり)
(loop ...)形式のままで変換できれば一番良いんですが・・。

(let loop ((a b) (c d)) (loop e f) )

((lambda (a c)
 ((lambda (loop) ;   …(1)
  (loop loop a c))
  (lambda (loop a c) ; …(2)
   (loop loop e f)
  )))
 b d)
192186:2001/05/16(水) 20:04
>>191 確かにうまくいってそうな気がする。だまされてるような気もする。
でも R5RSじゃ、やっぱり環境つくって set! してるみたいだ。
その方が素直だろ。letrecっつう関数型っぽいもので set!が出てくるのは
癪だけど。

確か R5RSの macroは hygenic(清潔?) っつーのが売りだったような。
Lispの macroだと新しく導入した symbolが既存の物とぶつかることもあるって
のが不潔なんだろうな。でも internしなきゃいい気もするが。忘れた。
193184>192:2001/05/16(水) 21:07
>だまされてるような気もする。
>>191は一応他の形式でもテストしたんで動きますよ(汗
named-let->letrec->lambda変換(set!を使う)の方だと
>>191の方法と違って環境探索が必要無いので、
素直に定型テンプレートで形式変換できますね。
((lambda (loop)
 (set! loop
  (lambda (a c)
   (loop e f)
  ))
(loop b d)
())
どのみちset!は必要だから、こっちの方がいいのかな。

>hygenic(清潔?) っつーのが売りだったような。
schemeのマクロはlispなら(gensym)で回避する問題を
自動でやってくれるって事ですか。
使いこなせればかなり便利そうですね。
(日本語の資料が不足ぎみ・・)
194184>:2001/05/16(水) 21:11
>>191の方法を使ったふぃぼなっち
(define fib3
 (lambda (n)
  ((lambda (fib-iter)
   (fib-iter fib-iter 1 0 n))
   (lambda (fib-iter a b c)
   (if (= c 0)
    b
    (fib-iter fib-iter (+ a b) a (- c 1))
   )
  )))
)
(fib 30)
=>832040
195デフォルトの名無しさん:2001/05/18(金) 07:25
syntax-caseってなんでしょう。
これもマクロかな?
196デフォルトの名無しさん:2001/05/19(土) 03:02
ageておく
197デフォルトの名無しさん:2001/05/19(土) 03:14
現在ある言語の中でどれが最高?スレの133へ
(他スレからの引用の仕方ってあるんですか?)

>マクロって参照を使える言語での関数定義とほとんど同じようなもんだろ?
>Cの関数定義では、絶対に同等のことが出来ないようなマクロって
>例えばどんなやつ?

決定的に違うのは、
・マクロ生成時に文脈を調べて生成方法を変えられる。
・マクロを解釈するコードは「プリプロセッサ」としての式ではなく、lisp関数群がそのまま使える。
・展開後のマクロはマクロとしてではなく、普通のlispコードと同じレベルで扱える。

例はとりあえず、オンラインにあるやつ見てください。
(define-macro defmacro macroで検索)
198133:2001/05/19(土) 03:27
>・マクロ生成時に文脈を調べて生成方法を変えられる。
なるほど。

> ・マクロを解釈するコードは「プリプロセッサ」としての式ではなく、lisp関数群がそのまま使える。
例えばfun(int,int){}内ではC関数群はそのまま使えると思うが?

> ・展開後のマクロはマクロとしてではなく、普通のlispコードと同じレベルで扱える。
fun();という文はCコードと同じレベルではないのか?
199デフォルトの名無しさん:2001/05/19(土) 03:29
マクロは通常、随時解釈されますが、
マクロを展開してコードに直接埋め込む事ができます。(破壊操作)
また、元コードを保ちたい場合、展開コードをキャッシュして持っておく様にもできます。
200デフォルトの名無しさん:2001/05/19(土) 03:34
>>198
Cでいうなら、#define内で「マクロ生成の為だけの」コードを
書けるということなんですが。
(展開コードには余計なものは含まれません。)
これは実際に触わってみないと判らないかもしれない。
201133:2001/05/19(土) 03:35
>>199
> マクロを展開してコードに直接埋め込む事ができます。(破壊操作)

何らかのコード;
fun();
何らかのコード;

という部分があれば、fun();が埋め込まれてるんじゃないのか?
変数を渡したい場合はポインタのようなもので渡さなきゃいけないが。

> また、元コードを保ちたい場合、展開コードをキャッシュして持っておく様にもできます。

何らかのコード;
if (保ちたくない場合)
fun();
何らかのコード;

とは違うのか?
202133:2001/05/19(土) 03:41
>>200
うーむ。#defineの中で本当のコードが使えるということか?
LISPは本で少し読んだだけだが、ふと疑問に思ったもんで。
まあ、マクロはもっと勉強してみます。
ありがとう。
203デフォルトの名無しさん:2001/05/19(土) 03:48
例えば、
#define myif(test, t, f) \
if (nullp(f)) printf("if (%s) %s ", test, t);
else printf("if (%s) %s else %s", test, t, f);
としたときのprintfの出力がそのままコンパイルの段階で
コードに埋め込まれるという感じに少し似ているかな?
printfの文字列の部分が展開テンプレート、
printfの出力が展開コード、
printfやif-elseの部分はマクロ解釈コード。
204133:2001/05/19(土) 03:58
>>203
そういうのって、
myif(int a, void (*b)(),void (*c)()){
if (a)
b();
else
c();
}

じゃやっぱ駄目かね…
myif使うたびに関数が増えるのがちょっと面倒だけど。
205デフォルトの名無しさん:2001/05/19(土) 04:51
おもしろage
206デフォルトの名無しさん:2001/05/19(土) 15:40
207デフォルトの名無しさん:2001/05/19(土) 19:46
call/cc (call-with-current-continuation) の使い方その3

while文 (break continue 付き)
(while test body .. )

C言語の繰返し制御構文whileと互換の物を作成します。
test式の評価結果が真の間、bodyシーケンスを繰返し実行します。
whileブロックからの戻り値は特に規定しない事にします。
208デフォルトの名無しさん:2001/05/19(土) 19:47
実装方法(1/2)
while文自体の定義は簡単です。
普通にマクロで定義するとこうなります。

(define-macro (mywhile0 test . body)
 (let ((loop (gensym)))
  `(let ,loop ()
   (cond
    (,test
     ,@body
     (,loop)))
  )))

ただしこの定義ではnamed-letのsyntax-sugarとしての役割しかなく、
Cで使えるbreakやcontinueといった脱出構文が使えません。
そこで、継続を使用してwhileのbody内で(break)や(continue)と
いった記述を出来るようにします。
209デフォルトの名無しさん:2001/05/19(土) 19:48
実装方法(2/2)
body内で、継続を束縛したシンボル(break、continue)を直接参照するには、
bodyをその継続ブロック内に置く必要があります。
breakはループの外側の階層に置くことで、(break)を呼出すとループの直後に抜ける事が出来ます。
また、continueはtestの直後、bodyの外側の階層に置くことで機能を果します。

(define-macro (mywhile test . body)
 (let ((loop (gensym)))
  `(call/cc (lambda (break)
   (let ,loop ()
    (cond
     (,test
     (call/cc (lambda (continue)
      ,@body
     )) ; call/cc continue
     (,loop)))
   ))) ; call/cc break
 ))
210デフォルトの名無しさん:2001/05/19(土) 19:49
;テスト
(define (make-step-list from to inc)
 (let loop ((i from))
  (if (= i to)
    '()
    (cons i (loop (inc i))))
 ))

(define-macro (mypop s)
 `(if (pair? ,s)
    (prog1 (car ,s) (set! ,s (cdr ,s)))
    #f))

(define (mywhile-test)
 (define step (make-step-list 0 20 (lambda (i) (+ i 1) )))
 (mywhile
  (pair? step)
  (display (car step)) (display #\space)
  (if (= 16 (car step))
   (break))
  (mypop step)
  (if (not (= 1 (% (car step) 2) ))
   (continue))
  (mypop step)
 )
 (display 'end) (newline)
 #t
)
211デフォルトの名無しさん:2001/05/19(土) 19:50
;テスト結果
(mywhile-test)
0 2 4 6 8 10 12 14 16 end
=>#t
212デフォルトの名無しさん:2001/05/20(日) 01:07
(a) -> aを関数と見立てて評価
a -> aに束縛されたオブジェクト
'(a) ->(a)というリスト
'a ->aというシンボル
便利だね。
シンボルはそのまま表示できるし。
(display 'a)
213デフォルトの名無しさん:2001/05/20(日) 01:33
>>212
symbol->stringかなんかで"a"の様に文字列にすると、
生成するたんびにその分のメモリを消費するから、
シンボルは引用符を付けて表示させるのが良い。
シンボルなら同一性のテストが低コストで行なえるし。
214213:2001/05/20(日) 02:12
>低コストで行なえるし。
*確実に*低コストで行なえるし。
のまちがい。
215デフォルトの名無しさん:2001/05/20(日) 11:15
可能性を感じさせる言語だ
216デフォルトの名無しさん:2001/05/20(日) 14:34
内部定義やlambdaで簡単に外側の変数いぢれるのがいいね
(let ((x 0))
 (map (lambda (i) 〜xの操作 ) list)
)
217デフォルトの名無しさん:2001/05/20(日) 15:14
(let ((x 3)) (funcall #'(lambda () (* x x))))
218デフォルトの名無しさん:2001/05/21(月) 04:03
219デフォルトの名無しさん:2001/05/21(月) 05:32
累積変数ってのは、末尾再帰に直すときに使われる技法だな。
(define (sum xs)
(if (null? xs) 0 (+ (car xs) (sum (cdr xs)))))
って素直だけど stackを消費する再帰を
(define (sum xs)
(define (isum xs r)
(if (null? xs) r (isum (cdr xs) (+ r (car xs)))))
(isum xs 0))
って、rって変数を使って末尾再帰に直す事。
っていうか、変数r そのものが累積変数。だと思われ。
220218:2001/05/21(月) 23:21
>>219
ありがとうございます。
なるほど。結果を保存しておく一時変数の事ですか。
こういうのって、機械が末尾再帰じゃない再帰を見つけて、可能なら末尾再帰に
直すとかしてくれると助かりますよね・・。
人間ならちょっと考えれば可能だけど、機械にやらせるとなるとしんどいかな。

(define (sum xs)
 (if (null? xs)
   0
   (+ (car xs) (sum (cdr xs)))
 ))

;↓(内部定義へ変換)
(define (sum2 xs)
 (define (isum r xs)
  (if (null? xs)
    r
    (isum (+ r (car xs)) (cdr xs))
  ))
 (isum 0 xs))
または
;↓(named-letへ変換)
(define (sum3 x)
 (let isum ((r 0) (xs x))
  (if (null? xs)
    r
    (isum (+ r (car xs)) (cdr xs))
  )))
この例は簡単だけど、パターン化できないかな。
221デフォルトの名無しさん:2001/05/21(月) 23:46
最初はこういう形式変換からかな。
このパターンの時
(rec xs)
(null? xs) => 0
(operator (car xs) (rec (cdr xs))) =>result

変数rを使用して下のパターンに変換
r := 0
(rec r xs)
(null? xs) => r
(rec (operator r (car xs)) (cdr xs)) =>result

一次変換
(define (sum r xs)
 (if (null? xs)
   r
   (sum (+ r (car xs)) (cdr xs))
 ))
(sum 0 '(1 2 3 4))
=>10
222デフォルトの名無しさん:2001/05/22(火) 00:49
(define (foldr bop defval xs)
(if (null? xs)
defval
(bop (car xs) (foldr bop defval (cdr xs)))))

(define (foldl bop defval xs)
(if (null? xs)
defval
(foldl bop (bop defval (car xs)) (cdr xs))))

bop が可換なら (foldr bop defval xs) と (foldl bop defval xs) は等価
foldl は末尾再帰 ?
223デフォルトの名無しさん:2001/05/22(火) 22:38
>>222
>foldl は末尾再帰 ?
見た感じそのようですが。
末尾再帰であるかの判定は、
foldrは、bopに与える被演算子がfoldr再帰の結果なのでそれが求まるまでbopの評価を遅延する必要がある。よって普通の再帰。
foldlは、foldl再帰の結果が関数の値そのものになるので遅延させるべき演算は存在しない。よって末尾再帰。
という風に考えれば良いんじゃないかと。
ifが絡みますが、ifは分岐構文であって、分岐先が決まったら、保存する様な状態が無いことからfoldlが末尾再帰である事の証明への妨げにはなりません。
224デフォルトの名無しさん:2001/05/22(火) 23:13
これも末尾再帰
(define (countdown5 s)
 (cond
  ((= 0 s) s)
  ((= 1 s) (display s) (countdown5 (- s 1)))
  ((= 2 s) (display s) (countdown5 (- s 1)))
  ((= 3 s) (display s) (countdown5 (- s 1)))
  ((= 4 s) (display s) (countdown5 (- s 1)))
  ((= 5 s) (display s) (countdown5 (- s 1)))
  (else (countdown5 (- s 1)))
 ))

(countdown5 10)
54321
=>0
225デフォルトの名無しさん:2001/05/23(水) 00:32
>>223
なる
226デフォルトの名無しさん:2001/05/23(水) 20:14
call/cc (call-with-current-continuation) の使い方その4
for文
(for init test incr body ...)

test body はwhileの時と同じ。initとincrが増えただけ。
initとincrにはfor内部で参照するカウンタ変数の初期化式と増減式を記述します。
initで(i 0) とすれば、iがカウンタ変数(初期値0)として使用されます。
initで宣言したカウンタ変数はtest/incr/body内で参照できます。
227226:2001/05/23(水) 20:15
(続き)
この例では、named-letの書式をそのまま当てはめて使用してるので、letと同じ
問題を含んでいます。(よって実際のC言語のfor文より使い勝手は落ちます。)
initとincrに与える書式は、
init が () の時、 incr は () (==whileと同じ意味)
init が (x 0) の時、 incr は (+ x 1)
init が ((x 0) (y 1) (z 2)) の時 incr は ((+ x 1) y (+ z y))
を許します。
let束縛順序の規則が適用されるので、initに((x 0) (y x) (z y)) の様な式は書けません。
(被演算子側の x, yは外部に存在する物と解釈されます。)

これらの書式の判定と選択はマクロ解釈コード内で行ないます。
出力の展開コードには含まれません。
for-expand内部定義の場合分けを増やす事によって、柔軟な構文を許す事ができます。
228226:2001/05/23(水) 20:15
;実装
(define-macro (for init test incr . body)
 (let ((loop (gensym))
    (expand-init
     (if (or (null? init)
         (pair? (car init)))
       init
       (list init)) )
    (expand-incr
     (if (or (null? init)
         (pair? (car init)))
       incr
       (list incr)) ))

  `(call/cc (lambda (break)
    (let ,loop ,expand-init
     (cond
      (,test
      (call/cc (lambda (continue)
       ,@body
      )) ; call/cc continue
      (,loop ,@expand-incr)))
    ))) ; call/cc break
 ))
229226:2001/05/23(水) 20:16
;おまけ
;letが大袈裟だと思ったときに使う。
(define-macro (tmp init . body)
 (let ((expand-init
     (if (or (null? init)
         (pair? (car init)))
       init
       (list init)) ))
  `(let ,expand-init ,@body)
 ))

;forのテスト
(define (九九 from to)
 (for (y from) (<= y to) (+ y 1)
  (for (x from) (<= x to) (+ x 1)
   (tmp (n (* x y))
    (if (< n 10) (display #\space))
    (if (< n 100) (display #\space))
    (display* n #\space)
   )
  )
  (display* eol)
 ))
230226:2001/05/23(水) 20:17
;テスト結果
(九九 1 9)
 1  2  3  4  5  6  7  8  9
 2  4  6  8 10 12 14 16 18
 3  6  9 12 15 18 21 24 27
 4  8 12 16 20 24 28 32 36
 5 10 15 20 25 30 35 40 45
 6 12 18 24 30 36 42 48 54
 7 14 21 28 35 42 49 56 63
 8 16 24 32 40 48 56 64 72
 9 18 27 36 45 54 63 72 81
=>()
231226:2001/05/23(水) 20:18
ずれちゃった・・
補足:
マクロの展開処理は普通のlispの記号処理と同程度のコストが掛かるので、
記述が長くなると不利ですが、コンパイラや直コード埋め込み、マクロキャッシュ
などを持っている処理系ならば、実行時に展開を行なう回数は0〜1回に抑える
事ができます。
(逆を言えば、これらの機能の無い処理系上ではマクロを積極的に使うことは考えられない。)
232226:2001/05/23(水) 20:26
;おまけ C言語のpre/post ++ --をエミュレートするマクロ
(define-macro (pre++ bind) `(begin (set! ,bind (+ ,bind 1)) ,bind))
(define-macro (post++ bind) `(prog1 ,bind (set! ,bind (+ ,bind 1))))
(define-macro (pre-- bind) `(begin (set! ,bind (- ,bind 1)) ,bind))
(define-macro (post-- bind) `(prog1 ,bind (set! ,bind (- ,bind 1))))
233226:2001/05/23(水) 20:35
call/cc (call-with-current-continuation) の使い方その5

do〜while文
(do- body -while test)

Cの繰返し制御構文do〜whileと互換の物を作成します。
既にdo文というものが存在するので、代わりに
do- -whileシンボルを使用します。-whileはダミーシンボルです。
ダミーシンボル自体には意味はありませんが、
ここでは簡単な構文チェックに使用しています。
234226:2001/05/23(水) 20:35
;実装
(define-macro (do- body dmy test)
 (let ((loop (gensym)))
  (if (not (eq? dmy '-while))
   (error "do- -while abnormal syntax : do-" dmy))
  `(call/cc (lambda (break)
   (let ,loop ()
    (call/cc (lambda (continue)
     ,@body
    )) ; call/cc continue
    (cond
     (,test
      (,loop)))
   ))) ; call/cc break
 ))
235226:2001/05/23(水) 20:36
;テスト
(tmp (x 0)
 (do-
  (display* x eol)
  (pre++ x)
 -while (= x 10))
)
error: do- -while abnormal syntax : do- (pre++ x)

(tmp (x 0)
 (do- (
  (display* x eol)
  (pre++ x)
 ) -while (= x 10))
)
0
=>()
236デフォルトの名無しさん:2001/05/23(水) 23:22
参考になりました。>>226
whileは検索で見つかるんだけど、forとかのサンプルって何処にも無いんだよね。
call/cc含めたやつなんか皆無だった。
使ってる人はどうしてるのかな?
237デフォルトの名無しさん:2001/05/24(木) 00:05
たしかに(C風の)forやdo-whileのサンプルなんて全然おちてないみたいね。
Cユーザー層向けにRxRSにでもマクロサンプルとか置いといてくれないかなあ。
(define-macroはvanilla Lisp styleだけど。)
238デフォルトの名無しさん:2001/05/24(木) 01:15
for (i = list; pairp(i); i = cdr(i)) {
 putatom(car(i));
}
(for (i '(a b c d)) (pair? i) (cdr i)
 (display (car i)))
うむ、似た書式で書けるのはやっぱ便利。
239デフォルトの名無しさん:2001/05/24(木) 02:17
forに相当する構文は、もともとdoってのがあるが。
だから見つからないだけだろう。

それになれてくると使わなくなってくるしな。
240デフォルトの名無しさん:2001/05/24(木) 02:22
よく知らないけど、マクロって言うのは
Lispにしかないの?

Cとかと違って、意味論的には汚くならないの?
241デフォルトの名無しさん:2001/05/24(木) 03:13
>>239
doって書式わかりずらくないですか?括弧も多くなるし。
(do ((var init incr)) (test result) body)
for文はC知ってる人なら多分とっつきやすいでしょうね。
c->scheme変換の時も楽だし。(c->schemeする意味自体はともかく)
doのresultに相当する部分が無いのは結構致命的ですけど。
慣れるとdoすら必要ない気がするのは同意。
242デフォルトの名無しさん:2001/05/24(木) 03:34
(for (set! i list) (pair? i) (set! i (cdr i))
 (print (car i)))
とかのがよさげ?
243デフォルトの名無しさん:2001/05/24(木) 03:44
あのforはわざわざ破壊的代入を避けて実装されてるのに、なぜにset!?>242
244デフォルトの名無しさん:2001/05/24(木) 18:31
>>241
わかりずらいのでfor-eachとかmapしか使わなくなってくるんだな。
一度closure使って数列発生器作っとけば
for-eachをcのfor的に汎用的に使えるんじゃないのかね。
245デフォルトの名無しさん:2001/05/24(木) 20:41
>240
schemeにはもっと高級なのがあります。
(パターンを記述する形式。わたしは良く知りません)
lispのdefine-macro形式は実現が簡単だという理由で、
ほぼ全ての処理系に付いてます。
(evalとapply部でフックできれば自作できる程度。多分・・。)
246デフォルトの名無しさん:2001/05/25(金) 01:07
fluid-letについて知ってる人いませんか?
fluid bindings
dynamic-windと関係あるみたいなんですが。
247デフォルトの名無しさん:2001/05/25(金) 01:23
ここ読んでもよくわからなかった。(動的スコープがなんたら。)
http://srfi.schemers.org/srfi-15/srfi-15.html
普通に使ってるぶんには関係ないのかな?
248デフォルトの名無しさん:2001/05/25(金) 23:32
do- -while修正
(do- body-expr -while test-expr)
(do- ((lambda (p) ) rp) -while test-expr) の場合に動作しない。
body-exprに複文を置きたい場合は↓の様にする。
(do- (begin ...) -while test-expr)

(define-macro (do- body dmy test)
 (let ((loop (gensym)))
  (if (not (eq? dmy '-while))
   (error "do- -while abnormal syntax : do- " dmy))
  `(call/cc (lambda (break)
   (let ,loop ()
    (call/cc (lambda (continue)
     ,body
    )) ; call/cc continue
    (cond
     (,test
      (,loop)))
   ))) ; call/cc break
 ))
249デフォルトの名無しさん:2001/05/26(土) 01:16
>>241
>(c->schemeする意味自体はともかく)
意味自体は結構あると思う。
括弧が減るってだけで可読性かなり良くなるし。
ありがと〜。
250デフォルトの名無しさん:2001/05/28(月) 00:32
>>247
fluid-letした変数は同名の変数をマスクしてdynamic scopeのように振舞う上に、
再びfluid-letのスコープに入ると前に入ったときの値が残っているというわけか。
例を見たほうがわかりやすいな。でもこのsfriはwithdrawnだよ。
251250:2001/05/28(月) 00:34
sfri -> srfi
252デフォルトの名無しさん:2001/05/28(月) 01:07
(define (fib n)
  (define (iter a b p q count)
    (define (even? n) (= (% n 2) 0))
    (cond ((= count 0) b)
          ((even? count)
           (iter a
                 b
                 (infix q * q + p * p)
                 (infix 2 * p * q + q * q)
                 (infix count / 2)))
          (else (iter (infix b * q + a * q + a * p)
                      (infix b * p + a * q)
                      p
                      q
                      (infix count - 1))
          )))
  (iter 1 0 0 1 n))
253デフォルトの名無しさん:2001/05/29(火) 00:44
list構造を再帰的に辿って、atom以外を全て複製したい場合が出てきました。
全てのconsで作られたセルを複製する関数って標準でありますか?
↓みたいなやつ。あればそっちを使いたいんですが。
  
(define list-dup (lambda (l)
  (let loop ((x l))
    (cond ((null? x) x)
          ((pair? x) (cons (loop (car x))
                           (loop (cdr x))))
          (else x)))))
254デフォルトの名無しさん:2001/05/29(火) 00:52
あ、やっぱりいいです
255デフォルトの名無しさん:2001/05/29(火) 02:03
lispはいーかげんなデータ構造簡単に作れるからいいね。
それを探索するのも簡単だし。
256246:2001/05/30(水) 00:10
>>250
ありがとうございます。
結局自分では使わなさそうということが分かりました。
257デフォルトの名無しさん:2001/05/30(水) 22:59
(deine f (lambda x 〜))
ってやると
(f a b c d )
(car x) -> a
(cadr x) -> b
(caddr x) -> c
(cadddr x) -> c
って書けるのね。
(deine (f . x) ...)
の意味がようやく理解できたyo
258デフォルトの名無しさん:2001/06/01(金) 00:11
age
259デフォルトの名無しさん:2001/06/01(金) 03:10
誰か質問に答えてくれる人います?
260デフォルトの名無しさん:2001/06/01(金) 21:11
質問の内容による
261デフォルトの名無しさん:2001/06/01(金) 23:17
なんで set! は setq と違って、代入した値を
返してくれないの?
262>261:2001/06/01(金) 23:38
未定義だと決まってるから、としか言えない。
なぜ未定義にしたかは、仕様を決めた人に聞くしかない。
(理由を知ってる人がいたら解説お願いします。)
代入値をそのまま返す処理系はあるとは思うけど、
どの処理系でも確実に代入値を返したいなら、
マクロで定義する方法がある。
(define-macro (myset! sym expr)
`(begin (set! ,sym ,expr) ,sym))
=>myset!

(define a 0)
=>a
(myset! a (+ a 1))
=>1
263デフォルトの名無しさん:2001/06/02(土) 03:06
(define := myset!)
=>:=
(infix-operator (cons := 'right))
;infix解析器に:=を右結合で登録

(infix a := a + 1)
---->(eval (begin (set! a (+ a 1)) a))
=>1
264デフォルトの名無しさん:2001/06/03(日) 01:10
(infix a ;= b := a + 1)
---->(eval (begin (set! a (begin (set! b (+ a 1)) b)) a))
か?
265デフォルトの名無しさん:2001/06/03(日) 01:42
マクロってapplyできるの?
266デフォルトの名無しさん:2001/06/03(日) 02:57
>>265
普通できるんじゃないの?
(define a 0)
(apply myset! `(a ,(a + 1)))
=>1
a
=>1
267デフォルトの名無しさん:2001/06/03(日) 03:01
まちがった
(apply myset! `(a ,(+ a 1)))

しかしこの場合マクロキャッシュが働くか疑問
268デフォルトの名無しさん:2001/06/03(日) 03:04
あ、マクロだから普通のquoteでもいいのか。
(apply myset! '(a (+ a 1)))
269デフォルトの名無しさん:2001/06/03(日) 04:39
>>265
lispでは(Common Lispの仕様書によると)できないみたいね。
270デフォルトの名無しさん:2001/06/04(月) 21:31
schemeハァハァ
271デフォルトの名無しさん:2001/06/05(火) 22:20
話題止まっちゃったね。
誰かネタ振り希望。
272デフォルトの名無しさん:2001/06/05(火) 23:13
スマソ LIPS スレと間違った。
273デフォルトの名無しさん:2001/06/05(火) 23:18
ネタ提供ありがとうございました。
274ネタ提供します:2001/06/05(火) 23:27
剥いたみかん→((()))
275デフォルトの名無しさん:2001/06/05(火) 23:35
( ´-`)
276デフォルトの名無しさん:2001/06/06(水) 00:05
剥く前のみかん(:*:)
277デフォルトの名無しさん:2001/06/08(金) 00:20
ネタ提供
>>226-231 のforの展開内容をリストで確認できる様にしたもの。

(for-expand '(a) 'b '(c) '(d e f))
=>(call/cc (lambda (break)
    (let G22 ((a))
      (cond
        (b
          (call/cc (lambda (continue) d e f))
          (G22 (c)))))))
278277:2001/06/08(金) 00:22
(define (for-expand init test incr body)
  (let ((loop (gensym))
        (expand-init
          (if (or (null? init)
                  (pair? (car init)))
              init
              (list init)) )
        (expand-incr
          (if (or (null? init)
                  (pair? (car init)))
              incr
              (list incr)) ))

    `(call/cc (lambda (break)
       (let ,loop ,expand-init
         (cond
           (,test
            (call/cc (lambda (continue)
              ,@body
            ))
            (,loop ,@expand-incr)))
       )))
  ))

;for-expand の結果をそのままマクロに適用する
(define-macro (for init test incr . body)
   (for-expand init test incr body)
)
279デフォルトの名無しさん:2001/06/10(日) 00:30
(define (while-expand test body)
  (let ((loop (gensym)))
    `(call/cc (lambda (break)
      (let ,loop ()
        (cond
          (,test
          (call/cc (lambda (continue)
             ,@body
          ))
           (,loop)))
      )
    ))
  ))

(define-macro (while test . body)
  (while-expand test body))
280デフォルトの名無しさん:2001/06/10(日) 00:32
(define (do-while-expand body dmy test)
  (let ((loop (gensym)))
   (if (not (eq? dmy '-while))
     (error "do- -while abnormal syntax : do- " dmy))
   `(call/cc (lambda (break)
      (let ,loop ()
        (call/cc (lambda (continue)
          ,body
        ))
        (cond
          (,test
           (,loop)))
      )))
  ))

(define-macro (do- body dmy test)
  (do-while-expand body dmy test))
281デフォルトの名無しさん:2001/06/10(日) 00:43
展開前
(define (example0 from to r p)
  (for (i from) (<= i to) (+ i 1)
    (if (< 0 r)
        (if (not (memv i p))
           (example0 from to (- r 1) (cons i p)))
        (begin
          (disp-rev p)(display " ")
          (break)
        ))))

展開後
(define (example0 from to r p)
  (call/cc
    (lambda (break)
      (let G22
        ((i from))
        (cond
          ((<= i to)
            (call/cc
              (lambda (continue)
                (if (< 0 r)
                  (if (not (memv i p))
                    (example0 from to (- r 1) (cons i p)))
                  (begin
                    (disp-rev p)(display " ")
                    (break)))))
            (G22 (+ i 1))))))))
282デフォルトの名無しさん:2001/06/10(日) 00:46
format作ってくれ。Common Lispにあるようなやつ。
283デフォルトの名無しさん:2001/06/10(日) 00:52
named-let/condの展開
(define example0
  (lambda (from to r p)
    (call/cc
      (lambda (break)
        ((lambda (G22)
           (set! G22
  (lambda (i)
    (if (<= i to)
      (begin
        (call/cc
          (lambda (continue)
            (if (< 0 r)
              (if (not (memv i p))
                (example0
                  from
                  to
                  (- r 1)
                  (cons i p)))
              (begin
                (disp-rev p) (display " ")
                (break)))))
        (G22 (+ i 1))))))
           (G22 from))
          ())))))
284デフォルトの名無しさん:2001/06/10(日) 00:53
>282
SLIBに入ってるよ
printf/scanf系も
285デフォルトの名無しさん:2001/06/10(日) 00:57
入ってた。1700行ぐらいある。作るのは結構大変かも。
286デフォルトの名無しさん:2001/06/10(日) 00:57
上のexample0はここにあったやつをforに書き直したもの
http://piza.2ch.net/test/read.cgi?bbs=tech&key=989929288&st=853&to=853&nofirst=true
287デフォルトの名無しさん:2001/06/12(火) 00:15
syntax-sugarを実際に展開できる言語マンセー
288デフォルトの名無しさん:2001/06/12(火) 00:30
>>286
そのレスのC言語での解答(かわいそうなので)
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
int memv_int(int k, int *a, size_t an) {
    int i = 0;
    for (i = 0; i < an; i++)
        if (k == a[i])
            return 1;
    return 0;
}

void disp(int *a, size_t n) {
    int i;
    for (i = 0 ; i < n; i++)
        printf("%d", a[i]);
}

void example0(int n, int r, int *a, size_t an) {
    int i;
    for (i = 1; i <= n; i++)
        if (r) {
            if (!memv_int(i, a, an)) {
                a[an++] = i;
                example0(n, r - 1, a, an);
                an--;
            }
        } else {
            disp(a, an);
            printf(" ");
            break;
        }
}

void example(int n, int r) {
    int *a = malloc(sizeof(int) * r);
    assert(a);
    example0(n, r, a, 0);
    free(a);
}

int main(int argc, char **argv) {
    assert(argc == 3);
    example(atoi(argv[1]), atoi(argv[2]));
    printf("\n");
    return 0;
}
289デフォルトの名無しさん:2001/06/13(水) 02:03
良く見たらバックトラックの問題だねえ
290デフォルトの名無しさん:2001/06/13(水) 03:00
結果をリストで得られる様にした物
(define (example efrom eto er)
  (let eloop ((from efrom) (to eto) (r er) (p '()))
    (let loop ((i from))
      (cond ((<= i to)
         (cond ((< 0 r)
           (if (not (memv i p))
             (let ((l (eloop from to (- r 1) (cons i p))))
               (if (and (pair? l) (pair? (car l)))
                   (append! l (loop (+ i 1)))
                   (cons l (loop (+ i 1)))))
             (loop (+ i 1))))
               (else (reverse p))))
       (else '())))))

(example 1 3 3)
=>((1 2 3) (1 3 2) (2 1 3) (2 3 1) (3 1 2) (3 2 1))
291デフォルトの名無しさん:2001/06/13(水) 04:56
>>202
> うーむ。#defineの中で本当のコードが使えるということか?

式が「実行時に」2回evalられると思えばよい。
よって、2度目にevalられる式を「生成する」式を書く。
一方、Cのマクロは翻訳時にしか展開されないし、単なる文字列展開に近い。
C++のtemplateは、翻訳時に整数計算できるけど。(よって翻訳時再帰展開可)

こういうのは、

>>240
> よく知らないけど、マクロって言うのは
> Lispにしかないの?

式自体が、first-class objectであるような言語でないと難しい。
Prologにもマクロを持っている奴がいる。(Lisp:Prolog=S式:節)
292デフォルトの名無しさん:2001/06/13(水) 21:17
マクロを応用すると、例えばdefine-with-expand-macroというマクロを定義する事により、
人間が定義した全てのマクロやインライン展開可能なコードを全て
展開した結果に対して定義できたりします。
(define-macro (define-with-expand-macro ...))

(define-with-expand-macro name (lambda () (マクロを使った定義)...))

(define name (lambda () 展開コード))
これはマクロ展開キャッシュの無い処理系にとっては速度アップに繋がります。
またキャッシュバッファの大きさを気にする必要もなくなります。
(その代わりコード量は増大しますが)

例)マクロが含まれた定義(infixや(if- else-if else)はマクロとします)
(define-with-expand-macro (fib4 n)
  (define (even? n) (infix n & 1 = 0))
  (define (fib4-iter a b p q count)
    (if- (infix count = 0)
         b
     else-if (even? count)
             (fib4-iter a
                        b
                        (infix q * q + p * p)
                        (infix 2 * p * q + q * q)
                        (infix count >> 1))
     else    (fib4-iter (infix b * q + a * q + a * p)
                        (infix b * p + a * q)
                        p
                        q
                        (infix count - 1))
    )
  )
  (fib4-iter 1 0 0 1 n))
293デフォルトの名無しさん:2001/06/13(水) 21:19

define-with-expand-macroは、
マクロ展開結果を直接埋め込んだコードに変換したdefineを評価する
(define (fib4 n)
  (define (even? n)
    (= (& n 1) 0))
  (define (fib4-iter a b p q count)
    (if (= count 0)
      b
      (if (even? count)
        (fib4-iter
          a
          b
          (+ (* q q) (* p p))
          (+ (* 2 p q)
             (* q q))
          (>> count 1))
        (fib4-iter
          (+ (* b q)
             (* a q)
             (* a p))
          (+ (* b p) (* a q))
          p
          q
          (- count 1)))))
  (fib4-iter 1 0 0 1 n))
294デフォルトの名無しさん:2001/06/13(水) 21:52
これが出来て何が嬉しいのかというと、人間側から見て、
より判りやすい様に納得がいくまで構文をカスタマイズできる事です。
(if- else-if elseマクロは、condと同等で、より括弧の数が少ない構文を作る)
(infixは中置記法を許すマクロ)

また、マクロを全て展開して埋め込む事で、インタプリタ上でも実行効率が損なわれない。
(lispではマクロもlispコードの一種なので、馬鹿正直に実行時に展開すると、結構なコストが掛かる。)
(キャッシュを持っていても、バッファから溢れたマクロは再評価されるので効率的ではない。)
295デフォルトの名無しさん:2001/06/13(水) 23:57
define-with-expand-macroみたいなの使うと
マクロが評価されるとき(すなわちdefineする前)
に構文チェックするハンドラ関数も呼出せるのでお得。
ここでまじめにチェックしておくと、実行時エラーになる
コードを減らす事ができる。
296デフォルトの名無しさん:2001/06/14(木) 04:44
でもさあ、lazy evaluation+カリー化関数で、マクロとそっくりに
ならない?
my_ifも、 引数三つ取る関数とかにしてさ…
lazy evaluationなら、三つ目の引数は評価しないとか出来るし。
297295:2001/06/14(木) 21:13
>>296
遅延評価は良く知りませんが、
恐らく(見掛け上)マクロと同様に、引数をapplyしないで得られるって事ですよね?
delayは積極的に使ったことが無いのでそういう方法がある事を思い付きませんでした。
後で実験してみます。
298デフォルトの名無しさん:2001/06/14(木) 21:16
sage
299デフォルトの名無しさん:2001/06/15(金) 03:35
>>296
良く考えたら遅延評価でできると言っても、
delayに渡すまでにどこかで評価されちゃうんじゃ?
それともこういうことですか?

(define (myif test true false)
(if (test) (true) (false)))

(myif
(lambda () #t)
(lambda () #t)
(lambda () #f)
)
300デフォルトの名無しさん:2001/06/15(金) 03:40
=>#t
301デフォルトの名無しさん:2001/06/15(金) 04:16
>>296
マクロの代わりにはならないと思う。
単に、
(関数 引数 引数 引数 ...)
をapplyを通さずにリストとして得られるって事なので。
(もし遅延評価+カリーで出来たとしても冗長なコードになる筈。)
302デフォルトの名無しさん:2001/06/15(金) 05:04
ある無名の書評者の文章より。
http://www.amazon.com/exec/obidos/tg/stores/detail/-/books/0262011530/customer-reviews/8/002-7400680-3044044?show=-submittime

This is very deep material for a programming
newbie to learn outside a course, but for an
experienced nerd who's looking for a systematic
framework, it's absolutely terrific. I had done
lots of lisp and compiler work before reading
the book, so many of the concepts were not new.
But it's with this framework in mind that I learn
new technologies, and this approach greatly speeds
up how long it takes to understand each week's "new"
hot product/language/tool/mindset. Put another way:
why do so many popular computer books take 1000 pages
to describe a few trivial concepts?

これ読んでXML関連スレから流れて来ました。よろしくお願いします。
303デフォルトの名無しさん:2001/06/15(金) 06:30
XML=LISPの方言
304デフォルトの名無しさん:2001/06/15(金) 17:22
>>301の書評ページみると、SICPを「プログラム書法」かなにかと間違えて
購入した人がたくさんいるみたい。
305デフォルトの名無しさん:2001/06/15(金) 21:10
>>304
ガイジンは購入する前にどんな本か目次でも見て確認しないのですか?
306ガイジン:2001/06/15(金) 21:12
ソウデザゴイスマ。>>305
307デフォルトの名無しさん:2001/06/16(土) 00:40
XMLって何がすごいんだろう?
あのタグって読みにくいから、LISPみたいに、括弧でくくる方が見やすいと思うんだけどなぁ〜。
それならLISPの資産がそのまま使えるのに。
DOMもcarやcdr、consで十分だし、こっちの方がカッコいいと思うんだけど・・・。あっ、ダジャレですいません。
どう思いますか
308デフォルトの名無しさん:2001/06/16(土) 00:42
LISPなんてマイナーな言語が考慮されるわけねーだろ!
309デフォルトの名無しさん:2001/06/16(土) 00:46
マイナーな言語なんですか?
名前は良く聞きますが
310デフォルトの名無しさん:2001/06/16(土) 00:50
>>308-309
いや、LISPはやっといた方がいいよ。
XML使うんならその前にLISPの本読んだ方がわかりやすいと思う。
311デフォルトの名無しさん:2001/06/16(土) 01:01
XML表現
<い><ろ><は>匂えど</は></ろ></い>
lisp表現
(い(ろ(は 匂えど)))

XMLめんどくさい
312デフォルトの名無しさん:2001/06/16(土) 01:04
つまりXMLは糞ってことですね?
313デフォルトの名無しさん:2001/06/16(土) 01:07
(car '(い(ろ(は 匂えど))))

(caadr '(い(ろ(は 匂えど))))

(car (cadadr '(い(ろ(は 匂えど)))))

(cdr (cadadr '(い(ろ(は 匂えど)))))
(匂えど)
(cadr (cadadr '(い(ろ(は 匂えど)))))
匂えど

こういうのXMLだとどうなるんだろう
314デフォルトの名無しさん:2001/06/16(土) 01:10
lisp ; XML
(car x) ; x.getTagName()
(cdr x) ; x.getChildNodes()
315デフォルトの名無しさん:2001/06/16(土) 01:12
(cadr x) ; x.getFirstChild()
316デフォルトの名無しさん:2001/06/16(土) 01:16
<い><ろ><は>匂えど</は></ろ></い>.getTagName()

ですか?>315
317デフォルトの名無しさん:2001/06/16(土) 01:22
>>316
ごめん良く知らない。DOMで検索して
318デフォルトの名無しさん:2001/06/16(土) 01:24
lispわかるなら、こういうの使えばいいかも
XMLTOOLS
http://www.graco.c.u-tokyo.ac.jp/~kamina/xmltools/
319デフォルトの名無しさん:2001/06/16(土) 01:49
ありがとう。>318
でもおおきいですね。(ファイルが)
reader/writerだけ抜き出して使うことにします。
320デフォルトの名無しさん:2001/06/16(土) 02:42
属性はどうするんだろう。
やっぱget/put使うのか。
321デフォルトの名無しさん:2001/06/16(土) 04:31
get/putは symbolごとにしか使えないんじゃ...
322デフォルトの名無しさん:2001/06/16(土) 06:11
>>321
となると
(tag (attr (name value) (name value) ...) contents...)
かな?
323デフォルトの名無しさん:2001/06/18(月) 04:46
職業プログラマだけど、Scheme萌え〜!
ついでにSICPも一緒に萌え〜!!
324デフォルトの名無しさん:2001/06/19(火) 00:36
処理系の大きさを考えれば、
自作言語はschemeで決まり。
325デフォルトの名無しさん:2001/06/19(火) 00:45
>>324
小さくて済むから幸せだよ、という意味での発言だとすれば、
じゃあForth系は?という反論が来ると思われ。

使いたくはないけどなForth(藁
326デフォルトの名無しさん:2001/06/19(火) 03:04
schemeって、もしかして無限相互再帰してもスタック消費しない?
(define (x n) (display 'x) (display n) (y (1+ n)))
(define (y n) (display 'y) (display n) (z (1+ n)))
(define (z n) (display 'z) (display n) (x (1+ n)))
(x 0)
x0y1z2x3y4z5x6y7z8x9y10z11x12y13z14x15y16z17x18y19z20...
327デフォルトの名無しさん:2001/06/19(火) 04:25
>>326
インタプリタでは消費しない実装方法があるけど、
それを言語仕様で保障してるか不明。多分処理系依存でしょう。
今試しに、hobbitっていうscheme->cトランスレータ通したら
ただの関数呼出しになっていました。
(このトランスレータは自己末尾再帰やnamed-letとかならgotoに直せる)

SCM x(n)
SCM n;
{
display(x_symb,cur_output_port());
display(n,cur_output_port());
return y(apply(GLOBAL(nonum_prefix_1_plus_),n,listofnull));
}

SCM y(n)
SCM n;
{
display(y_symb,cur_output_port());
display(n,cur_output_port());
return z(apply(GLOBAL(nonum_prefix_1_plus_),n,listofnull));
}

SCM z(n)
SCM n;
{
display(z_symb,cur_output_port());
display(n,cur_output_port());
return x(apply(GLOBAL(nonum_prefix_1_plus_),n,listofnull));
}
328デフォルトの名無しさん:2001/06/19(火) 04:40
letrecで試しても同じ結果
(define (xyz n)
  (letrec (
    (x (lambda (n) (display 'x) (display n) (y (1+ n))))
    (y (lambda (n) (display 'y) (display n) (z (1+ n))))
    (z (lambda (n) (display 'z) (display n) (x (1+ n))))
          )
    (x n)
  ))
329デフォルトの名無しさん:2001/06/19(火) 04:42
SCM xyz(n)
SCM n;
{
  return xyz_fn1(n);
}

SCM xyz_fn3(n__6)
SCM n__6;
{
  display(z_symb,cur_output_port());
  display(n__6,cur_output_port());
  return xyz_fn1(apply(GLOBAL(nonum_prefix_1_plus_),n__6,listofnull));
}

SCM xyz_fn2(n__5)
SCM n__5;
{
  display(y_symb,cur_output_port());
  display(n__5,cur_output_port());
  return xyz_fn3(apply(GLOBAL(nonum_prefix_1_plus_),n__5,listofnull));
}

SCM xyz_fn1(n__4)
SCM n__4;
{
  display(x_symb,cur_output_port());
  display(n__4,cur_output_port());
  return xyz_fn2(apply(GLOBAL(nonum_prefix_1_plus_),n__4,listofnull));
}
330デフォルトの名無しさん:2001/06/19(火) 20:28
確かにインタプリタだと止まらない。
331デフォルトの名無しさん:2001/06/19(火) 23:43
Schemeを最近始めました。読むのはつらいですけど書くのは楽しいです。
Scheme で「モジュール」的なプログラミングをしたいときどうしますか。
つまり、複数の関数のみで共有する変数・関数を作りたいときです。
(Cでいうと、関数の外で定義されたstatic変数・static関数みたいなやつ)
「プログラミング言語Scheme」に書かれていた方法で行くと

(define set-var #f)
(define get-var #f)
(let ((local-var #f))
  (define (set-var-1 x) (set! local-var x))
  (define (get-var-1) local-var)
  (set! set-var set-var-1)
  (set! get-var get-var-1) )

ちょっと面倒ですけど、これでlocal-varは外からはアクセスできないように
できますね。
実際に皆さんはこういうふうに書いているのでしょうか。
332デフォルトの名無しさん:2001/06/20(水) 00:12
> 327 名前:デフォルトの名無しさん投稿日:2001/06/19(火) 04:25
> >>326
> インタプリタでは消費しない実装方法があるけど、
> それを言語仕様で保障してるか不明。多分処理系依存でしょう。

保証してるよ。R^5RSの「Proper tail recursion」の節を読むべし。
333デフォルトの名無しさん:2001/06/20(水) 00:29
>>331
その方法でも良いんだけど、
変数の直接変更を嫌うなら、メッセージパッシングという方法があるよ。
メッセージを処理するクロージャを返す関数を作るんだけど。
これを使うと、必ずメッセージ経由でデータが処理される事が保障される。
例えば下は文字列のポインタを表現するオブジェクト
メッセージに使うアトムは何でも良いけど、ここではシンボルだけを使ってます。
(define (make-strptr s)
  (let ((pos 0)) ;s のoffset
    (lambda (m)
      (case m
        ((++) (set! pos (+ pos 1)) #t) ; ポインタを1文字進める
        ((--) (set! pos (- pos 1)) #t) ; ポインタを1文字戻す
        ((refch) (string-ref s pos)) ;文字の参照
        ((setch) (lambda (ch) (string-set! s pos ch) #t)) ;文字の設定
        ((reset) (set! pos 0)) ;位置のリセット
        ((rest) (substring s pos (string-length s))) ;参照位置以降の文字列
        (else #f)
      ))))

;make-strptrは文字列"abcd"を管理するポインタを作る
(define strptr (make-strptr "abcd"))
=>strptr
(strptr '++)
=>#t
(strptr 'refch)
=>#\b
((strptr 'setch) #\x)
=>#t
(strptr 'rest)
=>"xcd"
334デフォルトの名無しさん:2001/06/20(水) 00:51
(retrec ((this (lambda (m) 〜
 ((++) (set! pos (+ pos 1)) this)
 〜))
 this
)
副作用が目的で、戻り値が必用無いメッセージの場合、
上の様にthis(メッセージ処理closure)を返す様にすれば、
(strptr 'rest)
=>"abcde"
((strptr '++) 'refch) ;1文字進めて今注目してる文字を返す。
=>#\b
の様に書ける。
335デフォルトの名無しさん:2001/06/20(水) 03:16
336デフォルトの名無しさん:2001/06/20(水) 23:44
SICPにデータ主導プログラミングの方法が載ってるけど
あれでは駄目ですか?>331
337331:2001/06/21(木) 01:54
>>333,334
そのような手法もあるのですね。良く分かりました。
ありがとうございました。
>>335
ちょっと敷居が高そう。でも努力してみます。ありがとうございました。
>>336
SICP?調べたら有名な教科書なんですね。
恥ずかしいことに名前を聞いたこともありませんでした。
さっそく買いに行きます。ありがとうございました。
338デフォルトの名無しさん:2001/06/21(木) 21:44
(define generic-function-table
;優先度:高↑
`(
;書式(関数名 検査する型の並び 実際に呼び出す関数)
(- (,number?) ,-)
(+ (,number?) ,+)
(+ (,string?) ,string-append)
  ;・・・
)
;優先度:低↓
)

(call-generic-function '+ '(1 2 3)) ;引数が全て数値型なので+が呼ばれる
=>6
(call-generic-function '+ '("a" "b" "c")) ;引数が全て文字列型なのでstring-appendが呼ばれる
=>"abc"

引数の型によって呼び出す関数を切り替える総称関数みたいなのは
>>335の様な拡張ライブラリ使わなくてもできる。
CLOSみたいなクラスもこれにクラス用の述語(〜?)を定義すれば書けなくも無い。
マクロと併用すれば、型が限定されてるとき直接それ専用の関数を埋め込む事
もできそう。
(多分>>335のライブラリは型判定の効率を上げるためにコアをCで書き直したものだと思うけど。)
339デフォルトの名無しさん:2001/06/22(金) 03:18
>>338
>マクロと併用すれば、型が限定されてるとき直接それ専用の関数を埋め込む事
そのやり方だと、埋め込めるのは引数が定数の時だけだよ。
他(変数やリスト)はどうしても動的判定になる。(CLOSも同じ)
(apply-generic-funcrion + (<a-class> a) 1 2)
(apply-generic-funcrionはマクロとする)
とか、型を明示的に指定すればマクロ内で埋め込み処理可能かもしれないけど。
340デフォルトの名無しさん:2001/06/22(金) 23:01
Lisp の中をのぞいてみると...

新人「あ!先輩!何かS式がやってきましたよ!」
先輩「先頭にアポストロフィーついてっか?」
新人「はい、ついてます!」
先輩「よし、だったらそのままピーコしてエコーエリアに流せや」
新人「え!そんなんでいいんですか?」
先輩「おうよ、頭にアポストロフィーがついてるやつは、そのまま流せ。楽でえーわ」
新人「こんなんで給料もらっていいのかなぁ...あ!先輩!こんどは頭にアポストロフィーがついてないやつがきました!」
先輩「なに...?!」
341デフォルトの名無しさん:2001/06/22(金) 23:13
「前回までのあらすじ」
-- 大学卒業後、知人の紹介で Lisp で働くことになった新人 K 君。
少々口は悪いが気はやさしい先輩にめぐまれ、新人研修をこなす毎日だが.... --

先輩「そのS式の1番目のアトム確認しろや」
新人「はい!えーと,,, + って書いてますね」
先輩「プラスか...(ニヤソ)またきやがったか」
新人「よくくるんですか?」
先輩「まあな...おい、おまえ、大至急資料室いって、+のデーター集めてこいや」
新人「了解しました!」

いきおい良く廊下に飛び出していく新人君。
しかし、彼に恐ろしい運命が待ちうけているとは誰が想像できただろうか....

<第2部に続く>
342デフォルトの名無しさん:2001/06/22(金) 23:57
>>340-341
新人 :read write その他雑用
先輩 :eval apply
資料室 :環境
ですか?

うちの環境だと起動時の初期化だけで
新人、先輩とも8万回(単純計算)は呼びだし食らってます。
大変だなあ・・。
343デフォルトの名無しさん:2001/06/23(土) 01:39
Visual LISPとか無いのかねえ。
344デフォルトの名無しさん:2001/06/23(土) 04:33
>>343
VisualC++みたいなのか?それともVB/Delphiの方か?
どのみちGUI作ったりしない限りは、名前補完と括弧対応付け
できるエディタぐらいしか用無いんだけど。
345デフォルトの名無しさん:2001/06/23(土) 10:15
Smalltalk-80 のイメージみたいに、Lisp による Lisp のための
ウィンドウシステムつき Lisp ってのはフリーでは無いのかなあ。
346デフォルトの名無しさん:2001/06/23(土) 10:19
がいしゅつだがSTkじゃだめか?
さいきんはGuile-Gtkとかもあるが…
ST80ぐらいまで統合されているのは見たことない。けど、むかしのLispマシンってのはそうだったんでしょ?
347デフォルトの名無しさん:2001/06/23(土) 12:11
「リスト遊び」本にしばしばリストが繋がっているさまを描いた絵が
出てくるんだけど、ソースからあの絵を起こすんじゃなく逆に
あーいう絵「を」ぐりぐり動かすことでプログラムを「書く(描く?)」
ってのはLispとかでは望めそうですか?

特にLisp系は仕掛けが単純化されてるんで相性が良いと思うんだけど、
CARとかをマウスでつまんで他のCellにDropすると
参照を示す線がびゅびゅっと出て…みたいなのって
簡易プログラミングとして楽しいと思うのだが、どう?

掃除機の電源ケーブル引きまわしみたいなイメージだな(藁

頼むから、そういうのを学研の付録としてつけてくれぃ。
子供がみんな喜んでいじくりまわすぞ。
348デフォルトの名無しさん:2001/06/23(土) 23:42
>>345
やっぱり電通大の竹内郁雄氏に弟子入りするしかないのでわ。
相変わらずハードからLisp作っているそうだし。
349デフォルトの名無しさん:2001/06/25(月) 01:40
(substring "The quick brown fox jumped." 16 19)

これを評価すると
"fox"
と結果が返ってきます。次に

(substring "The quick brown fox jumped." 16 18)

これを評価すると
"fo"
になります。
ということは、
16 → f
17 → ?
18 → o

となるのでしょうか。
350デフォルトの名無しさん:2001/06/25(月) 01:43
自己解決しました。
3番目の引数は、抜き出したい文字列のひとつ右側を指定する、ということです。
351デフォルトの名無しさん:2001/06/26(火) 00:52
global環境で
(define *toplevel* '())
(call/cc (lambda (cont)
(set! *toplevel* cont)))

を定義したあと、任意の階層/場所で
(*toplevel*)
これって合法ですよね?
ところで、こういう風に返った時は、
call-with-i/o関係の後始末はしてくれるものですか?
352デフォルトの名無しさん:2001/06/26(火) 01:25
> 351 名前:デフォルトの名無しさん投稿日:2001/06/26(火) 00:52
…中略…
> を定義したあと、任意の階層/場所で
> (*toplevel*)
> これって合法ですよね?

合法。

> ところで、こういう風に返った時は、
> call-with-i/o関係の後始末はしてくれるものですか?

GCが回収するか陽に閉じるまでは、開かれたportは閉じてはいけないことになっ
ている。R^5RSのPortsの節を読むべし。
353デフォルトの名無しさん:2001/06/26(火) 01:39
ありがとうございます。>>352
ということは、やっぱりi/o-portとかを自動的に(確実に)破棄
したい場合CommonLispでいうunwind-protectの様な機構を自分で
作っておく必要があるみたいですね。
354デフォルトの名無しさん:2001/06/26(火) 06:42
今月のCマガ見たらschemeの記事が載ってた。(コラムで2ページだけ。)
やっぱGuileとかの影響?
記事書いてたのがきだあきら氏ってのもあるだろうけど。
他のページにrubyの末尾再帰の話題が出てたのが興味深い。
rubyって末尾再帰展開やってくれないんだね。
355デフォルトの名無しさん:2001/06/26(火) 21:58
schemeの継続を使ってマルチスレッドモドキを作れるって
どこかで聞いたんですが、これは協調型スレッドの事ですか?
356デフォルトの名無しさん:2001/06/27(水) 05:34
>>355
多分そうです。
どう考えてもプリエンティブにはならないと思います。
OS側で用意されてる割り込みとか、特殊な物使えば出来そうですが。
(OSネイティブでスレッド機構があったらそれ使った方が良い)
継続でやる場合、恐らくVBのDoEventみたいな関数を用意して、
自前で切り替えタイミングを発行をする様な形になる筈です。
実装するとしたら、おそらくこんな感じです。

(継続振り分け関数)

↓起動   ↑各スレッド内でDoEvent関数を呼ぶと振り分け関数に継続が渡る

(スレッド関数1) (スレッド関数2) (スレッド関数3)
357デフォルトの名無しさん:2001/06/27(水) 05:45
恐らく継続でスレッドを作る利点は、環境依存しない事ですが、
継続の切り替え効率が悪い処理系があると思います。
例えば、継続をハードウェアスタックで管理している処理系は
切り替える度にスタックのコピーが発生するので遅くなります。
ヒープで管理している処理系ならば瞬時に切り替わります。
(ただし、後者は元々全体的に遅い。)
358デフォルトの名無しさん:2001/06/27(水) 05:51
あと、排他制御が必要無いので、タイミングによる不具合が
発生しないというのも利点だと思います。
(この切り替え機構を「スレッド」と呼んでいいの疑問ですが。)
359デフォルトの名無しさん:2001/06/27(水) 06:47
その方法って、どこかのスレッドがI/O待機関係とかでブロックしたら、全体が止まってしまうんじゃない?>358
細切れにするか、非同期I/OにしてWaitForObjectとかで待てばいいんだろうけど。
GUI作るとき何も考えずにメッセージループを複数作れる、ってのはいいかもね。
360デフォルトの名無しさん:2001/06/27(水) 07:17
コルーチン?
361デフォルトの名無しさん:2001/06/27(水) 16:00
コルーチンの一種なんだけど、Smalltalk の fork. とか Mac (w
や昔の Windows のナニとかも含めて、協調型マルチタスクと呼ばれる
ことが多いと思う。コルーチンっていう言い方は、複数の「関連した」
処理が continuation で協調動作してひとつのタスクを遂行する、
って場面でより多く用いられるんじゃないかな。
362デフォルトの名無しさん:2001/06/28(木) 02:09
Lisp を学ぶことは、最初の道が急な坂であるような丘を登るようなものである。あなたが現在登っているのはもっとも急な部分である。先に進むに従って、より楽に進めるようになるはずだ。

↑とか書いてあるが、先に進めば進むほど、難しくなってきたぞゴルァうそつくなや
363デフォルトの名無しさん:2001/06/28(木) 03:08
>>362
どのへんが難しい?
364デフォルトの名無しさん:2001/06/28(木) 03:54
初心者だと最初に躓きそうなのはdot対とか
365デフォルトの名無しさん:2001/06/28(木) 05:38
IO関係の関数を全部定義しなおして wrapperかけてやって..
面倒くさいけど、そういうのもできるな>>359

CMU CommonLispとかは、command lineの裏で走ってる
ものとかあったな.. あれはなんだったんだろ。
よくわからず使っていた俺。
366デフォルトの名無しさん:2001/06/29(金) 06:28
こんな感じで書ければ既存コードに(do-event h)埋め込むだけで使えそう。
(define t (make-thread-object))
;thread closureの登録
((t 'beginthread) 'id1 (lambda (h) 〜(do-event h)〜 (endthread h)))
=>id1
((t 'beginthread) 'id2 (lambda (h) 〜(do-event h)〜 (endthread h)))
=>id2
((t 'beginthread) 'id3 (lambda (h) 〜(do-event h)〜 (endthread h)))
=>id3
;thread id1〜3の振り分けの実行
(t 'run)
---------
tは振り分け
hは各threadのuniqなハンドル

suspend/resumeも作れば結構実用性あるかもね。
367デフォルトの名無しさん:2001/06/29(金) 06:55
メッセージパッシングを用いない場合はこんな感じ
(runthread (lambda (t)
 ;thread closureの登録
 (beginthread t 'id1 (lambda (h) 〜(do-event h)〜 ))
 (beginthread t 'id2 (lambda (h) 〜(do-event h)〜 ))
 (beginthread t 'id3 (lambda (h) 〜(do-event h)〜 ))
))
最後のendthreadは自動で呼び出す様にすれば必要ないね。
作るのはちょっとめんどっちいかな?
368デフォルトの名無しさん:2001/06/29(金) 17:29
Lisp って C で作られてるの?
369デフォルトの名無しさん:2001/06/30(土) 04:50
>368
lisp自身は当然として、
アセンブラとかjavaとかawkとかもあるよ
質はまちまち
370デフォルトの名無しさん:2001/06/30(土) 13:10
それじゃあ、Lisp を真に理解するためには、まず C を勉強しなければならないの?
でも、C のコード書くためにエディターが必要で、Emacs 使うなら、Emacs Lisp の勉強が必要で、Lisp の理解のために C の知識が必要で、......
371デフォルトの名無しさん:2001/06/30(土) 13:14
Lispを理解したいならLispを理解すればいい。
372デフォルトの名無しさん:2001/06/30(土) 13:43
>>370
あんたの理屈だと、Cを勉強するためにはアセンブラが
必要で、アセンブラのためにはハードの知識や
デジタル回路理論、量子力学までぜんぶ必要になるんじゃないか?
373デフォルトの名無しさん:2001/06/30(土) 13:50
Lispのエッセンスを理解するには
まずS式をconsセルのリストとみなすこと.
そうすれば様々な操作が自然に見える.
あとはS式の評価規則だけ.
374デフォルトの名無しさん:2001/06/30(土) 14:29
確かにそうですよねぇ...
もし、
「日本語はもともと中国語からできてるのだから、本当に日本語を理解したければ、まず中国語を学ぶべきだ」
という主張があったらかなり変ですしね。

言語学者がそのようにいうならいいかもしれませんが、0才児にそんなこといっても意味ないですしね。
375デフォルトの名無しさん:2001/06/30(土) 18:01
ただ、Lispを使ってても計算機のアーキテクチャに関する
知識はいずれ必要になってくるが、それはOfficeを使うのに
PCIカードやドライバのインストールについて知らなきゃいけない
のと同じよーなもんだ(すこしちがうかな)。
376デフォルトの名無しさん:2001/06/30(土) 20:13
「Lispを理解したい」ってだけなら>>371が言った、
>Lispを理解したいならLispを理解すればいい。
で十分だよ

ただしlisp処理系を作りたいのであれば、それの基盤言語を何にするかに
よってその基盤言語の理解が必要。
lispでlispを作るのであれば理解するのはlispだけでいい。
実行効率を上げる必要があれば基盤言語に効率の良さそうな言語を選べばよい。
377デフォルトの名無しさん:2001/06/30(土) 20:21
で、実行効率と汎用性の点などで考えると、
基盤言語にCやアセンブラの組み合わせを使う場合が多い。
378デフォルトの名無しさん:2001/06/30(土) 20:27
これはperlやpython、rubyやC、pascalなど、
他の言語にも言えること。
perlを使うのにperlの実装を知る必要は無いでしょ。
379デフォルトの名無しさん:2001/06/30(土) 20:35
ただしlispは構造が単純で、自分で手軽に作成する事ができるから、
実装を理解するハードルは比較的低い。
現にlispのほとんどの教科書にはlispをlisp自身で作成/拡張する、
という章があったりする。
380デフォルトの名無しさん:2001/07/01(日) 00:26
>>363
この練習問題が難しいです。
でも、答えは書かないで下さい。
自分で考えます。

「現在の fill-column の値が関数に渡される引数よりも大きいかどうか判定し、もしそうなら適当なメッセージを表示するような関数を書きなさい。 」
381デフォルトの名無しさん:2001/07/01(日) 00:56
>>380

       ∧∧
       ( ゚∀゚) あーできたー
       ヽ|〃
 ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄

(defun hantei (number)
"setumei"
(interactive "p")
(if (> fill-column number)
(message "fill-column is bigger than the entered number!")))
382デフォルトの名無しさん:2001/07/01(日) 20:34
昔(386とか486時代)lispインタプリタ上で動くlispって作ったけど、かなり遅かった。
バイトコードコンパイラでも作っておけば、もうちょっと改善されたかも
しれないけど。(でもバイトコードの設計って大変)
今はインタプリタだけでもそこそこの速さで動くからありがたい。
383デフォルトの名無しさん:2001/07/01(日) 20:40
ものすごい遅レスだけど、
>>29
itemをclosureにすれば表示させても問題無いよ。
(define (make-item obj next prev)
 (lambda (m)
  (case m ((next) next)
      ((prev) prev)
      ((obj) obj)
      ((set-next!) (lambda (p) (set! next p)))
      ((set-prev!) (lambda (p) (set! prev p)))
      ((set-obj!) (lambda (p) (set! obj p)))
  ) ))
384デフォルトの名無しさん:2001/07/01(日) 20:48
あと、メッセージパッシンングだけど、
よく使うメッセージについては常にclosureを返すようにすれば、
そのclosureをdefineすることでメッセージ探索の数を減らす事ができるよ。

>>383のmake-itemの例なら、
;メッセージパッシングclosureを作成
(define item (make-item 'obj 'next 'prev))
;メッセージ処理後のclosureを保存
(define item-set-next! (item 'set-next!))
(define item-set-prev! (item 'set-prev!))
;直接closureを呼ぶ
(item-set-next! 'next) ;itemのnextに影響
(item-set-next! 'prev) ;itemのprevに影響
385デフォルトの名無しさん:2001/07/01(日) 21:36
>>383の双方向リストの要素の様に、沢山生成される
可能性がある場合、closureにすると、環境フレームを1つ
作成する事になるわけで、例えば環境フレームを
(変数名 . 値)のペアの連想リストで保持する処理系だと、
((obj .var1) (next .var2) (prev .var3))
こうなって、consセルが6個必要になる。
>>29の方法そのままでは
(var1 var2 . var3)
consセルは2つで済む。
引数を
(make-item obj next prev) -> (make-item obj-next-prev)
という風にまとめても、
((obj-next-prev .(var1 var2 . var3)))
consセルは4つ必要。
どちらにしろ倍にはなるので、あまり小さい単位ではclosure化は
しない方が良いと思います。(処理系に依るでしょうけど)
386デフォルトの名無しさん:2001/07/01(日) 23:17
>>385
じゃあ、内部では(cons obj (cons next prev))で処理して、
外部に出す時はiterater(pointer)の機能を持った
closureでラップして返す様にすればよいかな?
387デフォルトの名無しさん:2001/07/03(火) 21:09
>>351
デストラクタのclosureのstackを作っておいて、
あとで一気に実行すれば、安全な破棄ができると思う。
(define (closure-stack) (display "bottom"))
(define (closure-push closure)
 (let ((old-closure-stack closure-stack))
  (set! closure-stack
   (lambda ()
    (closure)
    (set! closure-stack old-closure-stack)
    (old-closure-stack) ))))
;デストラクタ
(define (test n) (lambda () (display n)(newline)))

;デストラクタの登録
(closure-push (test 1))
(closure-push (test 2))
(closure-push (test 3))
(closure-stack)
3
2
1
bottom
;もう一度実行しても123は呼び出されない。
(closure-stack)
bottom
388デフォルトの名無しさん:2001/07/03(火) 21:22
(closure-stack)をerrorの時一緒に呼び出すって意味ね
389デフォルトの名無しさん:2001/07/03(火) 21:29
>>353
なんだ、unwind-protect知ってる人なのね・・・
390デフォルトの名無しさん:2001/07/04(水) 21:05
( ゚∀゚)
Error: Unbounded variable ゚∀゚
391デフォルトの名無しさん:2001/07/06(金) 23:30
schemeにもlispのpackageがほしい
392デフォルトの名無しさん:2001/07/07(土) 00:16
read-eval-loopを細工すれば出来るかもしれないが、
環境依存
393デフォルトの名無しさん:2001/07/07(土) 02:16
winでschemeやりたいんだけど、どれがいいの?

Lisp初心者。Common Lisp, Emacs Lispなどは名前を知っているという程度。
C,Java,Perlなどは初心者++。

ちなみに、
ChezEdit
http://www5a.biglobe.ne.jp/~sasagawa/MLEdit/Scheme/index.html
を使ったところ、括弧がうざいというのは幻想なんだなと思いました。
(まだまだ短いプログラムしか書いてないからかも?)

で、ChezEditを使っていて思ったのは、前置式うざい、ということ。
Lispの勉強をまともにやる前(本のソースを眺めてたころ)は、「あー括弧うぜー」
でした。しかし、やり始めると、括弧より前置式のほうがはるかにうざく感じます。
慣れてないというのもあると思います。

しかし、エディタのモードでなんとかなるのでは?とも思いました。

例えば、
(a + b) * c
を前置式で入力するとき、
(+ a b)
って入力してから、「あ”、*あった・・・。欝だ」みたいな感じです。
このとき、カーソル左を連打して、忘れていたのを挿入してます。
(↑ここが、エディタのモードを使えばなんとかなるかな?と思った)
(例えば、M-x chotto-modoru(仮))
(Emacsに(たぶん)schemeモードとかあると思うけど)
Winではxyzzy使ってるし・・・。


みなさんは前置式の入力はどうやってますか?
394デフォルトの名無しさん:2001/07/07(土) 09:17
Emacsだと M-C-b ( * SPC M-C-f SPC c ) だね
395デフォルトの名無しさん:2001/07/07(土) 20:06
>>393
WinやUNIXならSCM(Guile)/STK/ELK/DrScheme/RScheme/MITSchemeなど、
フリーで色々選択肢あると思います。
SCMが速いという話をどこかで読んだ事がありますが、
実際に計った事はないのでなんとも言えません。
bashのコマンドラインに慣れているなら、readlineが組み込まれているGuileとか。
日本人が現在進行形で作って公開してるやつはgaucheやrhizome/piというのがあります。
これらは日本語も問題無く扱えると思います。
(私は公開してませんが、自作のやつ使ってます。)
396デフォルトの名無しさん:2001/07/07(土) 20:12
>>393
>みなさんは前置式の入力はどうやってますか?

中置式を展開するフィルター使うって手は・・?

(infix-expand b * q + a * q + a * p)
=>(+ (* b q) (* a q) (* a p))

こういうのは自分で作るしかないけど、便利ですよ。
今持ってるやつは、リスト→リスト変換なんで、セパレータに
空白入れる必要があるから不便です。
文字列→リストにすれば見やすいかと思います。

(infix-string-expand "b*q+a*q+a*p")
=>(+ (* b q) (* a q) (* a p))

Guileという処理系にこういう中置文字列→前置リストの
変換ライブラリがある様です。
397デフォルトの名無しさん:2001/07/07(土) 21:12
emacsならバッファの内容をS式と見なして評価できるんじゃないの?>393
398デフォルトの名無しさん:2001/07/07(土) 21:53
lisp使うならエディタをemacsやxyzzyに乗り換えた方がいいでしょうか?
399デフォルトの名無しさん:2001/07/08(日) 20:50
補完、ヒストリ付きの一行エディタあれば十分な気もする
400デフォルトの名無しさん:2001/07/09(月) 01:06
前置式つーか、lispに演算子は無いからねえ。>>393
全部関数呼出しと考えればいいんじゃないの?
演算子として使いたいなら、>>396 みたいに式解析させた方が後々楽だと思うよ。
401デフォルトの名無しさん:2001/07/09(月) 23:50
cygwin版(かwinで動く)lispってないんですか?
エディタのおまけではなくって純粋な処理系が欲しいです
402デフォルトの名無しさん:2001/07/10(火) 01:02
沢山あると思うんだけど。
検索してみれ>401
403デフォルトの名無しさん:2001/07/10(火) 20:34
CommonLisp処理系の中でメジャーなのってなんだろ?
漢字対応してる処理系って事だとかなり限られてくると思うんだけど。
xyzzyは駄目なの?>401
404デフォルトの名無しさん:2001/07/10(火) 21:33
研究用では Allegro CL がよく使われてる。
405デフォルトの名無しさん:2001/07/12(木) 03:18
たかいよ>ACL
それないの性能なんだろうけど。
学割効くとなんぼかましになるのかな
406デフォルトの名無しさん:2001/07/13(金) 19:10
progn てなんて発音するの?
ぷろぐん?
407デフォルトの名無しさん:2001/07/13(金) 21:00
prog1 ぷろぐいち ぷろぐわん
progn ぷろぐえぬ
読み方の根拠は、元々n番めの評価結果を返すって意味だろうから。
prog1は最初の評価結果。
408デフォルトの名無しさん:2001/07/13(金) 21:10
n番め、つーのはシーケンスの最後って意味ね。
programよりsequenceって名前にすればわかりやすかったん
じゃないかと思う。
Schemeのbeginも用途の割に変な名前。
恐らくPascal言語辺りのbegin 〜 endから取ったんだろうけど、
そもそもschemeにはendが無いし。
ネーミングセンスよくないよね。
409デフォルトの名無しさん:2001/07/13(金) 21:19
元々lambda/let/condなどはbeginを含んでるから、
beginを直接コード上に置くことってあんまりないからいいけど。
破壊操作系に!、述語系に?を付けるって習慣はよい事だと思う。>scheme
規則を守ってるかどうかはともかく。
410デフォルトの名無しさん:2001/07/13(金) 21:27
rplaca
rplacd
とかもいまいち。これはschemeだと
set-car!
set-cdr!
に対応する。
411デフォルトの名無しさん:2001/07/13(金) 21:38
(chubo? a)
412デフォルトの名無しさん:2001/07/13(金) 21:46
(chubo? 411)
413デフォルトの名無しさん:2001/07/13(金) 21:48
#t
414デフォルトの名無しさん:2001/07/13(金) 22:14
そもそもセンスの悪さはcar/cdrが元凶だと思われ。>408
(caddr '(a b c))
=>c
とか書けて便利なんだけど。
CommonLispでは、代わりにfirst/restがあるけど、
これは使い勝手悪し。(schemeでは消えた)
415デフォルトの名無しさん:2001/07/13(金) 22:16
>>409
nullやatomは歴史的経緯からか知らないけどpが無いのが納得いかない。
schemeでは それぞれnull? atom?
(atom?ってあったっけ)
実際は、これらを直接使って書いていく事はあんまり無いから良いかもしれないけど。
416デフォルトの名無しさん:2001/07/13(金) 22:19
(eq? >>411 >>412)
417デフォルトの名無しさん:2001/07/14(土) 21:02
>>391
packageというか、
環境のフレームを持ち回る、というのなら可能。
でもフレームの構造を知ってないと駄目だから、
やっぱり処理系依存という事になると思う。
(Schemeって環境の内部構造まで規定してないよね?)
418デフォルトの名無しさん:2001/07/14(土) 21:05
例えば、うちの処理系なら
(car (current-environment))
で現在のローカルフレームだけ取り出せる。
現在いる所がローカルフレームじゃ無ければグローバルフレーム。
(set! c-frame (append a-frame b-frame (interaction-environment)))
とでもして、この環境c-frameをevalすれば、
(eval expression c-frame)
expressionでの定義はc-frameに作成される。
これは単に処理系がこういう事するのを許しているからであって、
schemeの標準仕様には無いと思う。
これを踏まえた上てread-eval-printを書き換えれば、
packageのエミュレートも可能だと思う。
419デフォルトの名無しさん:2001/07/14(土) 22:31
フレームの保存
(define (make-package env) (lambda () env))
(define a-package #f)
(let () ;ローカルフレームのためのlet
(load "a.scm" (current-environment))
(set! a-package (make-package (car (current-environment))))
)
loadに現在の環境(letのローカルフレーム)を渡す。
環境をmake-packageで挟んでclosureにしているのは、
(current-environment)をそのまま表示した時に起きる再帰的な
不都合を、回避するため。
これで
(a-package)
とすれば、いつでもローカルフレームが得られる。
このローカルフレームを使いたい場合、
(eval expression (cons (a-package) (interaction-environment)))
とでもすれば、expression内でa-packageの定義がグローバル環境より優先的に参照される。
420デフォルトの名無しさん:2001/07/14(土) 23:11
ここまでをテンプレート化すると、
(define (make-package env) (lambda () env))
(define (package-expand name fn)
 (let ((pkg-name (string->symbol (string-append (symbol->string name) "-package")) ))
  `(begin
   (define ,pkg-name #f)
   (let ()
    (load ,fn (current-environment))
    (set! ,pkg-name (make-package (car (current-environment))))
   )) ))
(define-macro (package name fn) (package-expand name fn))

用法
(package a "a.scm")
=>#<closure>;a-package closureが生成される。

;;read-eval-print-loopにa-packageを適用する。
(read-eval-print-loop (cons (a-package) (interaction-environment)))
>(a-func) ;a.scmで定義された関数を使う。
=>ok
>(exit) ;ローカルのread-eval-print-loopを抜ける

(a-func) ;グローバル環境で使おうとしてもエラーになる
=>Error:Unbound symbol 'a-func'
421デフォルトの名無しさん:2001/07/14(土) 23:30
>>420はCommonLispのpackage機構には程遠い実装ですが、本質的には同じ事です。
(あっちはpackage間の移動とか、package:nameでアクセスできたりできますが。)
グローバル環境に沢山定義を溜めておくと、検索に時間が掛かったり、
名前の競合が発生したりと、良いことがあまりないので、
こういった機構は標準で存在すると便利なんだけど。
(せめて環境の内部構造までを標準化してくれるとありがたい。)
422デフォルトの名無しさん:2001/07/15(日) 00:10
package/use-package/require
辺りが初めから付いてる処理系はよく見かける。
CommonLispのやつと互換性あるのかは知らないけど。
423デフォルトの名無しさん:2001/07/15(日) 01:44
420見て思ったけど、beginって環境作んないんだね。
(if (undefined? hoge) (begin
(define hoge #t)
) (begin
(set! hoge #f)
))
グローバルに対して条件実行できるじゃん。
424教えて君みたいで嫌だけど:2001/07/15(日) 01:47
kispっていっぱいあって訳わからないんだけれど、
lispとschemaって違うの?
とりあえず有用なのはどれ?
覚えるには何で覚えるのがベスト?
425デフォルトの名無しさん:2001/07/15(日) 01:54
>>424
なんでもいいんじゃないの?
このスレはScheme中心みたいだけど。確かに今学習すんならSchemeはお勧め。
(Schemeは別に学習専用ってわけじゃないからね。)
GNUの標準スクリプトになりつつある様だし。
何からやるにしても、ある程度覚えればほかのlispも使える様になるよ。
426デフォルトの名無しさん:2001/07/15(日) 02:18
>>424
メジャー度でいうと、
EmacsLisp > CommonLisp > Scheme > その他lisp方言沢山
って感じだろうけど、少なくともEmacsLispは学習向きじゃないと思う。
非標準な関数だらけ。エディタと連携して使う分にはいい。
CommonLispは仕様が大きすぎるので、こればっかりやってると挫折しそう。
Schemeは確かに学習向きだけど、それでも既に他のlispを触わっている
事を前提にした説明が多い。(規格書がちょうどそんな感じ。)
多分、SchemeとCommonLispを交互にやっていくのが面白いと思う。

あとネットに転がっている、個人で公開してる様なマイナーな
lisp方言もたまに触わってみると感じが掴めると思う。
変なのに当たらなければ、こっちから入るのも良いかも。
427デフォルトの名無しさん:2001/07/15(日) 09:51
>>426
ウゥ俺は elisp しか判らないよ。
一度はちゃんとした lisp を勉強したいとはつねづね思っているんだけど。
428デフォルトの名無しさん:2001/07/16(月) 04:16
schemeがいいよ。
末尾再帰、継続の存在は知っといた方がいい。
429デフォルトの名無しさん:2001/07/16(月) 11:04
どうして、CommonLispとか、Schemeとかってはやらないのですか?
430デフォルトの名無しさん:2001/07/16(月) 21:40
見た目が怖すぎるから、か?(w>>429
機能的には流行のperl,ruby,python,java辺りとかと比べても、
引けはとらないとは思う。
実行速度も下手なスクリプト系言語より速いし。
lispの機能は他の言語に吸収されつつあるみたいだけど、それでも
オリジナルの貫禄はまだ保たれていると思う。
例えば、perlにもあるevalとかは、字句解析器通す必要ないから、
lispが圧倒的に速い。(意味も多少異なる。)
431デフォルトの名無しさん:2001/07/16(月) 21:42
人気が無い理由は、いくつか考えられるが、
演算子が無く、すべて関数記述(前置記法)で書かせるのが原因の一つ。
演算子として中置記法を処理するパーサーは簡単に書けるけど、
始めから用意されているわけではないし。
それと、何をするにも括弧で囲む必要がある。
セパレータは空白なので、くっつけて書くことができない。
432デフォルトの名無しさん:2001/07/16(月) 21:50
>>424
学習用には、非常にコンパクトなislispを使用しました。
http://www.okilab.com/islisp/
言語としては最低限ではあるのですが、
どのlispにでも応用が利きそうな言語仕様なので、いいと思います。
433デフォルトの名無しさん:2001/07/16(月) 22:13
elispも別にそれほど人気があるわけでは無い。
emacs信者が多いのは、ほとんどはエディタとしての価値が高いからでしょ。
確かにemacs==elispだけど、eispを主に使ってる人はあんまりいないみたいだし。
434デフォルトの名無しさん:2001/07/16(月) 22:28
lisperは、最終的に自分用のlispを作りたがる傾向にある。
これも一般向けしない理由。
実装コストがあまりかからず、機能拡張が他の言語に比べて易しい。
435Perl信者:2001/07/16(月) 23:54
>>429
このスレみて最近Schemeはじめました。
括弧や前置記法は個人的にはまったく抵抗ありません。

手を出しづらいのは、具体的に何ができるか、そのためにどう書くか、
という身近というか、下世話な情報が目立たないからだと思うのですが…。
Schemeの解説って、大抵Schemeの意義とか概念とか、難しい話が最初に長々とあって、
とにかく手をだしてみたいんだ! って人にはつらいかな、と。
本はまだ買ってないのでどうだかわかりませんが。
436デフォルトの名無しさん:2001/07/16(月) 23:59
>>434
自分用のlispと言えば、
自作のschemeにdllアクセス機能付けて使ってるけど、
Windowコールバックとかにclosure置けるようにしたので楽。
call-with-なんたらと感覚が一緒。
やっぱsoやdllは見えた方が良い。
437デフォルトの名無しさん:2001/07/17(火) 00:07

Tcp/Ip Addressing : Designing and Optimizing Your Ip Addressing Scheme (2nd Edition)
http://www.amazon.com/exec/obidos/ASIN/0122950216/103-5588829-5276648

こーゆーのもあるみたい。
438デフォルトの名無しさん:2001/07/17(火) 00:11
>>435
lisp系は基本的にi/o関係が弱いです。
S式に直してなんぼの世界なので。
実用的と言われる処理系には、その辺の弱い部分を吸収する
ライブラリがあるので、それで補います。
perlを知ってるなら、まず言語がどうのというより、
似た環境(socket/文字列処理/正規表現辺りなど)
が揃ってる処理系を使ってみては?
439デフォルトの名無しさん:2001/07/17(火) 00:20
うーん。みんなひっそりと個人用のプログラムに使っているんだろうね。
>>92 には消極的なレスしかつかなかったし。
ここに書込みされている方々がどんな用途にLisp/Schemeを使っているか
ぜひ知りたいです。
440デフォルトの名無しさん:2001/07/17(火) 00:43
>>437
このSchemeは体系という意味の名詞だろ。
441デフォルトの名無しさん:2001/07/17(火) 01:07
>>436
callbackの中でcall/cc呼ばれたときはどうしてる?
442デフォルトの名無しさん:2001/07/17(火) 01:11
>>439
自作schemeなんであんまり参考にならないかもしれないけど、
言語処理(構文解析、トランスレータ)
GUIとかのプロトタイプ
socket通信
HTML出力とかのバッチ処理
文字列処理(+正規表現拡張)
その他実験、雑用(bignumや分数も使えるんで、電卓代わりとか。)
速度を除いて、Cとほぼ同じ事(特にポインタ回り)ができる様に
ライブラリを拡張してるから、使い勝手は悪くない。
インタプリタとしての利点がほとんど。
処理系の大きさはwindowsのexeにすると100kbぐらい。
443デフォルトの名無しさん:2001/07/17(火) 01:14
>>441
エラーとかで復帰させる場合はlongjmpします。
復帰の必要が無いならcallback上で継続を切り替えます。
444デフォルトの名無しさん:2001/07/17(火) 01:24
継続を切り替えた後もcallbackのスタックは存在します。
なので、後で必ずcallbackの継続へ戻らなければまずいです。
(もしくは、どこかでlongjmpさせる機会を作る。)
よって、callback上での継続切り替えは結構制限が掛かります。
これは仕方ないかな?と思ってます。
445デフォルトの名無しさん:2001/07/17(火) 01:29
SCMとかはハードウェアスタックを直接切り替える様なので、
こういう場合では有利ですね。
446デフォルトの名無しさん:2001/07/17(火) 02:10
message loopで切り替えるなら問題ない
447デフォルトの名無しさん:2001/07/17(火) 09:45
ある問題を本質的に理解したいと思うとき、
SchemeとかMLなんかで解いてみると確実に
理解が深まるという印象がありますね。

実用システムにLISP/Schemeが使われない
理由は、開発環境と実行環境が一体化して
おり、実行可能ファイルだけを配布するの
に向かないからではないでしょうか。
Dylanの解説本にそういうことが書いてあ
りました。

Cにトランスレートしてコンパイルすれば
いいって言っても、開発時と異なる環境で
動作させて、本当に動作が変化しないとい
う保証はないわけですし。
448デフォルトの名無しさん:2001/07/17(火) 22:37
>>447
そういえばexe化は考えたこと無かったなあ。
lisp/scheme->cにするツールはいくつか有りますが、
質はまちまちみたいです。
(相互末尾再帰をちゃんと展開しないscheme->cトランスレータは最近見ました。)
ソース見せたく無いってだけなら、vbみたくschemeランタイムと
バイトコードモジュールの込みで配布するって手段が簡単そうですが。
(逆アセには弱そう)
449デフォルトの名無しさん:2001/07/18(水) 00:17
closureが絡むと厄介だね>トランスレータ
450439:2001/07/18(水) 01:03
>>442 レスどうもありがとう。
ちなみに私は、Chem3Dに食わせるファイルを作成するのに(分子を
構成する原子の座標の計算)、Schemeを使っています。
451デフォルトの名無しさん:2001/07/18(水) 01:06
(define (test)
 (let loop ((x 0))
  (lambda ()
   (display x) (newline)
   (loop (+ x 1)) )))
(define a (test))
(set! a (a))
0
(set! a (a))
1
(set! a (a))
2
こういうのだと、どういう風にCに変換されるのか、
ちょっと想像付かない。
全部gotoにするとかしないと、無理じゃないか?
452デフォルトの名無しさん:2001/07/18(水) 01:24
ああ、これだったらちゃんと変換するや。かしこいね。
453デフォルトの名無しさん:2001/07/18(水) 04:36
lispは名前付けるのに困らなくいいね。
とりあえずlambdaで作業始められる。
454デフォルトの名無しさん :2001/07/18(水) 06:46
lispってここではじめて知って情報なんとかってシリーズの本を
見てみたんですけど、何がなにやら・・・・
リスト処理言語とか書いてありましたけど、どんなことに使うとよい
言語なんですか?
455デフォルトの名無しさん:2001/07/18(水) 07:16
昔は、Lisp=人工知能
って感じだったけど、
今は、・・・、もっぱら研究用言語かな?
456デフォルトの名無しさん:2001/07/18(水) 07:36
>>453
禿げしく同意
457デフォルトの名無しさん:2001/07/18(水) 19:30
ではみなさんは何のために使っているんですか?
自分も単に触ってみたいと思っただけなのですが。
458デフォルトの名無しさん:2001/07/18(水) 21:19

ボキュは、この本を読むためにSchemeの勉強しました。
絶対に読む価値あります。
http://www.mmjp.or.jp/pearsoned/washo/prog/wa_pro20-j.html
459デフォルトの名無しさん:2001/07/18(水) 22:17
>>457
ある程度の定石さえ知っていれば、色んな処理がお手軽に書けるから、とか。
それと、自分にフィットする様に、言語自身に手直しを加える事が簡単なんだよ。
これはライブラリを作っていく様な事とは違う達成感がある。
460457:2001/07/18(水) 22:47
>>458
ワタシも読んでみたくなりました。
461デフォルトの名無しさん:2001/07/19(木) 00:39
基本的な事だけど、
シンボルが記号として、同一判定できるのがいい所だと思う。
文字列のままだと同値判定(strcmp相当)するしかないが、
文字列→シンボル変換すれば以後、
同一判定(ポインタ値の比較)だけで済む。
462デフォルトの名無しさん:2001/07/19(木) 00:45
.emacs をカスタマイズするために使うだけなので、Emacs-Lisp の
ごく簡単な構文しかしらないな…。
463デフォルトの名無しさん:2001/07/19(木) 00:57
>>462
lisp自体、複雑な構文はそれほど無いと思う。
構文唐を組み合わせれば複雑にもなるけど・・・。
464デフォルトの名無しさん:2001/07/19(木) 02:12
演算子が無い、ということは必然的に優先順位とかも無い。
syntaxを除いて、括弧のネストのレベルで評価される順番が決まる。
そういう意味で覚える事は少ない。
lispはコードを応用できるかどうかが肝。
465デフォルトの名無しさん:2001/07/19(木) 05:29
実際、quote lambda if define set!とか以外の構文は全部
マクロで作られた構文唐、ってscheme処理系は結構あるみたいね。
466デフォルトの名無しさん:2001/07/20(金) 01:14
>>423
beginがlambdaで構成されてたらアウト。
(define-macro (begin . l) `(lambda () ,@(cdr l)))
こういうやつだった場合ね。
eval使うしか無いんじゃないかと思う。
467デフォルトの名無しさん:2001/07/20(金) 01:17
こうだった。`((lambda () ,@(cdr l)))
468デフォルトの名無しさん:2001/07/20(金) 04:02
(define (・∀・) 'イイ!)
(・∀・)
=>イイ!
469デフォルトの名無しさん:2001/07/20(金) 19:20
>>466
そういう場合はletの結果をdefineすれば良いと思います。
 `(define ,pkg-name
  (let ()
   (load ,fn (current-environment))
   (make-package (car (current-environment)))))
470デフォルトの名無しさん:2001/07/21(土) 04:15
>>469
なるほど・・
なかなかトリッキーなコードに見えるけど、
schemeではこういうのが普通の発想なのか
471デフォルトの名無しさん:2001/07/21(土) 05:22
>>470
トリッキーに見えるのは恐らく、コードと環境を一緒に考えてるからだと思う。
472デフォルトの名無しさん:2001/07/21(土) 23:05
Schemeのオブジェクトは、どこかで参照されてる限り消えないので、
ブロックから抜けてもそこで生成したローカル変数が使える?
473デフォルトの名無しさん:2001/07/21(土) 23:34
>>472
objectは*永久に消えない*事が保障されてる。
ただしどこからも参照されなくなったobjectはgcで
勝手に回収されるのでメモリ不足とかの問題は起きない。
ローカル変数と言っても、中身はconsやstringとかで
動的に作られたobjectと一緒。
C++で言えばnewされたobject。
474デフォルトの名無しさん:2001/07/22(日) 00:31
こんなんがあった。

「普通のやつらの上を行け 」
http://www.shiro.dreamhost.com/scheme/trans/beating-the-averages-j.html
475デフォルトの名無しさん:2001/07/22(日) 00:40
letは値を局所的な名前でアクセス出来るようにフレームを作るだけで
値になるobjectまで生成するわけでは無いよ。(フレーム構成はobjectの集合だけど)
だから
(define (f i) (let ((a i)) (lambda()a)))
とした時、aはiに関連付けされた値をそのまま継承する。
fはclosureを生成して返すが、そのclosureはaを参照してる
ので、aの寿命はclosureと同じ期間に延長される。
(define x 0) ; 0 -> z
(define y (f x)) ;closure -> y
(eq? z (y)) ;object:0の同一性判定
=>#t
(eq? y (f x));object:closureの同一性判定
=>#f
476475:2001/07/22(日) 00:43
まちがえた
s/x/z/g
477475:2001/07/22(日) 00:54
で、>>469は(let()・・・)で作成した空のフレーム環境を使って
外部ファイルをloadして、そのフレームを返すclosureを作り、
そのclosureをpkg-nameにdefineする。
そのまま475のaがフレームに変わったと思えばいい。
478475:2001/07/22(日) 01:07
ちなみに標準的なloadには環境を設定する引数は取れないけど、
evalを直接呼んでそう言う風に作り直せる。
(define (load fn env)
 (call-with-input-file fn (lambda (r)
  (let loop ((s (read r)))
   (if (eof-object? s))
    'end
    (begin (eval s env) (loop (read r)))) ))))
479475:2001/07/22(日) 01:08
>>474
かなり前にがいしゅつっぽい
480475:2001/07/22(日) 01:12
s/(eof-object? s))/(eof-object? s)/
481デフォルトの名無しさん:2001/07/22(日) 01:13
>>479
スマソ
482デフォルトの名無しさん:2001/07/22(日) 07:12
John McCarthy's Home Page
http://www-formal.stanford.edu/jmc/
483デフォルトの名無しさん:2001/07/23(月) 01:10
クロージャの環境って、作った時点の環境で固定かと思ったけど、
(eval '(lambda()〜) env)
ってやれば適当な環境が見えるクロージャ作れるんだね。
484デフォルトの名無しさん:2001/07/23(月) 02:49
evalを使えば当然できる事だとは思うけどね。>483
応用として、evalの結果を使ってまた別の環境にbindとかすれば、
全く関係の無い環境から、他の環境を操作できる。
(eval '(define name (eval '(lambda()〜) env2)) env1)
これでenv2で作成したclosureをenv1からnameで参照できる。
頭硬くなると、こういう発想がなかなかできなくなって苦労する・・。
485デフォルトの名無しさん:2001/07/23(月) 06:04
いくつかのlispの処理系は、環境をalistとして取り出せるみたいだけど、
この辺まで規格化すると、実装に影響でるのかな?
486デフォルトの名無しさん:2001/07/23(月) 06:54
クロージャってなんですか?
487デフォルトの名無しさん:2001/07/23(月) 07:40
Steve Majewski によるクロージャーの特徴づけ

オブジェクトとは、処理が付加されたデータのことです。
クロージャーとは、データが付加された処理のことです。

dW : Linux : Pythonでの関数プログラミング (第2回)
http://www-6.ibm.com/jp/developerworks/linux/010706/j_l-prog2.html

原文
http://www.ibm.com/developerworks/linux/library/l-prog2.html
488デフォルトの名無しさん:2001/07/23(月) 20:14
C++Builderにも__closureつうのがあるね。
同じ物かは知らないけど。
void (__closure *func)();
489デフォルトの名無しさん:2001/07/23(月) 21:21
lispでのクロージャは、定義された場所から見える局所的な
環境が参照できる関数オブジェクト
環境がどこかで変更されれば、それを参照している
クロージャ自体も影響を受ける。
490デフォルトの名無しさん:2001/07/23(月) 23:30
>>488
あれは、delphiでいうTMethod型、つまり
あるObjectポインタと、そのObject用のどれか1つのメソッドのポインタ
のペア、だな。
なるほど、>>487の説明にドンピシャ一致してるかも(わら
491デフォルトの名無しさん:2001/07/23(月) 23:41
>>487を踏まえて整理すると、
普通の関数とクロージャの違いは状態(データ)を持つかどうかで、
オブジェクトとクロージャの違いは、
データ主体か関数主体かの違いって事ですかね・・?
492デフォルトの名無しさん:2001/07/23(月) 23:46
関数主体じゃなくて、処理主体でした。
「主体」って表現自体が曖昧っぽいですが。
493デフォルトの名無しさん:2001/07/24(火) 00:55
>>491
状態というか、そのクロージャを作った場所での環境が見える。
494デフォルトの名無しさん:2001/07/26(木) 04:17
lispのはレキシカルクロージャというらしい。
どっかのサイトに書いてあった。
495デフォルトの名無しさん:2001/07/26(木) 15:14
>>493
491はネストしたクロージャを想定していないから、状態と環境の違いが
わかりにくいんだろう。
496デフォルトの名無しさん:2001/07/26(木) 21:44
「As far as Lisp is concerned, the words we have been using in the lists cannot be divided into any smaller parts and still mean the same thing as part of a program;
likewise with numbers and single character symbols like `+'. 」

これの日本語訳が

「Lisp について話している限りは、我々がリストの中で使ってきた単語は、それ以上小さなプログラムのパートには分解出来ない。それは数字や `+' みたいな一つの文字からなる記号でも同じである。」

となっていますが、なんか違うような気がします。

特に
「mean the same thing as part of a program」
の部分がよくわかりません。
497俺的意訳:2001/07/26(木) 22:16
Lispについて話している限り、我々がリストの中で使ってきた概念
はほかのより小さな概念を使って説明できるものではない。
プログラムについても同じことが言える。たとえば+という一文字
の記号ですらそうである。
498デフォルトの名無しさん:2001/07/27(金) 04:11
499名無λ式:2001/07/27(金) 05:02
>>496
わざと仰々しく書いている文章上の遊びを無視すると、
「Lisp におけるリスト用語は、これ以上分割することは不可能であり、
プログラム中においても同じ意味であり続ける。
数や `+' のようなたった一文字の記号と同じように。」

"still"は「不変」を強調している。

要するに、car, cdr, cons, nil, (, ), ドット対のドット, "cons cell"などは、
数と四則演算のように、基本的でかつ身近なもので、
carが「フィボナッチ数列を計算する関数」の名前になるなんて事はありえない、
それほどLispとLisperにとって"list"は身近なもんなんだ、ということ。
500500!:2001/07/27(金) 17:19
Haskellスレが立ってますね。
関数型プログラミング言語Haskell
http://piza2.2ch.net/test/read.cgi?bbs=tech&key=996131288
501デフォルトの名無しさん:2001/07/27(金) 23:53
schemeとかって関数の引数の評価順序って決まってるんですか?
(define (func a b) (cons a b))
(define x 1)

(func x (begin (set! x 2) x))
=>(1 . 2)
502デフォルトの名無しさん:2001/07/28(土) 00:02
あとこんなのとか。
(let ((test 0))
 (define (local-func) (set! test (+ test 1)))
 (func test (local-func))
)
一時変数用意した方がいいですか?
503無能な姦理人@Shiri-Q:2001/07/28(土) 00:03
□□□□■□□□□□■□□□□□□□□□□□□□□□□□□□□□
□□□■■□□□□□■□□□□□□□■■■■■■■■■■■■□□
□□■■□□□□□■■■■■■□□□□□□□□□□□□□■■□□
□■■□□■□□□■□□□□■□□□□□□□□□□□□■■□□□
□□■□■■□□■■■□□■■□□□□□□□□□□□■■□□□□
□□□■■□□■■□■■■■□□□□□□□□□□□■■□□□□□
□□■■□□□□□□□■■□□□□□□□□□□□■■□□□□□□
□□■□□□■□□□■■■■□□□□□□□□□□■□□□□□□□
□■■■■■■□□■■□□■■□□□□□□□□□■□□□□□□□
□□□□■□□□■■□□□□■■□□□□□□□□■□□□□□□□
□□■□■□■□□□□■■□□□□□□□□□□□■□□□□□□□
□□■□■□■□□□□□■■□□□□□□□□□□■□□□□□□□
□■■□■□■□□□□□□□□□□□□□□□□□■□□□□□□□
□■□□■□□□□■■■□□□□□□□□□□□□■□□□□□□□
□□□□■□□□□□□■■■□□□□□□□□□□■□□□□□□□
□□□□■□□□□□□□□■■□□□□□□■■■■□□□□□□□





続きはコチラです
http://www.geocities.com/entry_k/main/main01.html
504デフォルトの名無しさん:2001/07/28(土) 16:40
>>501
R5RSの「4.1.3 プロシージャ呼び出し」に、
「評価の順序は規定されていない」と書いてある。
505デフォルトの名無しさん:2001/07/28(土) 20:24
>>504
こういうコードってうっかり書いてしまいそうになりませんか?
lispだと関数の引数に関数呼出しを続けて書くケースが多いのも
関連してると思いますが、結構気を付けていても、
知らず知らずの内に・・って場合が結構ありそう。
506無名λ式:2001/07/28(土) 23:01
>>505
私は、引数の評価順序が決まっている言語でも、
引数の評価順序に依存しないprogram書く習慣です。
別人(後日の自分も含む)が見た時も理解しやすいよん。

Lispだからといって、返値使いまくるprogramも嫌いだな。
507デフォルトの名無しさん:2001/07/28(土) 23:11
>>505
(func a (begin (set! a (+ a 1)) a))
の場合は、
(let* ((t1 a) (t2 (begin (set! a (+ a 1)) a)))
 (func t1 tt2))
という風に一時変数を挟めば評価順序を自分で制御できます。
508507:2001/07/28(土) 23:15
でも、評価順序の制御のためだけに、わざわざ一時変数を手書きで
挟むのも馬鹿らしいので、左から右(あるいは右から左)へ
評価される様に、let*やletrecを使ったマクロを定義して形式化
するのがいいかもしれません。

;左から右への評価順序を強制するマクロ。
(define-macro (ltor-args func . args)
 (let ((tmp (map (lambda (x) (gensym)) args)))
  `(let* ,(map (lambda (x y) (list x y)) tmp args)
   (,func ,@tmp) )))
509507:2001/07/28(土) 23:18
>>508のマクロの使い方
(ltor-args func a (begin (set! a (+ a 1)) a))
これは
(let* ((G10 a) (G11 (begin (set! a (+ a 1)) a)))
(func G10 G11))
という風に展開される。
510507:2001/07/28(土) 23:22
;ついでに、右から左への評価順序を強制するマクロ。(reverseしてるだけ)
(define-macro (rtol-args func . args)
 (let ((tmp (map (lambda (x) (gensym)) args)))
  `(let* ,(map (lambda (x y) (list x y)) (reverse tmp) (reverse args))
   (,func ,@tmp) )))
511507:2001/07/28(土) 23:30
>>506
その習慣が一番良いでしょうね。

例えばC言語にトランスレートされたりする状況を考えると、
>>501の様なコードを変換するとそのまま不具合まで継承される恐れがある。
(C言語も引数の評価順序は定められていないので)
これは賢いトランスレータを使ったとしても同じだと思います。
512無名λ式:2001/07/29(日) 00:27
>>511
Schemeの設計された年代を考えると、
並列化scheme方言の事まで視野に入れたと考えたとか、
研究テーマとしてcompilerのoptimizeを追求したかったという事も考えられるけど、
SICPなんか見るとやっぱりWhat you see is What the program meansって、
考えがあると思います。暗黙の評価順序はそういう考えに反するのでしょう。

今時、引数の評価順序が決まっている言語、(゚Д゚)ハァ?とさえ思ってしまう。

ltor-argsはその点明示的でいいね。マクロとS式のメタプログラミング炸裂だし。
513デフォルトの名無しさん:2001/07/29(日) 06:16
501です。
>>504 >>506 >>507
ありがとうございます。大変参考になりました。
なんか今までbeginのノリで書いてた様な気がします。(やべー
なんていうか、scheme(っていうかlispですか?)のマクロって凄いですね。
他の言語ではずっと悩みそうな問題が一発で解決したような気がします。
(ltor-argsありがたく使わせてもらいます。)
こういうのメタプログラミングっていうんですね。
514507:2001/07/29(日) 17:02
>>510
 (reverse (map (lambda (x y) (list x y)) tmp args))
にした方がスマートでした。(こっちはあんまり使わなさそうですが)

>>513
lispのマクロは既存の構文と同等に扱えるので作り甲斐があると思います。
515デフォルトの名無しさん:2001/07/30(月) 03:27
.NET対応のlispって無いの?
516デフォルトの名無しさん:2001/07/30(月) 04:22
うーむ、さっぱりわからん
517デフォルトの名無しさん:2001/07/30(月) 06:19
>515 ちょっと探してみたけど、ないみたい。
518デフォルトの名無しさん:2001/07/30(月) 12:27
Lisp で GUI なプログラミングはどうするんでしょう? STkですか?
Lisp でネットワークなプログラミングはどうするんでしょう? CL-HTTP あたりのソース読め?
519無名λ式:2001/07/30(月) 15:21
520デフォルトの名無しさん:2001/07/30(月) 23:26
>>515
これは?
.NET対応Lispコンパイラ
http://www.atmarkit.co.jp/fdotnet/special/dotnet_sdk_part2/dotnetsdk05.html
現物触わった事ありませんが。
521デフォルトの名無しさん:2001/07/31(火) 13:47
Side effect
の日本語訳が
副作用
になっていますが、「クスリの副作用」など、あまり良いイメージがありません。
そこで、
「2次効果」
と改訳したいと思いますが?
522俺様訳:2001/07/31(火) 14:15
「If evaluation applies to a list that is inside another list, the outer list may use the value returned by the first evaluation as information when the outer list is evaluated. 」

女の子の服を脱がすときに、Lisp はまず、一番肌に近いブラジャーを脱がします。
つぎに、その外側につけてるシャツを脱がします。
最後に、一番外側に着ているカーディガンを脱がします。

これが Lisp のやり方です。
523デフォルトの名無しさん:2001/07/31(火) 17:17
>>521
side effectに言及したがる人は、それを悪役にしたがる人で
ある場合はほとんどですから、あまり良いイメージのない「副
作用」で十分なのでせう。
524デフォルトの名無しさん:2001/07/31(火) 22:00
え!! >522
525デフォルトの名無しさん:2001/07/31(火) 22:19
>>522

やはり Lisp ってマニアックですね。
526デフォルトの名無しさん:2001/07/31(火) 22:24
>>522
ちょっとまって、
(カーディガン (シャツ (ブラジャー 女の子)))
なの?
527デフォルトの名無しさん:2001/07/31(火) 23:54
defmacroとdefine-macroってどう違うんですか?
528デフォルトの名無しさん:2001/08/01(水) 00:27
>>527
defmacroはcommon-lisp流の書式で、
define-macroはscheme流の書式。
common-lisp: (defmacro name args body)
scheme: (define-macro (name args) body) または
    (define-macro name (lambda (args) body))
単に書式の違いなので、処理系によっては両方用意されてたり
自分で定義もできるけど。
defunとdefineの関係と似てる。
529デフォルトの名無しさん:2001/08/01(水) 00:42
あとdefine-macroと同じ書式の
(defmacro (name args) body)
という書き方や
(macro name (lambda args body))
というのもある。(古い処理系に多い)
530デフォルトの名無しさん:2001/08/01(水) 01:01
>>528解説どうもです。
なるほど・・・たとえばDrSchemeだとdefine-macroの書式が使えるみたいですね。
531デフォルトの名無しさん:2001/08/01(水) 01:44
SCMはえー
532デフォルトの名無しさん:2001/08/01(水) 01:50
>>530
DrSchemeって`(quasiquote)使えなくない?
同梱のMzSchemeは使えるのに。どういう仕様なんだょぅ〜
533デフォルトの名無しさん:2001/08/01(水) 02:16
>>532 それは多分languageっていう設定が、
Beginning Studentになってるからだと思う。
Full Schemeとかにしてみては?
534デフォルトの名無しさん:2001/08/01(水) 06:59
>>513
MIT-Schemeだと右から左に評価されるみたいです。
というわけで、完全に実装依存っぽいです。>評価順序
535無名λ式:2001/08/01(水) 14:56
>>534
> というわけで、完全に実装依存っぽいです。>評価順序

仕様としては「未定義」です。実装ごとに違って不思議はないです。
それどころかversionごと、compile毎にかわって良い。> 「というわけで」
536デフォルトの名無しさん:2001/08/01(水) 21:55
>>533
あ、やっぱり設定の問題ですか。
537デフォルトの名無しさん:2001/08/02(木) 00:11
参考までにdefine-macroで定義したdefmacro
(define-macro (defmacro name args . body)
  `(define-macro ,(cons name args) ,@body) )
または
(define-macro defmacro (lambda (name args . body)
  `(define-macro ,name (lambda ,args ,@body) ))
機能的にはCommonLispのやつには及ばないだろうけど
538デフォルトの名無しさん:2001/08/02(木) 00:14
上のdefmacroで定義したdefun
(defmacro defun (name args . body)
  `(define ,name (lambda ,args ,@body)) )
539デフォルトの名無しさん:2001/08/02(木) 01:17
evalマンセー
540デフォルトの名無しさん:2001/08/02(木) 21:28
apropos
って、今辞書で調べたら
アプロポウ
って発音するんですね。
いままで
アプロポス
って読んでました。
541デフォルトの名無しさん:2001/08/03(金) 01:27
ハァ?
542デフォルトの名無しさん:2001/08/03(金) 02:04
最近出たR5RS対応のSchemeの本、2冊本屋にあったんで初めて読んで見たけど、
define-macro/defmacroとかのlisp形式マクロの説明がまるっきり省かれてた。
(まるで初めから存在しなかったかの様で、ちょっと悲しかった。)
入門書としてはdefine-syntaxとかsyntax-caseは仕様的には綺麗かもしれないけど、
いきなり載せても直感的には判りにくいから、標準じゃないにしても、
まずお手軽で実装も簡単なlisp形式マクロについて説明して、それの問題指摘と
define-syntaxに至った経緯とかを解説して欲しかった気がする。
ここに書いてもしょうがないけど。
あと、evalや環境辺りの説明はやっぱり弱かった。
(規格書以上の事はやっぱり書かれていない。)
543デフォルトの名無しさん:2001/08/03(金) 22:07
SLIBの解説でdefmacroの説明はあるよ(日本人が書いた方の本)
544デフォルトの名無しさん:2001/08/04(土) 00:02
> 542 名前:デフォルトの名無しさん投稿日:2001/08/03(金) 02:04
…中略…
> define-macro/defmacroとかのlisp形式マクロの説明がまるっきり省かれてた。
> (まるで初めから存在しなかったかの様で、ちょっと悲しかった。)
> 入門書としてはdefine-syntaxとかsyntax-caseは仕様的には綺麗かもしれないけど、
> いきなり載せても直感的には判りにくいから、標準じゃないにしても、

「直感的には判りにくい」と思うのはdefmacroが脳味噌にしみついてるからじゃ
ないの。入門者から見たらhygienic syntaxのほうがずっと直感的だと思うぞ。

> まずお手軽で実装も簡単なlisp形式マクロについて説明して、それの問題指摘と
> define-syntaxに至った経緯とかを解説して欲しかった気がする。

こっちはまぁおっしゃるとおり。
545デフォルトの名無しさん:2001/08/04(土) 05:39
>>544
>defmacroが脳味噌にしみついてる
実はそうです(w
結局自分にしてもsyntax-rule/syntax-caseを日本語で解説してる本
という事で非常に価値がありました。
(あの辺、R5RS規格書だけ見てもさっぱりわからないと思う)
546デフォルトの名無しさん:2001/08/04(土) 06:51
久々にネタ提供
いちいちrequire指定して外部ファイルを読みこませるのが
馬鹿らしくなったのでこういうの作ってみました。
外部ファイルを遅延ロードさせる関数です。
(関数が呼び出された時点でロードする。)

(define (ondemand fn sym-list)
  (define (regist s)
    (eval `(define-macro (,s . x)
             (if (require ',fn)
                 (cons ,s x)
                 (error "ondemand load failure" ',fn) ))
          (interaction-environment) ))
  (if (symbol? sym-list)
      (regist sym-list)
      (for-each regist sym-list) ))
547デフォルトの名無しさん:2001/08/04(土) 06:55
補足
・requireがマクロ→関数の上書きをしてくれないと機能しない。
・requireはloadでも代用できます。
・requireは 成功時#t 失敗時#f を返す実装であること。
これはロード中にエラーが発生した場合の対処。無くてもいい。
(requireでロードされるファイルに同名の関数が存在しないと無限ループになる。)

使い方
初期化ファイルなどに↓を置いておく
(ondemand 'trnscrpt '(transcript-on transcript-off))

こうすると、初期化ファイルが読まれた時点で仮のtranscript-on transcript-off
が定義される。
(transcript-on "log")
などとして関数を呼び出すと、そのときにtrnscrpt.scmを読みに行き、
transcript-on transcript-offが本来の関数にすげ変わり、その関数を再評価する。
548デフォルトの名無しさん:2001/08/04(土) 06:56
これでインタプリタの起動が数割程速くなりました。

問題点は、処理系依存な部分がありそうなんでどの環境でもそのまま動くとは限らない。
特に、ondemandで登録した関数は最初マクロとして定義されるので、
applyで呼び出されるとまずいかもしれない。(うちの環境では大丈夫だけど)
549デフォルトの名無しさん:2001/08/04(土) 07:05
あとclosureじゃないから、関数引数経由で評価される場合も
まずいかもしれない。
((lambda (p) (p "log") ) transcript-on)
とした場合。
550デフォルトの名無しさん:2001/08/04(土) 07:40
良く考えたら、普通の関数に対してはマクロ展開する必要は無いから、
仮関数を普通の関数にして、その中でapplyすれば解決する。
(define (ondemand-func fn sym-list)
  (define (regist s)
    (eval `(define (,s . x)
             (if (require ',fn)
                 (apply ,s x)
                 (error "ondemand load failure" ',fn) ))
          (interaction-environment) ))
  (if (symbol? sym-list)
      (regist sym-list)
      (for-each regist sym-list) ))

このondemand-funcを併用すれば、>>548-549で言われた問題が解決する。
(マクロの遅延ロードに対しては>>546を使う。)
551デフォルトの名無しさん:2001/08/04(土) 11:54
自己書き換えだね>550
552デフォルトの名無しさん:2001/08/04(土) 12:09
そう思う>551
553デフォルトの名無しさん:2001/08/05(日) 01:47
>>551
evalって自己書き換え保証してるの?
554デフォルトの名無しさん:2001/08/05(日) 06:58
>>553
MzSchemeとDrSchemeでは動きました。(loadに変更した)
仕様書には明確に書かれてないみたいですが、自己書き換えで
現在の継続が失われる様な処理系は多分ないと思います。
555デフォルトの名無しさん:2001/08/05(日) 07:03
それに自己書き換えと言ってもこの場合、
require(またはload)で新しくclosureを作成し、
それをbindし直すので。
仮関数のclosureの継続には影響されない筈。
(少なくともrequireからの戻り、apply以降の継続は存在してる)
556デフォルトの名無しさん:2001/08/05(日) 07:18
本当の意味での書き換えは、既存のオリジナルコードを
何らかの手段で取り出して直接加工した場合。
それで自己書き換えする場合は、よほど注意深くやらないと
おかしな事になります。(相互書き換えならまだ容易ですが)
557デフォルトの名無しさん:2001/08/05(日) 11:07
defmacroで作ったsyntax-caseとかって無いですか?
(CommonLispからでも使える様なやつ。)
なんか大袈裟なコードのしか見かけないんで。
558デフォルトの名無しさん:2001/08/05(日) 20:29
dfmacroによるdefine-syntax(syntax-rule)の実装で、
mbeというのがある様です。>557
559デフォルトの名無しさん:2001/08/05(日) 20:34
これです。
Scheme Macros for Common Lisp
http://www.cs.rice.edu/~dorai/mbe/mbe-lsp.html
でも説明を見る限り、hygienicの対応が不完全な様です。
560デフォルトの名無しさん:2001/08/06(月) 04:52
>>559
ありがとう
561デフォルトの名無しさん:2001/08/06(月) 05:49
SCMのSLIBはdefmacro、STkはdefine-macroで作られてるからそれ移植するか、
pseudo-schemeとか使って適当にscheme->commonlispすればいいんじゃないかと思う。
562デフォルトの名無しさん:2001/08/06(月) 20:23
Lisp/Scheme でソケットなネットワークプログラミングな解説を
しているサイト、書籍ってありませんか?

あとはどの処理系ならできるとか。
563名無し:2001/08/06(月) 20:49
Scheme について質問。
というかだれかお助けを。

問題で以下のようなものをだされました。

リストを集合としたとき、その部分集合全体の集合を表すリストを
かえす手続きを作成せよ。

どなたかおねがいです。
564562:2001/08/06(月) 21:04
MIT Scheme の Reference に 15.8 TCP Sockets というのが
ありましたね。

本当は UDP がしたいんだけどな。
565563:2001/08/06(月) 21:40
全く同じなのですが組み合わせの問題です。
すべての組み合わせを返すものをつくれということです。
たのんます。
566無名λ式:2001/08/06(月) 23:01
>>563
再帰で考えろ。以上。
567デフォルトの名無しさん:2001/08/06(月) 23:48
>>565
ちょっと前に作ったやつ
(define (ex efrom eto er)
  (let G45 ((G41 efrom) (G42 eto) (G43 er) (G44 '()))
    (let G47 ((G46 G41))
      (cond
        ((<= G46 G42)
          (cond
            ((< 0 G43)
              (if (not (memv G46 G44))
                (let ((G48 (G45 G41 G42 (- G43 1) (cons G46 G44))))
                  (if (and (pair? G48) (pair? (car G48)))
                    (append G48 (G47 (+ G46 1)))
                    (cons G48 (G47 (+ G46 1)))))
                (G47 (+ G46 1))))
            (else (reverse G44))))
        (else '())))))

0〜3(4桁)までの組み合わせ全部
>(ex 0 3 4)
=>((0 1 2 3) (0 1 3 2) (0 2 1 3) (0 2 3 1) (0 3 1 2) (0 3 2 1) (1 0 2 3) (1 0 3 2)
(1 2 0 3) (1 2 3 0) (1 3 0 2) (1 3 2 0) (2 0 1 3) (2 0 3 1) (2 1 0 3) (2 1 3 0)
(2 3 0 1) (2 3 1 0) (3 0 1 2) (3 0 2 1) (3 1 0 2) (3 1 2 0) (3 2 0 1) (3 2 1 0))
568デフォルトの名無しさん:2001/08/07(火) 22:26
autoload>546
569デフォルトの名無しさん:2001/08/07(火) 22:47
>>568
schemeには無いよ
つーかCommonLispにも無いけど
emacs?
570無名λ式:2001/08/07(火) 23:29
librepにもautoloadありまっせー。sawfishとかで使っているぅ。
571デフォルトの名無しさん:2001/08/08(水) 00:20
面白そうなんでlibrep落としてきた。
sawfishも面白そうだけど自分は普段windows環境なので
使えないのだった。cygwinでなんとかならないかな
とりあえずlibrepだけでも動けばいいけど
572デフォルトの名無しさん:2001/08/08(水) 00:28
>>546-550
なにげにスゲー便利だった。>関数呼出し一発ロード
57318:2001/08/08(水) 00:53
日本語のページが見つかったから一応貼っておく
Sawfish JP
http://sawfish.gnome.gr.jp/index-ja.html
574デフォルトの名無しさん:2001/08/08(水) 02:04
(lambda (x) (f x)) - > f
((lambda () x)) - > x
((lambda (x) (f x)) y) - > (f y)
みたいに、式を単純化するプログラムってありませんか?
575デフォルトの名無しさん:2001/08/08(水) 04:45
それぐらい自分でなんとか作れない?>574
576デフォルトの名無しさん:2001/08/08(水) 12:23
>>567
それは順列ではないか?

>>563, >>565
SICPのExercise 2.32より(一部変更)

(define (subsets s)
(if (null? s) (list '())
(let ((rest (subsets (cdr s))))
(append rest (map (lambda (x) (cons (car s) x)) rest)))))

Exerciseでは、(lambda (x) (cons (car s) x)) が <??>になっている。
実行例
(subsets '(a b c))
(() (c) (b) (b c) (a) (a c) (a b) (a b c))
577しおり:2001/08/08(水) 20:30
(push-mark) ;ここまで読んだよ
578デフォルトの名無しさん:2001/08/09(木) 04:18
>>574
そういうのはコンパイラとかのソースに含まれてる
と思うんで、そういうコード探してみては?

汚いけど一番最初のやつだけ
(lambda->nop '(lambda (x y z ...) (f x y z ...))) => f
(lambda->nop '(lambda () (f))) => f

(define (lambda->nop x)
  (and (pair? x)
       (eq? (car x) 'lambda)
       (pair? (cdr x))
       (pair? (cddr x))
       (null? (cdddr x))
       (pair? (caddr x))
       (symbol? (caaddr x))         ; (f ...)の形式
       (equal? (cadr x) (cdaddr x)) ; 引数の比較
       (caaddr x) )) ;fを返す
579デフォルトの名無しさん:2001/08/09(木) 22:07
パターンマッチさせた方が良いと思われ
580デフォルトの名無しさん:2001/08/09(木) 22:40
581デフォルトの名無しさん:2001/08/10(金) 00:30
http://www.gnu.org/manual/emacs-lisp-intro/html_mono/emacs-lisp-intro.html

↑このマニュアルを自分なりに改変して再配布しようと思ってますが、GPLなので問題無いですよね?
582デフォルトの名無しさん:2001/08/10(金) 00:36
オリジナルの入手先をちゃんと貼っておけば問題無いと思います。>581
583デフォルトの名無しさん:2001/08/10(金) 02:33
The Sugar Homepage
http://sugar.mini.dhs.org/
584デフォルトの名無しさん:2001/08/10(金) 02:53
585デフォルトの名無しさん:2001/08/10(金) 19:13
昨々日The Little Schemerを購入したんだけど、
なにげにスゲー面白いね。
なぜ翻訳が出ないのかしら。
Scheme入門というだけでなく、再帰処理入門としてもステキな出来だと思うけど。
586名無しさん:2001/08/10(金) 19:20
「Scheme手習い」(啓学出版)で訳が出てた奴?
つーかLisperでなくてもLispの本は参考になるから
いいぞーって言いたいトコ。
587デフォルトの名無しさん:2001/08/10(金) 21:22
しつもんです。
(define test (let ((i 0)) (lambda () (set! i (+ i 1)) i)))
testは初期値0で、評価するたんびに+1された値を吐き出します。
(test) => 初回は1
(test) => 2
(test) => 3
んで、
ある関数に引数を多く渡した場合、半端な引数は
評価される事が保証されてるんでしょうか?
(話を簡単にするために、引数の評価順序は左から右という事にしておいてください)
((lambda (x y) (+ x y)) (test) (test) (test) (test))
これを評価した場合、
以降の
(test)
で3が返るのか、5が返るのか、引数が多いとエラーになるのか、
それとも決まってないのかが知りたいです。
ちなみに自分の所では3が返りました。
588デフォルトの名無しさん:2001/08/10(金) 21:25
間違えました。
こうすると、
(define test (let ((i 0)) (lambda () (set! i (+ i 1)) i)))
((lambda (x y) (+ x y)) (test) (test) (test) (test))
=>3
(test) =>5
自分の所では5が返ります。
589デフォルトの名無しさん:2001/08/10(金) 21:26
つまり、半端な引数もちゃんと評価されるのかどうかが知りたいんです。
590デフォルトの名無しさん:2001/08/10(金) 23:28
エラーなんじゃ??
591デフォルトの名無しさん:2001/08/11(土) 01:02
and式中の各々の評価結果を次の式に使いたい場合、
いちいちletで一時的なバインド作成するのが面倒なので
こういうの作ってみました。なかなか便利だったので公開します。

(define-macro (letand meta . expr)
  (let loop ((x expr))
    (if (pair? x)
        (if (pair? (cdr x))
            `(let ((,meta ,(car x)))
               (and ,meta ,(loop (cdr x))))
             (car x) )
        #t )))
592デフォルトの名無しさん:2001/08/11(土) 01:03
書式 (letand <一時変数として使うメタシンボル> [シーケンス])

メタシンボルを参照すると、直前の式の評価結果を返します。
(letand tmp 1 (+ tmp 2) 3 (+ tmp 4))
=>7
このマクロを展開するとこうなります。
(let ((tmp 1)) (and tmp (let ((tmp (+ tmp 2))) (and tmp (let ((tmp 3)) (and tmp (+ tmp 4)))))))
(この場合は全部定数の論理式なので、最適化したらただの7になりますが)
593デフォルトの名無しさん:2001/08/11(土) 01:38
ちなみに
(letand tmp)
=>#t
これはandと同じ仕様。
letorは意味が無いのでありません。(直前の式の評価結果が全部#f)
同様のアイデアを検索したらLAND*というのが既にあるみたいですが、
letバインド風の余計な括弧が必要なので、
letandの方がスマートだと思います。
594デフォルトの名無しさん:2001/08/11(土) 02:40
XML and Scheme
http://www.lh.com/~oleg/ftp/Scheme/xml.html

XMLをS式で表現するSXML
(XMLドキュメントの抽象構文木Abstract Syntax Tree)
他にXPath->SXPath XSLT->SXSLTなど
595デフォルトの名無しさん:2001/08/11(土) 03:54
596デフォルトの名無しさん:2001/08/11(土) 12:01
>>593
>同様のアイデアを検索したらLAND*というのが既にあるみたいですが、

SRFI-2ね。
http://srfi.schemers.org/srfi-2/
597デフォルトの名無しさん:2001/08/12(日) 00:19
(define-macro (letif meta test true false)
`(let ((,meta ,test)) (if ,meta ,true ,false)))
598デフォルトの名無しさん:2001/08/12(日) 02:12
LISPでかかれたおもろいプログラムってある?
599デフォルトの名無しさん:2001/08/12(日) 06:34
面白いかどうか知らないけど、
html2lisp
http://www.fides.dti.ne.jp/~liki/lisp/lisp2html.html
(みた感じ、なんか実装が適当っぽいですが。)
とか。

(html ()
(body ((bgcolor "red") (link #aabbcc))
ああああ
)
)
↓(ちゃんと表示されるかな)
<HTML>
<BODY BGCOLOR="RED" LINK=#AABBCC>
あああ
</BODY>
</HTML>
ドキュメントをS式で書いとけば、後で実行できたりして面白いかも。
600デフォルトの名無しさん:2001/08/12(日) 06:36
しまったインデントが
(html ()
  (body ((bgcolor "red") (link #aabbcc))
       ああああ
  )
)


<HTML>
  <BODY BGCOLOR="RED" LINK=#AABBCC>
  あああ
  </BODY>
</HTML>
601デフォルトの名無しさん:2001/08/12(日) 15:30
602デフォルトの名無しさん:2001/08/14(火) 07:12
簡単なパターンマッチの例です。
(match メタシンボルのリスト パターン テストする式)
全てのメタシンボルが一致したら、メタシンボルをマッチした物に
置き換えたリストを返す。
1つでも一致しなかったら#fを返す。

(define (match meta-list ptn tst)
  (define (list-tail x k)
    (if (zero? k) x (list-tail (cdr x) (- k 1))))
  (define (memq-pos obj l)
    (let loop ((x l) (c 0))
      (and (pair? x)
           (if (eq? obj (car x))
               c
               (loop (cdr x) (+ 1 c)) ))))
  (let ((r (map (lambda (x) x) meta-list)))
    (define (match? x y)
      (cond
        ((pair? x)
          (and (pair? y)
            (match? (car x) (car y))
            (match? (cdr x) (cdr y)) ))
        ((string? x)
          (and (string? y) (string=? x y)))
        ((and (symbol? x) (memq x meta-list))
          (set-car! (list-tail r (memq-pos x meta-list)) y)
          #t )
        (else (eqv? x y)) ))
    (and (match? ptn tst) r) ))
603デフォルトの名無しさん:2001/08/14(火) 07:15
テスト
(match '(何か) '((lambda () 何か)) '((lambda () (f x))))
=>((f x))

(match '(何か) '((lambda () 何か)) '((lambda () (f x) (g y))))
=>#f

(match '(何か) '((lambda () . 何か)) '((lambda () (f x) (g y))))
=>(((f x) (g y)))

(match '(λ引数 関数 関数引数) '((lambda λ引数 (関数 . 関数引数)))
'((lambda (a b c) (f x y z))))
=>((a b c) f (x y z))
604デフォルトの名無しさん:2001/08/14(火) 07:34
; --- A Pure Lisp Interpreter in Lisp ---
(defun plisp ()
(defun pl-evalquote (func args env) (pl-apply func args nil))
(defun pl-apply (func args env)
(cond ((atom func) (cond ((eq func 'car) (car (car args))) ((eq func 'cdr) (cdr (car args)))
((eq func 'cons) (cons (car args) (car (cdr args)))) ((eq func 'atom) (atom (car args)))
((eq func 'eq) (eq (car args) (car (cdr args)))) ((eq func 'return) (car args))
((eq func 'exit) (bye))
(t (pl-apply (pl-eval func args) args env)))) ((eq (car func) 'lambda)
(pl-eval (car (cdr (cdr func))) (pl-pairlis (car (cdr func)) args env)))
((eq (car func) 'label) (pl-apply (car (cdr (cdr func))) args (cons (cons (car (cdr func)) (car (cdr (cdr func)))) env)))))
(defun pl-eval (e env) (cond ((atom e) (cond ((eq e nil) nil)
((eq e t) t) (t (cdr (pl-assoc e env)))))
((atom (car e)) (cond ((eq (car e) 'quote) (car (cdr e)))
((eq (car e) 'cond) (pl-evcon (cdr e) env)) ((eq (car e) nil) (princ "Undefined Func.")
(terpri) (bye)) (t (pl-apply (car e) (pl-evlis (cdr e) env) env)))) (t (pl-apply (car e) (pl-evlis (cdr e) env) env))))
(defun pl-evcon (e env) (cond ((pl-eval (car (car e)) env) (pl-eval (car (cdr (car e))) env))(t (pl-evcon (cdr e) env))))
(defun pl-evlis (args env) (cond ((eq args nil) nil) (t (cons (pl-eval (car args) env) (pl-evlis (cdr args) env)))))
(defun pl-pairlis (x y env) (cond ((eq x nil) env) (t (cons (cons (car x) (car y)) (pl-pairlis (cdr x) (cdr y) env)))))
(defun pl-assoc (x env) (cond ((equal env nil) (princ "Undefined Func.") (terpri) (bye))
((equal (car (car env)) x) (car env)) (t (pl-assoc x (cdr env)))))
(princ "--- A Pure Lisp Interpreter in Lisp ---) (terpri) (prog (env) (setq env nil)
(loop (terpri) (princ "=>") (princ (pl-eval (read) env)))))
605デフォルトの名無しさん:2001/08/14(火) 07:35
LISPでLISPインタープリタを記述すると上の様になる…
(動作はGCLで確認済み)
606デフォルトの名無しさん:2001/08/15(水) 02:59
数学板で
http://cheese.2ch.net/test/read.cgi?bbs=math&key=997418959&st=1&to=1&nofirst=true
「2の50乗を計算するには?」

という質問が出ていたので、Meadow で

(expt 2 50)
C-x C-e
とやったら、値がでかすぎたのか、
0
と表示されてしまいました。

どうしたらいいのでしょうか?
607デフォルトの名無しさん:2001/08/15(水) 03:06
xyzzy でやったら出来た。xyzzy 最高!

(expt 2 50)
1125899906842624
608デフォルトの名無しさん:2001/08/15(水) 03:07
LISP でBignumを使って見るとか!
609デフォルトの名無しさん:2001/08/15(水) 03:14
http://www.gnu.org/manual/elisp-manual-20-2.5/html_node/elisp_21.html
いま、↑ここを調べたら、Lisp のInteger 型の取れる最大値は
134217727
らしいです。
なんでMeadowでできなくてxyzzyでできるんだろう?
610デフォルトの名無しさん:2001/08/15(水) 03:41
ttp://www1.mirai.ne.jp/~gyo/xyzzy/xyzzy-list.html

xyzzyの標準機能

オーバーフローしらずの電卓
多倍長整数が使える・・・・お小遣いが国家予算を超える人向き
611デフォルトの名無しさん:2001/08/15(水) 03:42
なんでもなにも、xyzzyはCommonLispだから>609
lisp汎用のbignumパッケージとか何処かに落ちてると思うから、
それ使ってみたら?
612デフォルトの名無しさん:2001/08/15(水) 04:03
>>602のメタシンボルをletバインドで参照できる様にした物。

(define (tagged-list? l tag)
  (and (pair? l) (eq? (car l) tag)))
(define (strip-quote expr)
  (if (tagged-list? expr 'quote) (cadr expr) expr ))

(define-macro (match-let meta ptn tst . body)
 (let ((r (gensym)) (m (strip-quote meta)))
  `(let ((,r (match ',m ,ptn ,tst)))
   (and ,r (let ,(map (lambda (x)
              (list x (list 'list-ref r (memq-pos x m) ))) m )
          ,@body )))))

(match-let '(expr) '((lambda () expr)) '((lambda () (f x))) expr)
=>(f x)

(match-let (rest) '((lambda () . rest)) '((lambda () (f x) (g y) (h z)))
 (case (length rest)
  ((0) '())
  ((1) (car rest))
  (else (cons 'begin rest)) ))
=>(begin (f x) (g x) (h z))
613デフォルトの名無しさん:2001/08/15(水) 04:12
×=>(begin (f x) (g x) (h z))
○=>(begin (f x) (g y) (h z))

(match-let (lp fp f) '(lambda lp (f . fp)) '(lambda (x y z) (func x y z))
 (if (equal? lp fp) f #f))
=>func

(match-let (lp fp f) '(lambda lp (f . fp)) '(lambda () (func))
 (if (equal? lp fp) f #f))
=>func
614デフォルトの名無しさん:2001/08/15(水) 18:54
604>
LISPでLISPインタープリタを組むのはウインストンの本にも載ってるや〜ね
615デフォルトの名無しさん:2001/08/15(水) 20:53
>>605
インデントしろよーとか言おうと思ったけど
長くなりそうだからやめた
LispOnLispはそのままだと遅いけど、
なんか速くする方法無いかな
616デフォルトの名無しさん:2001/08/16(木) 02:54
Lispで仕事したいのですが、どこ行けばいいですか?
617デフォルトの名無しさん:2001/08/16(木) 03:05
>>616
大学教授になりましょう
618デフォルトの名無しさん:2001/08/16(木) 05:07
製品にLISP使ってそうな会社に無理やり就職する。>616
619デフォルトの名無しさん:2001/08/16(木) 08:27
>>616 AutoCAD ってソフトに Lisp 付いてたよ
620デフォルトの名無しさん:2001/08/16(木) 13:48
Emacs Lisp のみを受注生産するフリ−ぷろぐらまぁになる

例)リージョン内の改行コードを削除するマクロ → 3万円
621デフォルトの名無しさん:2001/08/16(木) 19:54
図研のCAEソフトはマクロランゲージとしてschemeが組み込まれてる。
622デフォルトの名無しさん:2001/08/16(木) 20:59
>>615
Lisp in Lispを高速化するには、コンパイルするだけじゃ、ダメかな?
コモンだったら、最適化しない?
623デフォルトの名無しさん:2001/08/16(木) 23:18
日本Lispユーザ会
JLUG (Japan Lisp User Group)
http://jp.franz.com/jlug/index.html
624デフォルトの名無しさん:2001/08/17(金) 02:02
素のLISPとLispOnLispの間に生じた差分を取って
その差をマクロ化するとか。
こういうの自動化できればいいんだけど。
625デフォルトの名無しさん:2001/08/17(金) 02:11
だんだん Lisp の お勉強が おもしろく なって きて しまいました。
どう したら いいでしょうか?
626デフォルトの名無しさん:2001/08/17(金) 11:54
そのまま、立派なLisperになって大成してください。
627デフォルトの名無しさん:2001/08/17(金) 20:23
Lisp in Lisp で検索部分を線形探索じゃなくて、ハッシュにするというのはどう?
628デフォルトの名無しさん:2001/08/17(金) 20:26
LISPでハッシュするには、配列や拡張データ型が必要だけどね。
629デフォルトの名無しさん:2001/08/17(金) 21:59
>623

ttp://jp.franz.com/jlug/ja/resources/communities.html#community

しっかり、2chのLISPスレッドもリンクされているところが凄い。
にしても、ACLは高すぎ。欲しい〜。
630デフォルトの名無しさん:2001/08/17(金) 22:02
LISPでCGI&データベース連携
ttp://www.etl.go.jp/~matsui/eus/weld/weld.html
631デフォルトの名無しさん:2001/08/18(土) 03:31
>628
スレッド全部読んでないので違う話だったらすいません。
CommonLispなんかだとハッシュというオブジェクトがはじめからあります。
(make-hash-table) ってやれば生成できて、
gethash っていうアクセサ使えば簡単に使えます。
ちなみにハッシュ・キーの等価チェック用の述語もeq eql equal
(第2版からequalpも)から選べます。
632デフォルトの名無しさん:2001/08/18(土) 16:15
>>631
628です。不勉強で、すいません(藁)
いまだに、マッカーシーの原著論文+LISP1.5 Programmer's Manualだけで処理系を
実装してるもので(藁)
633デフォルトの名無しさん:2001/08/18(土) 16:19
ちなみに、私のいる、大学院では、いまだにLISP1.5 Programmer's Manualを
使って、LISPの処理系の実装を講義されている先生がいらっしゃりますです。
634デフォルトの名無しさん:2001/08/18(土) 16:26
www.civilized.comではLISP1.5をベースにしたLISP処理系をC言語で実装するテキスト
(勿論、ソースも附属)を配布してますぜ。
635デフォルトの名無しさん:2001/08/19(日) 07:59
JavaScript to Scheme translator
http://sourceforge.net/projects/js2scheme/
636デフォルトの名無しさん:2001/08/19(日) 08:46
>>633
もう図書館のこの本バラバラになりそうなんだよな。
コピーして持ってた方がいいかも。
637デフォルトの名無しさん:2001/08/19(日) 08:49
>>606
(expt 2.0 50)
1125899906842624.0
638デフォルトの名無しさん:2001/08/19(日) 19:51
>>612 のmatch-letを使った条件式の変形
(define (condition-optimize x)
  (or (match-let '(test e) '(if test e #f) x
        (list 'and test e) )
      (match-let '(test e) '(if test #t e) x
        (list 'or test e) )
      (match-let '(test t f) '(if (not test) t f) x
        (condition-optimize (list 'if test f t)) )
      ; ...
      x ))

(condition-optimize '(if (not a) b c))
=>(if a c b)
(condition-optimize '(if a b #f))
=>(and a b)
>(condition-optimize '(if a #t b))
=>(or a b)
(condition-optimize '(if (not a) #f b))
=>(and a b)
639デフォルトの名無しさん:2001/08/20(月) 02:44
>>637
2.0 にしたらオーバーフロー起こさずに答えが出ましたよ!!
Meadow でも!!!
理由はわからんがすごい!!!!
640デフォルトの名無しさん:2001/08/20(月) 03:03
>>639 emacs19 あたりから浮動小数点がついたからでは。
641デフォルトの名無しさん:2001/08/20(月) 03:55
>>636
まだ、MIT PressからLISP 1.5 Programmer's Manualは販売されてるから、
絶版になる前に買っとくのが正解かもよ。
642デフォルトの名無しさん:2001/08/20(月) 23:36
LISPで天下が取れますか?
643デフォルトの名無しさん:2001/08/20(月) 23:45
LISP1.5ってだいぶ前の仕様だと思うけど
いまさらでも読む価値ありますか?>641
644無名λ式:2001/08/21(火) 00:02
>>643
1.5の仕様はともかく、本の内容が面白いです。
"History of Lisp"なんかも面白い。
http://www-formal.stanford.edu/jmc/history/lisp/lisp.html
645デフォルトの名無しさん:2001/08/21(火) 02:17
644に禿げしく同意!
646デフォルトの名無しさん:2001/08/21(火) 02:19
>>643
LISP1.5は全てのLISPの基本となる、LISPの本質そのものともいえるもの。
そんな質問は愚問だと思う。
647デフォルトの名無しさん:2001/08/21(火) 03:52
1ヶ月前、OOP・デザパタ萌え〜な私

何気なく、SICPをチラッと見てみた

面白そう、「チョット」やってみるか

めっちゃ、面白いじゃん!lisp/scheme萌え〜

(゚д゚)ウマ-
648デフォルトの名無しさん:2001/08/21(火) 10:44
Lisp/Scheme系のプログラミングパラダイムに、「ストリーム(streams)」
というものがあって、

0.UNIXのファイル抽象とは無関係。:-P
1.状態の変化を変数への代入無しに表現する。
2.状態の時系列の変化を連続したデータのつながりとして表現する
3.遅延評価と高階関数によって実装する

というものらしいんですが、状態の変化を扱わざるを得ないGUIプログ
ラミングなどに応用できるものかどうか識者の見解をうかがいたいです。

読んだ本(SICP2nd)の例では bank-account の例が載ってましたが、口
座利用者の引出し額もストリームとして扱うことにしていて、そんなも
んどうやったら計算で得られるんじゃと頭を抱えてしまいました。
(洩れってアホですか?)
649無名λ式:2001/08/21(火) 11:02
Atomic transactionのintention list方式って、
「額」じゃなくて「操作」のlistだけど、bank-accountのstream方式みたいなもんじゃん。
;; commitが起きる度に短くなっていくけど。
650デフォルトの名無しさん:2001/08/21(火) 12:41
>>649
操作の待ち行列があればストリームと同じように扱えるからオッケーということですね
651無名λ式:2001/08/21(火) 13:00
そうだす。
>>648の2,3は「『状態の変化』自体を『時系列を意識して』扱いたい」ということなのだから。

>>648のGUI云々って事で言えば、GIMPのundoの実装を見るよし。
control panelなんかも複数回のapplyの任意の段階に戻りたい時は履歴持つ必要あるよね?

Command patternも眺めてみてね。
652デフォルトの名無しさん:2001/08/21(火) 13:38
Haskellの話しなんでsageるけど、
Fudgetって GUI frameworkは streamをつなぎまくって
GUI作ってたぞ。
653無名λ式:2001/08/21(火) 14:41
>>652
pure functionalで状態扱いたい時は、そう(モナド系)するしかないっすね。
654デフォルトの名無しさん:2001/08/21(火) 16:32
SCHEMEとCommon ユーザはどっちが多いかな
655デフォルトの名無しさん:2001/08/21(火) 16:44
>>651
あれ、でも操作の待ち行列って変数に値としてため込まないといけないような…。
いや、遅延評価でなんとかなる…?

ああ、分からなくなってきた。
656無名λ式:2001/08/21(火) 17:09
>>655
遅延評価云々は、未来の出し入れを無限リストで表現するからでしょ?
リストにpost-pendするんじゃなくて。

後はそんな難しい事は言ってないよん。
657デフォルトの名無しさん:2001/08/21(火) 23:52
すいません、いままで
lambda

ランバダ
って読んでました。なぜそこで踊るのかといつもふしぎに思ってました。
658デフォルトの名無しさん:2001/08/21(火) 23:57
>>657
よかったー自分だけじゃなかったんだあああ(w
659デフォルトの名無しさん:2001/08/22(水) 00:05
http://homepage2.nifty.com/galaxystar/yool.htm
誰かこれ↑使ってる人いる?

「YOOL for Windowsの紹介<概要>YOOL for WindowsはWindows95以降で動作するLISPインタプリタです。オブジェクト指向プログラミングやWindowsアプリケーション作成も可能です。
<特徴>
 ・LISP1.9とCommon LISPの中間のような仕様。・スタックが深いので10000回程度の再帰呼び出しも可能。
・小さなプログラムを実行するときは少ないメモリしか消費せず、大きなプログラムを  実行すると自動的に大量のメモリを確保する。
・オブジェクト指向プログラミングをサポート。仕様は独自です。 ・WindowsのGUIを使ったプログラムの作成可能。 ・最大10個までのウインドを制御可能。
・32bitアプリケーションなので比較的高速。・サンプルプログラムとして、次のようなものを添付しています。
デジタル回路シミュレータ  英文和訳プログラム  お絵描きプログラム  スタック型のインタプリタ  各種ベンチマークテスト」
660デフォルトの名無しさん:2001/08/22(水) 01:10
>>659
昔使ってたけど、ナンカなあ〜
661デフォルトの名無しさん:2001/08/22(水) 01:11
>>659
付録のプログラムは結構有益だったけど。
662デフォルトの名無しさん:2001/08/22(水) 02:17
>>659
>・スタックが深いので10000回程度の再帰呼び出しも可能。
「スタックが深い」ってどういう事だろう?
一回の関数呼出しに使うスタックサイズが小さいって事かな。
(スタックに使うメモリをヒープに置いてるとかなら、
そもそも制限は無い筈。)
使ったこと無いのでなんとも言えないです。
vectorにそれしか置いてないってのが不思議。
何か問題あるのかな>vector
663無名λ式:2001/08/22(水) 03:14
>>662
Interpreterをもっている処理系では(compilerがあっても)、
stackを自前でheap上に管理するのよん。
664デフォルトの名無しさん:2001/08/22(水) 12:57
LISPやってみたいのですが、開発環境が見つかりません。
フリーで手に入れられる開発環境はありませんか?

ちなみに一つだけ見つけてDLしたのですが、
使い方が良く分からなかったのです…
http://plaza10.mbn.or.jp/~lisp/
665デフォルトの名無しさん:2001/08/22(水) 13:44
>>664
とりあえず >>624 を見ようね。
666665:2001/08/22(水) 13:46
>>623 だった。鬱…。
667デフォルトの名無しさん:2001/08/22(水) 13:59
ひとつだけ質問。
Lisp開発環境なるものを2つ入手したけど、どちらも、
CUIコマンドのように一行ずつ入力していくタイプだった。
Lispって、そういう入力形式なものなの?
それとも、たまたまそうだっただけの話?
1行ずつの入力で不便はないの?
668デフォルトの名無しさん:2001/08/22(水) 14:34
>>667
不便。
でもファイルに書いて読み込むことも出来るはず。
669デフォルトの名無しさん:2001/08/22(水) 14:55
>>667 >>668
(load "nantoka.l")
とかって無かったっけ?

それか Emacs を使うとか
670デフォルトの名無しさん:2001/08/22(水) 17:59
user functionのない古いawkで書かれたLispをみたときは感動を通り越してあきれたYO
671667:2001/08/22(水) 20:10
ん、では、LISPの開発環境って、伝統的に1行ずつ入力していく
ということでよろしいわけですね。
672デフォルトの名無しさん:2001/08/22(水) 20:20
>>668 >>669 は読んでないの?
673デフォルトの名無しさん:2001/08/23(木) 00:48
Schemeのcond構文で => てのがあるけど、これを言語仕様に含めることに必然性は
あるのだろうか。特に便利というわけでもなく、かつ激しく美しくない気がするのだが。
674デフォルトの名無しさん:2001/08/23(木) 06:20
>>673
Schemeのcond-syntaxはlispでは昔からあったやつだから、
今更仕様を変えてしまうとlisperが混乱するってんで、
そのまま残してあるのでは?
=>はテスト結果を引数に、関数を呼び出すってので、多少は有用性があるし。
((assq obj alist) => cdr)
(連想リストでobjが見つかったら、それに関連付けされた値(cdr)を返す)
675デフォルトの名無しさん:2001/08/23(木) 07:46
>>672
読んだけど、明確には書いて無いじゃん。
”文から察する”のではなくて、はっきりした答えを望んでいたワケよ。
676デフォルトの名無しさん:2001/08/23(木) 08:15
伝統的に1行すつ入力していくということで良い、とも書いてないと思うが?

大体、はっきりした答なんてあるのかね。場合によりけり、では?
677デフォルトの名無しさん:2001/08/23(木) 21:27
>>675
伝統的って何よ
CUIの伝統?
GUIの伝統?
一行入力って事はBASIC?
678デフォルトの名無しさん:2001/08/23(木) 22:22
>>675
脳内までコンピューターになってるぞ。
679デフォルトの名無しさん:2001/08/24(金) 00:19
>>671
フリーで公開されてる処理系のほとんどは対話的な編集機能は
無いみたいです。(DrSchemeとか、IDEが載ってるやつもある。)
標準入力からのダム入力がほとんど。
ただし、そういう場合でもLISPで書かれたコード編集機能とかを提供
していたり、処理系とは別に、LISP用のエディタってのがあるので、
それを使うのが一般的なんでしょう。
LISP専用マシンや、商用のならIDEぐらいは用意してると思います。
680デフォルトの名無しさん:2001/08/24(金) 00:46
つーかemacsあるじゃん
681デフォルトの名無しさん:2001/08/24(金) 22:21
x-emacs
682デフォルトの名無しさん:2001/08/25(土) 05:05
CommonLisp を 6 割くらい実装しているっていう xyzzy もあるし
683デフォルトの名無しさん:01/08/26 12:41
開発/実行環境は、emacs配下で処理系動かしている人が多いんじゃないかな?
CMU Common Lispなんかは自前のeditor/開発環境が強力だったけど。

>>664はwindowsな人みたいだから、わしにはお勧めが出来ない。
http://www.cs.cmu.edu/afs/cs/project/ai-repository/ai/lang/lisp/impl/0.html
http://www.cs.cmu.edu/afs/cs/project/ai-repository/ai/lang/scheme/impl/0.html
http://SAL.KachinaTech.COM/F/1/
あたりから漁ってみては?
684デフォルトの名無しさん :01/08/26 13:34
>>674
そんな単純な理由じゃないよ。もしチャンスがあったら John R. Allen の
"ANATOMY OF LISP" を読んでみてください。きっと疑問に思っていることが
かなり解消されると思います。
685デフォルトの名無しさん:01/08/26 14:40
>>684
これ、結局後半部分の翻訳は出なかったね。
686デフォルトの名無しさん:01/08/26 14:57
翻訳って出たんだ。改めて読んでみたけど、理論と技術が絶妙なバランスで書か
れていて名著ですね。
687デフォルトの名無しさん:01/08/26 15:14
>>686
"Let's talk LISP" も名著では?
日本の出版社なら断るであろう絶妙な文章が最高だった.(藁
688デフォルトの名無しさん:01/08/26 15:22
>>686
大昔。東大後藤研HLISPの人達の翻訳。
日本コンピュータ協会からじゃなかったかな。白とオレンジの表紙。
前半の理論パートだけ翻訳された。

当時実装の情報飢餓だった学生の俺は欝…
689デフォルトの名無しさん:01/08/26 15:28
あ、もちろん、前半だけでもめちゃ面白かった。
690デフォルトの名無しさん:01/08/26 15:41
>>688
Lispの実装に興味がなければ前半で十分ですね。理論はこの本で、
実装は K-LISP で勉強させて貰いました。
691デフォルトの名無しさん:01/08/26 16:35
>>684
Anatomy of LISP は原著&訳書ともに、現在、入手困難だねえ。
神田の古本屋街でも売ってない。若い人は、なかなか読めるチャンスがないでしょ。
マッカーシーのLISP関係の論文を調べる方がよほど楽だもの。
692デフォルトの名無しさん:01/08/26 16:41
その昔、電総研で国産LISP処理系の実装をしてた人が、
LISPの本質を学ぶには、"LISP 1.5 Programmer's Manual"
で十分だって言ってるよ。その人は、>>633の大学教授。
693デフォルトの名無しさん:01/08/26 18:43 ID:N7ZU6aks
>>692
"LISP 1.5 Programmer's Manual" の Eval の定義のページは基本中の基本
ですね。その先に進むとすれば "Anatomy of LISP" なんですよ。
694639:01/08/26 18:48 ID:N7ZU6aks
「その先」と言っても深さじゃなく幅のことです。
695デフォルトの名無しさん:01/08/27 00:05 ID:M6E23zcw
nthcdr って方言によって実装がちがうんですね。

Emacs Lisp では
(nthcdr 2 "a" "b" "c" "d")
→("c" "d")
なのに、Common Lisp を実装しているという YOOL では

(nthcdr 2 "a" "b" "c" "d")
→("d")
になりました。
696デフォルトの名無しさん:01/08/27 00:07 ID:M6E23zcw
>>695 のS式間違えました。
(nthcdr 2 '(a b c d))
と読み替えてください。
697デフォルトの名無しさん:01/08/27 02:42 ID:HLWIQFE6
>>696
Common Lisp を実装しているという xyzzy では

(nthcdr 2 '(a b c d))
→(c d)

となりました。
698デフォルトの名無しさん:01/08/27 04:08 ID:YHyrpXK2
>>695
実装によって機能が異なる関数があっても,それを許容するのが Lisp の
基本的なスタンスです.インプリメンタの解釈が気に食わなければ,関数
を再定義するなり,計算形マクロを定義するなりして,自分の好みにする
ことが可能です.例えば,TAO/ELIS には,MacLisp および ZetaLisp の
互換パッケージがあって,ユーザが趣味(?)の応じて使えるようになって
いました.
# MacLisp は,Macintosh 向けの Lisp の処理系ではありません.(藁
699デフォルトの名無しさん:01/08/28 00:37 ID:w0po3FXw
>>684
>そんな単純な理由じゃないよ。
簡単に説明してもらえるとありがたいのですが・・
700デフォルトの名無しさん:01/08/28 22:35 ID:eihQBBgU
Common Lisp において、
(setf a '(1 2 3 4 5))
の状態で、list である a の個々の要素に対する操作、一例としては
(max 1 2 3 4 5)
を行う場合、一般的にはどのようにするのでしょうか。
今現在は
(eval (cons 'max a))
としているのですが、これが一般的な書き方なのかわからないのです。
ご教授宜しくお願い致します。
701デフォルトの名無しさん:01/08/28 23:21 ID:GcQivBcQ
>>693
なるほど。。。
"Anatomy of LISP"読んでみたいなあ〜。
702デフォルトの名無しさん:01/08/28 23:40 ID:VQ.Eh2.o
>>700
(apply #'max a)
703デフォルトの名無しさん:01/08/28 23:54 ID:UYkVndh6
Lisper が書いた本を読んだ。
文の内容まで Lisp 風に実装されていた。(汗

「ここではAという概念を説明する。しかし、その前に、Bという概念を説明しておいたほうが望ましいので、まずBを説明する」
「ここではBを説明するが、その前に、Cという概念が必要なので、まずCを説明する」
「Cを説明するがその前にDを...」
てな感じでいつまでたっても本文がでてこない。
いっぺん氏ねとオモタ。
704デフォルトの名無しさん:01/08/29 00:31 ID:5V.Ejvn.
Haskell風なら call-by-needで説明できるからいいよ!
705デフォルトの名無しさん:01/08/29 01:28 ID:GIhJkjc.
>>703
参考までに本の名前を教えてください。
706デフォルトの名無しさん:01/08/29 01:55 ID:GIhJkjc.
>>700
eval/applyを使いたくないなら、maxを2引数固定とみなして、
リストイテレータ(fold-leftとか)を使うとか。
(fold-left #'max (car a) (cdr a))
結局max内部でも同じ様な事してるわけだけど。
707700:01/08/29 14:35 ID:9ek6n1iU
>>706
現在の問題では 2 引数固定とみなすことはできないので残念ながら
適用できません。
そもそもイテレータという概念がどんなものか理解していないので
これから調べてきます。
ご教授ありがとうございました。

>>702
> (apply #'max a)
キレイさっぱり apply の存在を忘れていました。
ご教授ありがとうございました。

つい最近 Lisp でプログラムを書き始めたのでどうしようもないコー
ドを大量生産中です。
大量に変数を let してしまうし、ついつい副作用を目的とした
function ばかり書いてしまいますし。
速度を求めた場合はそっちの方がよいような気がするのですが、コードが
Lisp らしくなくて自分で泣けてばかりきます。
厨房な質問でスレを汚してしまいすみませんでした。
708デフォルトの名無しさん:01/08/29 22:52 ID:KTWH2gm.
schemeならともかく、普通のlispで副作用無しってのはきついんじゃない?>707
709デフォルトの名無しさん:01/08/30 00:03 ID:C3TsWUik
>>707
schemeでもLispでも副作用の使い方による。
良い使い方もあるし、悪い使い方もある。
710デフォルトの名無しさん:01/08/30 01:37 ID:ewrL03ng
>>707
変数に値を入れるのではなく,値に名前(変数名)を付けるという
考えに頭が切り替われば,副作用は自然に減ると思います.
711デフォルトの名無しさん:01/08/30 12:10 ID:OvgrHWKE
コンビネーターってなんですか
712デフォルトの名無しさん:01/08/30 13:55 ID:C3TsWUik
>>711
自由変数のないλ式の事。S, K, I, Yなどが有名です。
詳しくは関数型言語スレで。
713700:01/08/30 15:35 ID:FZu.V9eg
何度もお目汚ししてしまいすみません。
(apply #'max '(1 2 3 5 4))
はうまくいくのですが、
or が defmacro で定義されているため
(apply #'or '(nil nil t nil nil))
(apply 'or '(nil nil t nil nil))
がうまくいきません。
(eval (cons 'or '(nil nil t nil nil)))
で現在は評価しているのですが、'or 等の場合でも常套句がある
のでしょうか。ご教授宜しくお願い致します。

なんだか、Lisp を書いていても list がポインタの集合にしか
見えないっていう余計なワンクッションが頭の中で起こってしまっ
ています。
フィーリングで Lisp を書けるようになるのは遠そうです。

そらから、もし宜しければ、setf と setq の違いについても
ご教授お願いできないでしょうか。
どういう場合にどちらを使うべきなのかがわからず右往左往して
しまっています。
宜しお願い致します。
714デフォルトの名無しさん:01/08/30 22:38 ID:36uDa7mk
今日会社の上司に
「今、Lisp の勉強してるんですよ〜」
って逝ったら
「ほえ?リスピュってなに??」
って言われた。
りしゅぴゅって知名度低いって実感した。

ホントは50年の歴史があるんだけどね。
715デフォルトの名無しさん:01/08/30 23:40 ID:rGyCxIX.
>>713
CommonLisp第2版の本に、マクロはapplyできないと書いてある筈。
多分普通のifとかの構文も駄目だったと思う。
どうしてもapllyでやりたければ、自分でapplyのラッパーとか
を実装すれば良いんじゃない?
うまいやりかたは知りません。
orの様なマクロや構文であれば、引数をclosureのリストに、
orも相当する機能の関数に置換して、それをapplyする
my-applyマクロを作るとか。
716デフォルトの名無しさん:01/08/30 23:57 ID:rGyCxIX.
>>715
setqは単純変数代入文、setfは汎用代入文
普通に使う場合はなにも考えずにsetfで良いと思います。
(インタプリタ上でなんの最適化もせずに実行速度を上げたい
とかの場合以外)
こういう標準的な関数の機能については先程も出てきた、
CommonLisp第2版 著者 GUY L.STEELE JR.(共立出版)
ISBN4-320-02588-1
や、過去ログに載ってるような本を参照してください。
717716:01/08/30 23:58 ID:rGyCxIX.
>>715じゃなくて>>713
718716:01/08/31 00:07 ID:Cbba3liI
ここでCommonLispに近い仕様の、ISLISPというISO標準規格の
Lispのリファレンスがweb上で参照できます。(日本語)
ttp://www.ito.ecei.tohoku.ac.jp/~izumi/TISL/doc/ISLISP/index_j.html
トップ
ttp://www.ito.ecei.tohoku.ac.jp/~izumi/TISL/top_j.html
719デフォルトの名無しさん:01/08/31 00:26 ID:R3B1Jouc
orがなぜ関数ではなく macroになってるかも考えるべき>>713
多分、関数 or* とか作って applyするのがいいと思うが用途による。
で、 >>715 はなんか違う気がする。
720711:01/08/31 01:25 ID:qFL5sH4M
>>712
即答ありがとう。逝ってきます。
721デフォルトの名無しさん:01/08/31 01:46 ID:JrJLvbeM
>>719
shortcutする必要がなければ、ifで書いた関数でlistをfoldしてもいいしねー。
722デフォルトの名無しさん:01/08/31 01:49 ID:.j91wkso
>>713
CommonLispには、orの関数版という感じの
someというのがあるので、それで代用できると思います。
723715:01/08/31 01:54 ID:.j91wkso
>>713
逆に、andの関数版という感じのはeveryです。

>>719
自分でもややこしいこと書いてしまった感じがします。
724デフォルトの名無しさん:01/08/31 02:01 ID:.j91wkso
ちなみにsomoとeveryは述語を指定する必要があるんで、
普通のorやandとして振る舞わせる場合
(defun identity (x) x)
とでもして、
(some #'identity 〜)
(every #'identity 〜)
として使ってください。
(もっと適切な関数があるかもしれませんが。)
725デフォルトの名無しさん:01/08/31 02:23 ID:oLrxQ0UE
>>713
リストの中身を評価する必要がなければ、、
(find-if #'identity '(nil nil t nil nil)) や
(member-if #'identity '(nil nil t nil nil)) などで
代用できる。評価するのなら、evalでいいんじゃないかな。
726デフォルトの名無しさん:01/08/31 02:29 ID:oLrxQ0UE
>>724
identityは標準であるよ。
727713:01/08/31 15:59 ID:H3ikKes.
>>715 >>719 >>721 >>722 >>723 >>724 >>725 >>726
親切に回答してくださりありがとうございます。
リストの中身を評価する必要があるため、今回は
(some #'identity 〜)
でいこうかと思います。
ありがとうございました。

>>716
基本的なことにもかかわらずご返答してくださりありがとうございました。
KCL の実装上での CommonLisp についての解説がかかれた
「CommonLisp 入門」をようやく読める環境になったので、今後このような
質問はしないよう、基本をきちんと学ぼうと思います。

>>719
> orがなぜ関数ではなく macroになってるかも考えるべき>>713
実はまだ自分で defmacro でマクロを定義したことがないため macro の有用性
についてきちんと把握できていない状態です。
「CommonLisp 入門」を読んで勉強してきます。

皆様、ご返答ありがとうございました。
728デフォルトの名無しさん:01/09/01 01:54 ID:ctDE.PS.
LISPっていうと、コモンの話題ばかりになってしまう風潮が気に入らない。
コモンの話題しか話せない様なのは、真のLISPerじゃない!
コモンの様な軟派な亜流のLISPじゃなく、無駄な機能を省いた、美しいLISP言語
の真髄に関する話題を希望。
そもそも、コモンLISPだあ、オブジェクト指向だあって言ってる連中は、
LISPの処理系の内部の詳細を知って、自分で処理系を作る能力があるのだろうか。
真のLISPerなら、処理系を自分で実装してみるべき。
>>708
LISPで副作用のない、副作用のない関数型プログラミングができてこそ、
真のLISPer

パンティーはいたまま排便、好きな人
パンティーはいたまま排便、好きな人
パンティーはいたまま排便、好きな人
パンティーはいたまま排便、好きな人
パンティーはいたまま排便、好きな人
パンティーはいたまま排便、好きな人
パンティーはいたまま排便、好きな人
パンティーはいたまま排便、好きな人
パンティーはいたまま排便、好きな人
パンティーはいたまま排便、好きな人
パンティーはいたまま排便、好きな人
パンティーはいたまま排便、好きな人
パンティーはいたまま排便、好きな人
パンティーはいたまま排便、好きな人
パンティーはいたまま排便、好きな人
パンティーはいたまま排便、好きな人
パンティーはいたまま排便、好きな人
パンティーはいたまま排便、好きな人
パンティーはいたまま排便、好きな人
パンティーはいたまま排便、好きな人
パンティーはいたまま排便、好きな人
パンティーはいたまま排便、好きな人
パンティーはいたまま排便、好きな人
パンティーはいたまま排便、好きな人
パンティーはいたまま排便、好きな人
パンティーはいたまま排便、好きな人
パンティーはいたまま排便、好きな人
パンティーはいたまま排便、好きな人
730デフォルトの名無しさん:01/09/01 19:43 ID:Wnumu9r2
>>728
Scheme
731デフォルトの名無しさん:01/09/01 21:21 ID:loW1WFjk
えーなんでー。
歴史的には
Lisp → すきぃむ → こもんLisp
だから、顧問LIsp が最強なんでしょ?

すきぃむ って OO 対応してるの?
732デフォルトの名無しさん:01/09/01 23:01 ID:Hclu0oRE
Guile=Scheme
733デフォルトの名無しさん:01/09/01 23:22 ID:cxkeoCoY
>>731
Schemeは今現在も発展してるし、
OOも対応してる
734デフォルトの名無しさん:01/09/02 01:25 ID:.7XrLN8.
>>731
コモンが最強だというのは、コモン信奉者の妄想。
あんな言語仕様が水膨れしたものを平然と使う神経が理解しがたい。
731はLISPの何たるかを全く理解しないまま、世間のいうことをそのまま鵜呑みに
してるだけ。
735デフォルトの名無しさん:01/09/02 01:38 ID:.7XrLN8.
10年くらい前までは、LISPの処理系の実装に関する書籍が、洋書和書
を問わずに何冊か出てたけど、最近は全くないなあ。
今じゃあ、LISP言語自体の解説書も良書と呼べるものは、殆ど出て
ないし(SICP及びその訳書は別として)。
こんなんじゃ、真のLISPerは育たんよ。
736デフォルトの名無しさん:01/09/02 12:11 ID:/QCPLR4U
http://www.recruit.co.jp/cgi-bin/rperl5.pl/r-staffing/search/search.html?AREA=1

↑ここの
「プログラミングスキルをいかせるお仕事」
UNIX UNIX−C C++ VC++ COBOL
PL/1 VB Java JavaScript Linux
Oracle SQL Perl

Lisp は入ってないねぇ。
737デフォルトの名無しさん:01/09/02 13:13 ID:ulMTJ1N.
>733
OOも対応してるって、「規格で」ですか?
実装で対応してるっていうのはよく見かけるけど……。
738デフォルトの名無しさん:01/09/03 02:37 ID:LXi6Pi92
>>737
規格というか、「暗黙に」では?
メッセージパッシングやデータ主導とか。
マクロが構文として書けるので、OOの対応レベルやインタフェースを
自分で決定できる。既存のOOパッケージを使用するという方法が楽かも。
(ちなみにCommonLispのCLOSとかもマクロとして実装できる。)
速度が問題では無いときには、コアを小さくしておいて
他の構文やらは全部マクロで定義、とかはLISPではよくあります。
関数型として書けば別にOOは必要ないと思うけど。
739デフォルトの名無しさん:01/09/03 02:39 ID:LXi6Pi92
>>736
LISPコードをそのまま納品する仕事ってのは
確かに少ないかもね。
740デフォルトの名無しさん:01/09/03 05:19 ID:hl5nRbHk
誰か本書けや
741:デフォルトの名無しさん:01/09/03 13:57 ID:FtmBGRGU
>>731
歴史的経緯をちゃんと見れば「理論的には」Schemeが最強だね。
742デフォルトの名無しさん:01/09/03 21:38 ID:qXV4pYUY
>>740
今、日本にオリジナルの良書を書けるほどのツワ者LISPerが何人いることか。。。
電通大の竹内先生とか、SICPを翻訳した和田先生、東大の萩谷先生に京大の湯浅先生
とかくらいかな。
743デフォルトの名無しさん:01/09/03 21:44 ID:wy3QSGS6
萩谷・湯浅の本とか、訳書とかなら大きな本屋に売ってるでしょ。
図書館行けば間違いなく置いてあるし。大学生有利かな。
744デフォルトの名無しさん:01/09/03 21:45 ID:qXV4pYUY
>>741
Schemeは、確かに無駄な機能を極力省き、数学的に美しい。
だけど、何をもってして最強と定義するのか、それが問題。
記号処理を主体とした汎用プログラミング言語として、必要
十分条件を満たす言語を最強と定義するなら、Schemeはどうかな?
少なくとも、この定義なら、コモンは十分条件は満たすけど、必要条件
ではなく、無駄な部分が多いので、最強ではないね。
個人的には、LISP 1.5がいいと思うけど。
745NIL:01/09/03 21:49 ID:o032XSFY
某訳書は酷い翻訳だったけど,原書の装丁がそれよりも酷かっ
た(3日使うとバラバラになった)ので売れたんだよねぇー.
746デフォルトの名無しさん:01/09/03 21:53 ID:qXV4pYUY
>>743
湯浅先生は、最近はLISP系の本を書いてないね。
HPではJAVAでSCHEMEの実装とかを公開してるけど。
萩谷先生は、日本評論社から「関数プログラミング」って本を
出したっしょ。これは初学者にはわかりやすくてお奨めだけど、
上級者には物足りないかも。
747デフォルトの名無しさん :01/09/03 21:53 ID:o032XSFY
>>744
LISP1.5はシンプルだけどFSUBRという盲腸があるからな...
748デフォルトの名無しさん:01/09/03 21:55 ID:qXV4pYUY
>>745
某訳書って?
749デフォルトの名無しさん:01/09/03 21:58 ID:qXV4pYUY
>>747
確かに、一理ありますな。
この定義を満たす言語ってのが難しいから、いろんな方言が出てきたの
だし。
750デフォルトの名無しさん:01/09/03 22:04 ID:U9hn1Usc
Schemeの多値を返すインターフェースの部分って
規格書(R5RS)みた限りではなんだか中途半端な気がしますが、
実際どうなんでしょう。使ってる人っていますか?
valuesやcall-with-valuesの辺り。
751デフォルトの名無しさん:01/09/03 22:06 ID:qXV4pYUY
>>745
今、書棚のLISP本コレクションを眺めながら思ったけど、
某訳書って、まさか、後○先生が翻訳した、アノ本じゃあないよねえ。。。
752デフォルトの名無しさん:01/09/03 22:11 ID:qXV4pYUY
>>750
R5RSで曖昧な定義になっているのは、処理系によって微妙に違う
ことがよくある。私が一番信頼している(信頼できると思う)のは、
MIT Schemeの実装だけど。
753デフォルトの名無しさん:01/09/03 22:18 ID:7MZMrdcY
>>751

SICP じゃないの? ゼミの学生が訳したとしか思えんかったが。
Web で原文が公開されてることが分かってたら買わんかったのに。
訳はともかく内容は期待通りすばらしかった。
754デフォルトの名無しさん:01/09/03 22:21 ID:qXV4pYUY
>>753
SICPって言っても、初版の方のことでしょ?
二版は、和田先生が翻訳してるから、しっかりしてるはず。
(訳本も買ったけど、原書しか読んでないので、確かじゃないけど。)
755デフォルトの名無しさん:01/09/03 22:23 ID:qXV4pYUY
>>753
SICPの初版の装丁って貧弱だったかな?
二版の装丁はしっかりしてるけど。
756デフォルトの名無しさん:01/09/03 22:28 ID:xBWWifTI
>>750
ああインタプリタの実装のときすごく困った。
結局本体に手を入れたような。
757デフォルトの名無しさん:01/09/03 22:31 ID:o032XSFY
LISPファミリーに於ては、規格書は『メーカー希望小売価格』のよう
なもので、それが絶対的なものではありません。それがLISPの良さの
1つなんですが、残念ながら嫌われたり批判されたりする理由にもな
っています。個人的には道具としてのTAO/Heliumが好きでした。
758デフォルトの名無しさん:01/09/03 23:05 ID:7MZMrdcY
>>754

あっ二版の方です。
どうなんだろ、みんなはそうでもないんかな。
どうも某訳というのは SICP じゃさなそうだけど。
759デフォルトの名無しさん:01/09/03 23:09 ID:7MZMrdcY
>>758
じゃなそう => じゃなさそう
760デフォルトの名無しさん:01/09/03 23:40 ID:1zSk4pr2
LISPは仕様変更/拡張されてもある程度までなら自力で修正が
効くからあんま困らないね。
(多値対応は恐らく処理系自体に対して修正が必要だけど)
761デフォルトの名無しさん:01/09/04 08:46 ID:YviMCw/Q
Lisp系の言語でどれが最強かという話ならDylanはどうなるかな?
括弧が無い書き方も出来るから拒否感がある人もいるかもしれないけど、
Schemeを発展させたような仕様らしいよ。

Haskellなども候補になると思うけど、これはスレ違い。
762デフォルトの名無しさん:01/09/04 11:30 ID:5Y4kUfsc
>>761
Apple が初期に作ってたころは括弧ついてたけど、その内なくなった。
今のは括弧を受けつけないんでは。

現在、実装が行われているのはこれか。
ttp://www.gwydiondylan.org/

下の Larry Tesler の前書きを読むと Scheme を発展させているようには思
えんけど。 CLOS の影響を受けているようだが。

ttp://www02.so-net.ne.jp/~komuro/Mutsumi/DylanInfo/foreword.html
763デフォルトの名無しさん:01/09/04 17:11 ID:CUE4BAnw
>>762
でもLispに多大な影響を受けてるのなら、Schemeもたくさん参考にしたのは
間違いないと思うよ。
764デフォルトの名無しさん:01/09/05 02:48 ID:jFtajofc
>>761
SchemeでDylanをエミュるの無かったっけ?
765デフォルトの名無しさん:01/09/05 03:09 ID:jFtajofc
検索したら見つかった。
Bob: Jim Miller's algolesque syntax for Dylan implemented in Scheme.
http://www.cs.cmu.edu/afs/cs/project/ai-repository/ai/lang/scheme/code/syntax/bob/0.html
766デフォルトの名無しさん:01/09/05 22:52 ID:1ojJgpEE
bobdylan
767デフォルトの名無しさん:01/09/06 01:42 ID:d8b4MtxQ
こっちに貼っておきます。
The Hotdog Compiler
(Scheme->JVM
Scheme->C
Scheme->.NET)
http://www.cs.nwu.edu/~surana/
BaseがScheme48かな?
768デフォルトの名無しさん:01/09/06 03:51 ID:9dUi5gVA
こもんりすぷ、は、列とかをCLOS風に直さないかね。
この際、assocも多値にして。setfが可哀想…
769デフォルトの名無しさん:01/09/07 02:36
なんかschemeのソース見てると、
(null? #f)
=>#t
を前提としてるコードがよくあるんだけど、
これってどういう事なのかなあ?
(null? '())
=>#t
これ以外は#fが返る筈だと思ってたんだけど。
具体的なやつは、例えばassoc/member系の失敗判定をnull?で行なってたり。
770デフォルトの名無しさん:01/09/07 02:59
>765
これってMIT-Scheme用だね。
char-setとか非標準なやつ使ってる
771デフォルトの名無しさん:01/09/08 03:21
>>754
第2版にしてみても読みにくいと思うけど。
原文も難しいの?
772デフォルトの名無しさん:01/09/08 11:50
lispのnilがschemeでは#fに相当するからでは?>769
773デフォルトの名無しさん:01/09/08 13:29
>>772
相当しません。lispのnilは、schemeでは#fとnilに分解されました。
(null? #f)
=>#f
です。
774デフォルトの名無しさん:01/09/08 15:12
そういえばschemeの、'() #fや#tなどのcar cdrって、
取ってよい物なの?
ぶっちゃげた話、
(car #f)
=>#f
とかは成り立ちますか?
775デフォルトの名無しさん:01/09/09 02:18
>>774
成り立つ筈
(car '())
=> ()
776デフォルトの名無しさん:01/09/09 02:29
>>769
たしかR4RS以前は、#fと'()(nil)を同一視してたと思う。
777デフォルトの名無しさん:01/09/09 02:56
schemeにもnamespaceが欲しい
(genericな実装をするときに困る)
自力でできないことは無いけど
標準化されてるに超したことないし
改行を含む文字列をCommon Lispでどうやってかくの?
リテラルで。。(リテラルとはいわないみたいだけど)

へたれな質問ですんまそ。。へたれsage。
779デフォルトの名無しさん:01/09/09 03:12
>>778
文字なら
#\returnまたは#\newline
文字列はそのまま改行するんでは?
"改行を含む文
字列"
>>779
エエッ!?そのままでいいの??
ACLのコンソールでうまくいかなかったからあきらめてた。。
欝だ。。'(good-bye world)

恥さらし:
(format nil " ~C )" #\Newline)

ありがとう。。
781デフォルトの名無しさん:01/09/10 02:29
SchemeのOOパッケージってtiny-closとstklosの
他に何かありますか?(stklosのベースはtiny-closみたいだけど)
782デフォルトの名無しさん:01/09/10 03:06
783デフォルトの名無しさん:01/09/10 03:47
784デフォルトの名無しさん:01/09/10 05:40
最初はBOSというOOパッケージが
軽いしシンプルで良いと思う
785デフォルトの名無しさん:01/09/10 20:00
やっぱlispだとCLOS風の
(method obj args...)
という呼出し形式が一般的なんですか?
(obj method args)
だとapplyとかが使えなくなるから?
786デフォルトの名無しさん:01/09/10 21:39
>>785
Lispでは昔からfunctionとoperatorを区別しない習慣だけど、
そうすると+のようなbinary operatorは、(Lispではn-ary operatorだけど…)
(method obj args...)とか(obj method args...)とかいう見方は不自然だわな。
どうしても(method obj1 obj2)となる。で、generic functionの世界へ突入。

C++もoperator overload, generic functionがあるね、
だから、send message to objectの世界からは少し離れている。

Smalltalkみたいに一つの見方で閉じてるのが特殊なんだと思う。
787デフォルトの名無しさん:01/09/10 22:26
>>785
CLOS形式の利点は既存の関数がそのまま使える点にあると思う。
(メソッドと関数を区別する必要が無い)
788デフォルトの名無しさん:01/09/10 23:44
(method obj1 obj2)
ってやると、どっちのobjectのmethodが立ち上がるのでしょうか?
obj1ですか?
789デフォルトの名無しさん:01/09/11 00:05
>>788
obj1が<class-1>か、<class-1>の関係クラス
obj2が<class-2>か、<class-2>の関係クラス
として、
(method <class-1> <class-1>)
という形式のmethodが呼ばれる。
どっち、っていうのは考えない方が良いとおもう
主従関係があるとすれば、obj1の方。
790デフォルトの名無しさん:01/09/11 00:06
(method <class-1> <class-2>)
でした
791デフォルトの名無しさん:01/09/11 01:45
>>788
>>789のとおりだけど。。

第一引数(いわゆるthis、self)に対して特別なアクセス権を有する、
なんていう区別がないから、メソッドの引数はみんな平等だよ。

「メソッドは引数の型によって総称関数から選択される手続きである」
(引用元:ウィンストンとホーンの『LISP 原書第3版 (I)』培風館)

総称関数(generic function)ってのは同じ名前のメソッドの集まり。
だから「メソッドは総称関数に属している」のほうがぴったり。
792デフォルトの名無しさん:01/09/11 02:12
>>784の言うBOSって
(method obj . args)って形式しか
dispatchしないみたいなんですけど、
これを例えば
(method obj1 obj2)
と書きたい時はどうするんでしょう?
(第2引数以降の型も区別させたい)
良い方法ありますか?
793792:01/09/11 02:22
総称関数内で、argsに対してis-a?判定するしか
ないでしょうか?2度手間な気がします。
794デフォルトの名無しさん:01/09/11 03:17
>>792
良い方法は思い付かない。
多分、書き換えるしかない気が・・
ソース見た感じでは、
(assq generic specialised-methods)の辺りを
第2引数以降も判定する様に書き換えればなんとかなりそうだけど。
795デフォルトの名無しさん:01/09/11 03:19
その場合、最も限定的なmethodからヒットする様に
specialise!される度に、methodを引数についてソートする。

あとは総称関数の登録インターフェースに↓みたいな形式を許可する。
(specialise! add (list <number> <number>)
(lambda (call-next-method l r) (+ l r) ))
796デフォルトの名無しさん:01/09/11 03:21
いっそのことマクロで↓みたいにするとか。
(defmethod add ((l <number>) (r <number>)) (+ l r))

つーか、tiny-clos辺りに乗り換えては?
(実装が3倍ぐらい大きいけど)
797デフォルトの名無しさん:01/09/11 03:44
あと考えられるのは、
↓の様な、明示的型変換を行なう総称関数を作って、
(define-generic ->number)

+に渡る型を<number>のみになる様にフィルタリングするとか。
(specialise! add <number>
 (lambda (call-next-method obj . args)
  (apply + (cons obj (map ->number args)))))

解決にはなってないけど。
798792:01/09/11 07:05
色々参考になりました >>794-797
なんとか修正できそうです。
BOSは小さい割に完成されている感じがするので
しばらく使ってみようと思います。
799デフォルトの名無しさん:01/09/11 07:25
multi-methodをsupportしてない言語で使われる
double dispatchと呼ばれるpatternだから、検索してみれ
800792:01/09/12 02:00
なんとか形になりました。
(ドット対の部分がまだしっくりきませんが)

>>799
visitorパターンの事ですか?
(define-method method1 ((obj <class1>) arg)
 (method2 arg obj)) ;method2に処理を委譲

(define-method method2 ((obj <class2>) arg)
 (実際の処理 obj arg) )
という感じになるんでしょうか。
801デフォルトの名無しさん:01/09/12 02:23
dylanの書式と似てるね
802792:01/09/12 03:04
結局こういう風に記述できる様にしました。
(define-method method1 <class1>
 body) ;<class1>の参照はselfで行なう
または
(define-method method1
 (obj <class1> . args) body)
または
(define-method method1
 ((obj1 <class1>) (obj2 <class2>) . args)
 body)
お答え下さった方々、ありがとうございました。
803デフォルトの名無しさん:01/09/12 05:07
MOPが付いてるぶん、tiny-closが良い感じだけど、
そのまま使うにはちょっと重い気がする
804デフォルトの名無しさん:01/09/13 03:02
>>803
メソッドディスパッチは適応させるメソッドが多くなると遅くなるから、
レキシカルに固定化されたコードを解析して、実効メソッドに変換する
処理ってのが必要になると思う。
805デフォルトの名無しさん:01/09/13 04:02
簡単な最適化は、メソッド初回起動時に引数を解析して、
適応する可能性のあるメソッドのみを選択するclosureを作成して
次回からはそれを呼び出す様にする、とか。(メモ化)
これだとコードの探索は必要無い。
この処理をマクロ化して、コードをmacro-expandしておけば、
初回の解析も省かれる。
806デフォルトの名無しさん:01/09/13 06:02
普通の呼出し
(lambda (args)
 ((find-method args) args))

メモ化
(letrec ((method
 (lambda (args)
  (set! method (find-method args))
  (method args))))
 method)
807デフォルトの名無しさん:01/09/13 15:28
Inter Lisp って普通の Lisp とどっか違うんでしょうか?
808いつでもどこでも名無しさん:01/09/13 18:52
「普通のLisp」の意味を知りたいな...
809デフォルトの名無しさん:01/09/14 02:52
ACLと普通のLispと(以下略)
810デフォルトの名無しさん:01/09/14 03:24
メモ化って、適用するコードを書き換えないでできるでしょうか?
例えば下のfibについて(add dec == が総称関数だとして)

(define (fib n)
 (let loop ((a 1) (b 0) (c n))
  (if (== c 0)
    b
    (loop (add a b) a (dec c)))))

自分が思い付いたのは、
(define (fib n)
 (with-memorize-method (add dec ==)
  (let loop ((a 1) (b 0) (c n))
   (if (== c 0)
     b
     (loop (add a b) a (dec c))))))

こういう風にループ前にメモ化を明示する方法なんですが。
(上の様にfibをメモ化すると、4倍程速くなりました。)
811デフォルトの名無しさん:01/09/14 04:30
>>810
ディスパッチ処理でキャッシュしてみては?
関数に渡された引数の数や、引数の型同士のeq?比較の様な軽い
判定で、まずキャッシュにヒットするかをテストしてみる。
812デフォルトの名無しさん:01/09/14 05:45
つーか、BOSのメソッド探索アルゴリズムって、
まだ改善の余地ありって感じだけど
813デフォルトの名無しさん:01/09/14 07:31
機能追加はlispの十八番
VisualLISP
せめてTurboLISP作ってくれyo!
>>808>>809
そのツッコミで大体分かりました。ありがとう。
815デフォルトの名無しさん:01/09/14 16:37
>>808
LISP1.5
816デフォルトの名無しさん:01/09/15 03:18
C->LISPのトランスレーターってありますか?
817デフォルトの名無しさん:01/09/15 04:34
LISPでOOってのも良いかもね。
余計な構文いらないし
818デフォルトの名無しさん:01/09/15 17:04
(・∀・)
=>イイ!
819デフォルトの名無しさん:01/09/15 17:11
(define (・∀・)
 (lambda x (if (pair? x) (list 'カエレ! x) 'イイ!)))

((・∀・))
=>イイ!

((・∀・) >>818)
=>(カエレ! >>818)
820デフォルトの名無しさん:01/09/15 17:12
s/list/list*/(・∀・)デシタ!
821デフォルトの名無しさん:01/09/15 18:47
((´ ∀`) >>818 - >>820)
>>818-821
( ゚Д゚)
=>逝って良し!
823デフォルトの名無しさん:01/09/15 18:59
>>816
CTAXというのがあった様な・・?
824デフォルトの名無しさん:01/09/15 19:08
>>816
たしか
dylan->lisp/scheme
tk->lisp/scheme
logo->lisp/scheme
というのがあるから、その辺を参考にするとか。
(Cのパーサーってのはあったと思う。)

lisp/scheme->C
なら沢山あるんだけどねぇ
>>823
ctaxはC風の構文トランスレーター(guile)
825792 810:01/09/16 03:47
>>811-812
あれから、メソッド毎に枝分けする様に変えてみたら多少速くなりました。
普通の関数にはまだ及びませんが。
キャッシュする方法を考えてみます。
826デフォルトの名無しさん:01/09/16 04:10
自分でリストを表示するルーチンを作ってるのですが、
リストが巡回構造だと判定する良い方法はありますか?
親を順番に検索していって自身が検索されたら巡回
828デフォルトの名無しさん:01/09/16 04:20
>>827
やっぱりそういう地道な方法しかないですか。
ありがとうございました
829デフォルトの名無しさん:01/09/16 04:40
探索の手間が惜しいなら、リミッタを付けるとかすれば?>828
(let ((x (list 'dmy)))
 (set-car! x x)
 (set-cdr! x x)
 x)
=>(((((((((((((((((((((((((((((((((((((((((((((((...
831デフォルトの名無しさん:01/09/16 05:31
>>829
表示だけならそれで良かったですね。
832デフォルトの名無しさん:01/09/16 19:35
Schemeてどう発音するんですか?
聞く人によって答えが違う…
833デフォルトの名無しさん:01/09/16 20:05
すきいむ
835 :01/09/16 22:22
"scheme"のアクセントは「スキー」と同じみたいだけど、
言語のことをいうときはアクセントなしで読んでるなあ。
836デフォルトの名無しさん:01/09/16 23:31
>>826
仕事と同時にcheck。

(defun search (x l)
"lの中にxがあったら、それがcarなlistを返す。なければnil。"
(cond (((null l) nil)
(eq x (car l)) l)
(t (search-1 x (cdr l) l))))

(defun search-1 (x l r)
"searchの下請け"
(cond ((eq r l) nil) ; loop break
((null l) nil)
((eq x (car l)) l)
(t (search-1 x l r))))
837デフォルトの名無しさん:01/09/18 05:01
schemeの関数にデフォルト値って置けないですか?
CommonLISPのoptionの様な事したいんですけど
838デフォルトの名無しさん:01/09/18 09:57
>>837
(define (func . args)
(if (null? args)
(display "hello world!")
(display (car args)))
(newline))

(func)
hello world!
(func 'hoge)
hoge
lisp って意外と簡単でおもしろいね。
今まで見にくいとか差別してすいませんでした。
840デフォルトの名無しさん:01/09/18 14:46
記念age
841デフォルトの名無しさん:01/09/18 19:28
>>838
いえ、そういう事じゃなくて、
(define (f x :option (y 1) (z 2))
 (+ x y z))
で、
(f 0)
=>3
(f 0 0)
=>2
(f 0 0 0)
=>0
というのをしたかったんです。
マクロでできるかな?
842shige:01/09/18 22:16
(quit)
843デフォルトの名無しさん:01/09/19 01:04
>>841
マクロでちょっとしたパーサを書けばなんとかなる
844デフォルトの名無しさん:01/09/19 01:43
>>841

(define f (lambda (x :option (y 1) (z 2)) ...))
という書き方もしたい場合、lambdaも加工する必要がある。
どちらにせよ普通に考えれば、引数の使われかたを実行時に
判定する関数になるかと。
展開コードの例
(define (f x . rest)
 (let ((len (length rest)))
  (let ((y (if (> len 0) (list-ref rest 0) 1))
     (z (if (> len 1) (list-ref rest 1) 2)))
   (+ x y z))))
マクロを生成するマクロにすれば、実行時判定は消えるけど、
関数引数やapplyで呼び出せないなどの制限がある。
845デフォルトの名無しさん:01/09/20 02:59
前、どっかにoption使う例があったと思った。schemeで。
多分マクロ
846デフォルトの名無しさん:01/09/21 02:22
>>841
syntax-rulesで、lambda-with-optionってのをdefineして、

(define f (lambda-with-option (x :option (y 1) (z 2)) 略)

ってやれば?

# defineの第一引数がpair?なら…ってダサクない?
# (a b c)って形式の意味を定義する、ってノリなんだとは思うけど。
847デフォルトの名無しさん:01/09/21 05:25
>>846
># defineの第一引数がpair?なら…ってダサクない?
(define (a b c) ...)は確実に記述量とカッコのネストが
減るからsyntax-sugarとしては妥当かと
848デフォルトの名無しさん:01/09/21 05:36
>>841
http://zowie.metnet.navy.mil/~oleg/ftp/Scheme/parsing.html
ここのinput-parse.scm の中に

(define-opt (foo arg1 arg2 (optional (arg3 init3) (arg4 init4))) body)
という形式を変換するマクロがあったよ。
>>847
define-functionとか別の名前にして欲しかったなー。
二つ意味を持つのは美しくない。
850デフォルトの名無しさん:01/09/22 03:21
美しくない?
851デフォルトの名無しさん:01/09/22 03:27
気に入らなければ各自
構文を拡張せよ
852デフォルトの名無しさん:01/09/22 10:23
>>849
考え方、オカシイヨ
853デフォルトの名無しさん:01/09/22 11:11
(define (f))は
(define f (lambda ()))
でしょ?
(define a 1)とするのと変わらない。
2つの意味って何のこと?
854デフォルトの名無しさん:01/09/22 13:42
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$

あなた達には分からないでしょうが、Rubyは素晴らしい言語です。
オブジェクト指向スクリプト言語として他のスクリプト言語を圧倒する性能と美しい言語仕様を持っています。
例えば、SchemeやSmallTalkなどは比較的美しい言語だと言われていますが、後発である優位さでRubyは
さらなる美しさと実用性を備えています。
もちろんPerlやPythonなど問題外です。
日本語との親和性ではRubyしか選択肢がないでしょう。

LinuxのディストリビューションもRubyの採用例が増えてきています。
1年後には全てのディストリビューションがRubyを標準採用するでしょう。
Rubyは未来のスクリプト言語なのです。

長くなりましたが、コピペではありません。
賛同していただける方はRubyの事を分かっていただけない人に出会ったら、
この発言をコピペしていただければ幸いです。
>>854
早速Delギコスレにコピペされていましたよ。よかったですね。
Rubyはクソです。ゴミ箱逝きです。

いじょ
Smalltalk氏「Rubyはカッコがオブジェクトじゃない。全てが
オブジェクト?笑わせないでくれ。(プ」

Scheme氏「Rubyはプログラムや継続自体がファーストクラスオブジェクト
ではない。文字列をeval?リストじゃないの?(ワラ」

Perl氏「Rubyが綺麗だって?endの羅列で汚いじゃん。(ゲラゲラ」
858デフォルトの名無しさん:01/09/22 18:29
Perlに汚いって言われるなんて、言語として最大の屈辱だよな(藁
859デフォルトの名無しさん:01/09/22 18:33
でも事実だから仕方ないよ。
ダメ人間共がRubyを煽ってるねー。
そんな事をして楽しいのかなあ。
857なんて全然わかってないし(藁
実用性ならRuby>>>>>>>>>>>>>>>>>>>>Smalltalk,Schemeだよね。
今時SmallTalkやSchemeで何作れっていうの?(プププ
861デフォルトの名無しさん:01/09/22 18:40
>>854-860
きみらスレ違いなのヨ
しかしワラタ
8631Rubyユーザ:01/09/22 20:29
Schemeなんかに実用性はありません。いじょ
864デフォルトの名無しさん:01/09/22 20:38
>>863
ハァ?
schemeで検索してみたら?
実用例が山ほど出てくるから。
>864
君はscheme何に使ってんの?
866デフォルトの名無しさん:01/09/22 20:40
りかぁじょん のおべんきょう。
867デフォルトの名無しさん:01/09/22 20:40
googleで検索してみた所
Scheme 約5,010,000件
Ruby 約1,630,000件

レベルが違うんだよ、厨房君。
868デフォルトの名無しさん:01/09/22 20:44
schemeってDBとかいじれるの?
Rubyはいじれますよ。
Ruby/TKって知ってます?
schemeはGUIプログラミングなんて出来ないでしょ。
8691Rubyユーザ :01/09/22 20:45
ね。おもしろいでしょ。
ちょっと扇ってやっただけでこの反応。
マイナー言語ユーザの結束の固さ(大爆笑)には毎度ながら驚くよ。(嘲笑)
866=867なんかに実用性はありません。いじょ
Rubyに実用性で負けているのは事実です。
ですが、わざわざここに来て書き込む事ではないでしょう。
Rubyスレッドに戻ってください。
868みたいなのはRuby使ってもScheme使っても
「DB」なんていじれないし、「GUIプログラミング」とやらもできないだろうな。
なんだ?
なんでruby厨房がこんなところに?
874デフォルトの名無しさん:01/09/23 05:06
>>848
そのサイトってなんか色々あるね
875まじれっさ:01/09/23 05:51
>>867
scheme も ruby も、他に意味を持った単語なんだから
検索して出てくるものすべてが、プログラミング言語である scheme や ruby
を指しているわけじゃないので、それってちょっと意味無いと思うよ。
876ruby:01/09/23 05:52
sage
877デフォルトの名無しさん:01/09/23 11:17
schemeって名前カコイイ
878デフォルトの名無しさん:01/09/23 13:40
ったら鞭打
879デフォルトの名無しさん:01/09/23 13:58
よーし、1000目指すぞ!
880デフォルトの名無しさん:01/09/24 18:44
LISPでマクロを作るという意味がやっとわかった。
ほとんど新しい構文じゃん
881所新車:01/09/25 04:45
最近、SICPを読み始めて、その流れでMIT Schemeを使っているのですが、
みなさんの使っているLisp処理系はどういうものなんでしょうか?

少しでも調べてみると、Lisp処理系は異常なほどにべらぼうに多いので
どういうものがポピュラーなのか、初心者向けなのか、遊びがいがあるか…
というのが、よく分からないです
最近、DrSchemeを使い始めましたが、これは楽しいですね
882 :01/09/25 22:56
♪Girls just wanna defun

I can't wake up, in the morning
Cause of what I've been doing for most of the night.
Teacher don't you know my program is done?
And girls just wanna defun.

The phone rings, in the middle of the night
Advisor screams, "Watcha gonna do with your life?"
Patrick**, how I relish double-oh-one***!
And girls just wanna defun.

They just wanna, just wanna, yeah
Girls just wanna defun.

Some people say
A beautiful girl can't tool all night like
The rest of the world.
I wanna be the one to welcome the sun.
And girls just wanna defun.
883デフォルトの名無しさん:01/09/26 02:51
>>881 自作しろ
884 :01/09/26 10:05
>>881
いちばんメジャーなのはSCMじゃないの。
885デフォルトの名無しさん:01/09/26 19:25
SCMとGuileって何が違う?
886デフォルトの名無しさん:01/09/26 22:07
guileとSchemeとのもっとも大きな違いは、guile では識別子とシンボルで大文字と小文字が区別される点です。
これは大文 字と小文字を区別する他の言語とのインタフェースをとりやすくするため と考えられます。
変数や定数に一貫した名前を使っていれば、 Schemeプログラムはguileでも動作します。
guileではTk、gimp、gtkなどのGUIをモジュール として取り込んで利用したり、逆に異なるアプリケーションから guileオブジェクトを利用することが容易になっています。
guileのベースになったのはAubrey Jafferさんの SCM(version 4e1)ですが、SCMとはだいぶ違ったものになっ ています。SCMの軽快さはguileでは当初から失われていました。
Schemeの拡張と見るか肥大化と見るかによって、guileの 評価は変わるでしょう。guile自体はいずれの評価とも関わりなく、 活動と拡大を活発に続けています。

http://www4.ocn.ne.jp/~inukai/scheme_j.html
slibというものを落としてみましたがどういうものかさっぱり分かりません。
888デフォルトの名無しさん:01/09/27 20:40
>>887
じゃあなんで落としたの?
889887:01/09/27 23:04
>>888
ポケットに穴が空いていたんです。
890デフォルトの名無しさん:01/09/28 00:28
(  ´_ゝ`)  < ふーん
891デフォルトの名無しさん:01/09/28 00:38
Bigloo
ってどうでしょう?
892デフォルトの名無しさん:01/09/28 01:17
使ってみろよ
893デフォルトの名無しさん:01/09/30 16:24
guile-for-winがあれば便利なのだが
Tkは、使いたくない
894デフォルトの名無しさん:01/10/01 19:39
>>841
亀レスだけど。
(lam (<a1>... [&optional <o1>...] [&rest <r>]) <body>)
こういう構文が書けるらしい。
http://www-2.cs.cmu.edu/afs/cs/project/ai-repository/ai/lang/scheme/code/ext/function/
895デフォルトの名無しさん:01/10/01 21:33
なんでもありだな
896デフォルトの名無しさん:01/10/02 19:41
LISPの欠点は区切りが空白しか無いこと。
(+1 2)
これは'+1'というシンボルを探しに行く。

(with-operator (+)
(+1 2))
こういうのが欲しい。可能?
>>896
どうしてわざわざくっつけたいの?
898デフォルトの名無しさん:01/10/02 23:45
>896
マクロでできる。
本気で考えてるなら、リーダーを自分で作るとかした方が良い。
899デフォルトの名無しさん:01/10/03 00:35
>>898
できたとしても、適用できる範囲が狭そうだから無駄な労力に
なるかも・・・
\\\     \ \\
   \\ヾ__ ∧_∧_ヾ\
\   \ \ (*´∀`)_\ \
\\     | ̄ ̄∧∧  |  ヾ
\\\ ヾ   |\ ミ;゚Д゚ ∧_∧
  \\\      | ̄ ̄ ( *・∀・) 今だ!900番ゲットォォォォ!!!
   \\\ ヾ  |\ ̄/っ y っ\
     \\       |  ̄ ̄ ̄ ̄ ̄ |
901デフォ:01/10/03 03:45
SICPをチョット前から読み始めて、同時にSchemeも始めたのですが…
今更になって、今まで使ってたS式自体がリストだって事に気づいた
すごいね…の一言

SICPでは、継続とかマクロとか出てこないみたいなんですけど、
知ったら、やっぱり、すごいと感じるのでしょうか?
> 今まで使ってたS式自体がリストだって事に気づいた

すまん。どうすごいんだ?
すごいよ。マクロのおかげでいろんなことが出来る。
様々なことが出来ることこそが、SchemeがC++やJavaなどより
圧倒的に強力な所以。
>>893
Windowsならコンパイラがほしい。
UNIXだとインタプリタで十分だと思うんだけど
(速さを求めなければそれで良いから、perl,pyhton,rubyのアプリも沢山ある)、
Windowsで何か作って配布でもしようとすると(私がそうするというわけではなく)、
どうしてもコンパイラ言語になる、ということが多いと思う。
905デフォルトの名無しさん:01/10/03 19:22
>>904
バイトコードっつーか、実行するコードをメモリイメージにしといて、
1つのEXE作るってのはやった事あります。
(コンパイラと名乗れるほど高級じゃなかった。)
そのイメージを適当に圧縮しとけば、まあEXE覗かれたとしても
普通の人はわかんないし。w
そのEXEは、まんまLISPエンジンが載ってるので、
当然ながら外部のLISPコードも読みこめます。

SchemeだとSIODって処理系がたしかEXEつくってくれたんじゃないかと思います。
906905:01/10/03 19:25
907904:01/10/03 21:15
>>905
なるほど、エンジンも一緒に乗っけてしまうのか……。
物知らずな私には思いつきませんでしたが
>>906
どうもです。
908デフォルトの名無しさん:01/10/03 21:32
自分はelispをちょこっといじったことがある程度の情報科の学部2回生ですが、
lispってどのへんが人工知能なのでしょうか?
909デフォルトの名無しさん:01/10/03 21:57
データとプログラムが完全に分かれていないのは
メリットになるのですが?
910デフォルトの名無しさん:01/10/03 23:21
>>909
なんかの演算の結果をそのままデーターとして再利用できる。
おんなじことCでやったら、変数宣言して代入して計算してその結果を代入しなおしてその変数を計算して...となる。
>>910
君、なんか違うよ。
912デフォルトの名無しさん:01/10/03 23:31
>>910
なるほど
>>912
違うってば…
>>908
lisp = 人工知能じゃないです
どのへんも糞もありません

>>910
Cでも変数に代入しないようにプログラムすることは可能です。
つか、「演算結果をデータとして…」って
プログラムコードとデータが分かれてないのと関係ないです。
つか、演算結果がデータでなくてなんなのでしょう?

>>909
マクロとかで便利
915デフォルトの名無しさん:01/10/04 01:45
>>914
lispて人工知能言語だってよく聞くけど、それはなぜ?
人工知能とどういうふうに関係あるのか聞きたいです。
煽りではなくマジレスで。
916914:01/10/04 02:01
あ、どのへんが人工知能言語?って話ね。
えーと、なんで人工知能の研究に使われてた(る)んだろうねぇ?
正直、よく知らないです。
記号処理が人工知能研究に向いてるとかでしょうか?

フォローしてくれ > 識者様
人工知能だとか、そういう研究的なことは、普通
のプログラムに比べて極端に難しくて複雑な考え方を
使うわけよ。
だから、言語として一番柔軟性があって記述力のある
Lispが主流ってこと。
918デフォルトの名無しさん:01/10/04 02:11
>>916
LISPを設計したJ・マッカーシーが人工知能やってたからじゃないの?
一応、マッカーシーは人工知能向けに考えて作ったとの話。
詳細はジョン・マッカーシーで検索
あと、スタンフォード大学にマッカーシーのWebサイトがあったはず。
>>901
LISP系マクロは一回さわっといた方がいいよ。
継続は、制御構造の親玉で、例外処理とかコルーチンなどが
小細工無しで作れたりするんで、結構カルチャーショックがあるかも。
920デフォルトの名無しさん:01/10/04 05:22
XML関連のシステムってLispで作るのがよさそうね。
921デフォルトの名無しさん:01/10/04 05:55
http://www.amazon.co.jp/exec/obidos/tg/detail/glance/-/english-books/0262194554
ところでこの本はいったいなんですか?サスマンの本なのですが
まあ自分で自分を拡張してゆくというか
自分で自分のプロうグラムを書き換えてるような所が
昔は人工知能への近道に思えたんでしょうね
923デフォルトの名無しさん:01/10/04 09:39
>>903
うーん、>>896はまだそこに気づいてないんだな。
S式はsimpleだから便利で強力なんだ。(, ), car, cdr, cons, null, これだけ。

単純な事が力になる、これはよくあることだな。The Internetのbest effort deliverとかさ。
普通はFORTRANでプログラミングしてる時代に生まれたんだから、
数値計算ばりばりでなく、作っては壊しを繰り返し改良を重ねないといけない
人工知能研究に重宝されるのは当然な気がする。
925デフォルトの名無しさん:01/10/05 00:53
fluid-letって今まで使い道わかんなかったけど、
どうやら既存のコードを変更せずに別の解釈にするって事ができるらしい。

;数値しか引数に取れない+オペレータ
(define (fun a b) (+ a b))
(fun 1 2)
=>3

;これを一時的に他の型に対しても適用させたい。
(fluid-let ((+ generic-add)) ;一時的に+を総称関数化する
 (fun "1" "2"))
=>"3"
926デフォ@901:01/10/05 03:34
>>923 1ヶ月、Schemeやってて、やっと気付いたのがS式=Listってこと。
いや、マジで、(, ), car, cdr, cons, nullだけで必要十分ですね。
おかげで、思考自体も高度にシンプルになりました。
 「まとめたいものを(と)で束ねる」
それだけ。(これに気付くのに、1ヶ月かかるとは…)
この極度の柔軟性は、逆に当たり前過ぎて、説明しづらい。

しかし、使ってて思ったのが、Schemeは強力か?ってことです。
確かに、知ってるなかで、最高度の思考的柔軟性を与えてくれるが、
シンプル故に、強力さは使用者に依存してしまう。
つまり、想像しうることは(おそらく)すべて表現できるが、
逆に言えば、使用者の想像の限界がSchemeの限界にもなってしまう。

まあ、僕みたいなヒヨッコが使うと強力さを生かしきれないってことです。
927デフォルトの名無しさん:01/10/05 09:16
>>926
マクロ使うとだいぶ楽になるよ
928デフォルトの名無しさん:01/10/05 10:13
>>926
SICPがその典型だと思うが、(言語解説部分の短さと内容の豊富さを見よ)
programmingにおいて本題に集中させてくれる、と考えれば嬉しい事だ。

人工知能向きという評価もそういうところから出たと思われ
当時としては極端に複雑なalgorithmを人口知能屋は追求していたわけだから。
929デフォルトの名無しさん:01/10/05 12:33
>>926
quoteもよろしく.
quasiquoteもよろしく。
931デフォルトの名無しさん :01/10/05 18:47
>>926
プログラムもデータもすべてS式(リスト構造)であるため,プログラムその
ものが別のプログラムを生成することも,自分自身を書き換えることも出来る
ため,人工知能の研究に向いていました....というか,人工知能の研究のため
に設計された言語です.一方Scheme は,λ計算の過程を学生に見せるために実
装したのが切っ掛けだったと思います.
932デフォルトの名無しさん:01/10/05 23:20
恐るべき Scheme の威力

(define (A x y)
(cond ((= y 0) 0)
((= x 0) (* 2 y))
((= y 1) 2)
(else (A (- x 1)
(A x (- y 1))))))

(A 1 10)

これを DrScheme でステップ実行したらえらいことになった。
933Ruby!:01/10/05 23:24
+++++++++++++++++++++++++++++++++++++++++++++++
☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆
Del厨断末鬼の叫び!!!
拙い言いがかりからRubyを必死に煽ろうとしたDel厨が逆襲を受けて死亡!
理論的にDelphiはRubyの足元にも及ばないことが証明された!!!
「Ruby撲滅スレ」
http://piza2.2ch.net/test/read.cgi/tech/1001125342/
★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆
934デフォルトの名無しさん:01/10/06 00:21
>>932
どうなったの?
935無名λ式:01/10/06 01:02
>>931
> 一方Scheme は,λ計算の過程を学生に見せるために
> 実装したのが切っ掛けだったと思います.

λ計算ちゃいます。かーるひゅいっとのActor理論です。
(lambda の代わりに(alpha がある、新しいinterpreter作ろうと思ったら、
continuation付きのLisp(=Scheme)があれば十分だった、と。

http://www.cs.umbc.edu/331/resources/papers/Evolution-of-Lisp.pdf読んでみ
936デフォルトの名無しさん:01/10/06 10:41
937デフォルトの名無しさん:01/10/06 11:52
板違いだけど、pdfをテキストかhtmlに変換して
英和翻訳してくれるサイトってありませんか?
英語読めないのか...(プ
939デフォルトの名無しさん:01/10/06 14:14
>>938
ごめんよ(w
英語はまあ、翻訳サイトあるからいいけど、pdfが通らない。
940デフォルトの名無しさん:01/10/06 14:20
>>938
あ、よかったら要約してちょ(はぁと
941無名λ式:01/10/06 14:20
942デフォルトの名無しさん:01/10/06 14:24
>>941
すいません。
うちの環境がクソすぎて、ソフトはもういれらんないのです。
これ以上はスレの迷惑になるので諦らめます。
他の方法を模索します。(パソコン買い替えるなど)
ご迷惑お掛けしました。
943デフォルトの名無しさん:01/10/06 18:28
以前 bitに Sussmanさんだかに Schemeの生い立ちのインタビュー記事が
ありました。2ヶ月にわたって載ってた。
何年何月号だったかわ今はわかりませんけど、そこに >>935 さんの言って
たような事が書いてありましたよ。
デッカクなる前の bit だったと思います。
944943:01/10/06 20:24
Scheme過去・現在・未来(前編) bit 1996/04
Scheme過去・現在・未来(後編) bit 1996/05

Guy L. Steele Jr. (訳 井田昌之)

でした。
945デフォルトの名無しさん:01/10/07 02:16
>944
図書館に行けば見れるかな?
いいかげんpdfでもなんでもいいから電子化してほしい・・>蔵書
946デフォ@901:01/10/07 04:04
継続を学ぶためのお勧めの情報源にはどんなものがありますか?
947デフォルトの名無しさん:01/10/07 07:15
>>945
> 図書館に行けば見れるかな?

bitは世田谷区図書館レベルでもあったな。
948デフォルトの名無しさん:01/10/08 05:42
(((lambda(r)(set! r(lambda()(r))))'米国が攻撃開始))
949おいおい:01/10/08 08:43
(set! r (lambda () (r))) の帰り値は未定義だぞ
950 :01/10/08 09:21
(define terrorism (lambda (x y) (reprisal y x)))
(define reprisal (lambda (x y) (terrorism y x)))
951デフォルトの名無しさん:01/10/08 15:46
(cons 1 (cons 2 (cons 3 '())))と
(list 1 2 3)
てどっちが速いの?
952デフォルトの名無しさん:01/10/08 17:02
>>951
作りによるだろ
終端がnilで良いならlist使っとけ
953 :01/10/08 17:15
`(,x ,y ,z) と
(list x y z)
てどっちが速いの?
>>953
quasiquoteの実装具合によるだろ
おれっちの環境ではlistが圧倒的に速いけどさ
955デフォルトの名無しさん:01/10/08 17:21
(list* a b c)

`(,a ,b ,@c)
てどっちが速いの?
956デフォルトの名無しさん:01/10/09 00:10
guileを使っていろいろと遊んでいるところなんですが、
これを終了させるのになにかいい方法はないですか?
いまはCtrl+zしてからkill -9してるんですが、皆さんどうされてますか?
957デフォルトの名無しさん:01/10/09 00:16
>>955
list*
qquoteは余計な解析パスが掛かる。
>>956
(exit)とか(quit)って無かったっけ。
>>957
!!!ありがとうございます!!!
これを知らずに何日苦労したことか・・・
>>958
Ctrl-D(=端末からのEOF)でもOK。
そろそろ次スレ立てて欲しいところなんだけど、
その前にリンクの整理と参考書籍をまとめようよ!
>>960
とりあえず次スレ立てておきました。
リンク先とかは2以降ということで。
LISP Scheme Part2
http://piza2.2ch.net/test/read.cgi/tech/1002584344/
962デフォルトの名無しさん:01/10/09 16:47
Schemeについて日本のポータルサイト(?)
http://www.sci.toyama-u.ac.jp/~iwao/Scheme/
963デフォルトの名無しさん:01/10/09 17:40
■■■■ 推薦書籍 ■■■■

【計算機プログラムの構造と解釈(SICP)】
日本語 http://www.amazon.co.jp/exec/obidos/ASIN/489471163X
原書 http://www.amazon.co.jp/exec/obidos/tg/detail/glance/-/english-books/0262011530

私はこれだけしか読んでないヘタレなので、あとは識者の方、下のリンクから推薦書籍をあげて下さい。
よろしくお願いします。
個人的にはいつの間にか刷られていた、CommonLisp 2edが欲しいところです。
http://www.amazon.co.jp/exec/obidos/tg/detail/glance/-/english-books/1555580416


アマゾン "Scheme" 和書検索結果
http://www.amazon.co.jp/exec/obidos/search-handle-form/250-7032484-4473008

アマゾン "Scheme" 洋書検索結果
http://www.amazon.co.jp/exec/obidos/search-handle-form/250-7032484-4473008

アマゾン "Lisp" 和書検索結果
http://www.amazon.co.jp/exec/obidos/search-handle-form/250-7032484-4473008

アマゾン "Lisp" 洋書検索結果
http://www.amazon.co.jp/exec/obidos/search-handle-form/250-7032484-4473008
964デフォルトの名無しさん:01/10/09 17:41
965デフォルトの名無しさん:01/10/09 17:45
すいません、検索結果へ直接は飛べないみたいです。
ごめんなさい。
966デフォルトの名無しさん:01/10/09 19:30
>>963
Web で読めるよ
967デフォルトの名無しさん:01/10/09 19:30
968964:01/10/09 19:35
>>967

俺の書いたのと何が違うんだ?まあいいけど。
969Part2の1:01/10/09 20:07
2へ適当にリンク貼っておきました。
足りない様でしたら補完おねがいします。
970デフォルトのん足:01/10/09 20:09
>>969
ありがとうございます
971 :01/10/09 20:16
がいしゅつ?

"The Scheme Programming Language Second Edition"
http://www.scheme.com/tspl2d/index.html

日本語訳では「プログラミング言語Scheme」という本になってるよ。
972デフォルトの名無しさん :01/10/09 20:26
>>971
初出みたいですね。でも関数言語の本ってWebに公開されて
いるものが多いですね。教科書として毎年生徒の数だけ
売れることが約束されているからあんまりセコくならないのかな?
英語だと世界中で教科書として使われるわけだし。
973デフォルトの名無しさん:01/10/10 10:23
Common Lisp the Language, 2nd Edition
http://www.math.uio.no/cltl/clm/clm.html
974デフォルトの名無しさん:01/10/10 20:06
C言語 a = b = c;
Scheme (set! a (begin (set! b c) b))
うむむ・・
975デフォルトの名無しさん:01/10/10 20:17
>>974
副作用が基本の言語と比べるのって...
976デフォルトの名無しさん:01/10/10 22:25
>>974
記述量を問題にしてるならマクロつかえ
977デフォルトの名無しさん:01/10/10 22:53
(define b a )
(define c a)
ぢゃだめなの?
978 :01/10/10 23:15
{hoge ... } => (begin hoge ...)
みたいなマクロって書ける?
979デフォルトの名無しさん:01/10/10 23:38
>>978
まずカッコが無いとだめ。
(operator args)
が基本なので、無理矢理やるとしたら
({ hoge... ) => (begin hoge ...)
980デフォルトの名無しさん:01/10/10 23:40
>>980
マクロ文字というのがある。
Schemeでは規定されてないけど、
厳密なLISP処理系ではマクロ文字が定義できる筈。
`',,@(←こういうのは本来マクロ文字。)
マクロ文字は演算子に近いので、シンボルなどと
くっつけて書いても区別される。
'a => (quote a)
マクロ文字は無いけど、どうしても使いたい場合、
(read)を修正するとか。
981デフォルトの名無しさん:01/10/10 23:41
982デフォルトの名無しさん:01/10/10 23:55
>>981
はげしくどうい!
983デフォルトの名無しさん:01/10/11 13:18
プログラマー板「リスプ」より
http://mentai.2ch.net/test/read.cgi/prog/963134110/

> franz Lispにあるfexprって言う関数は
> XLispにありません。
> exprから誘導出来ますか?

FEXPRは、可変個引数でかつ引数を評価しない関数なので、
マクロで書き直しましょう。引数が評価されてもいいなら、

(defun fname (&rest arg) ふにゃふにゃ)

で可変個引数にしてもいいです。
984Lisp板の753:01/10/11 22:41
>>983さん
Thanx
今問題のソースPLT Schemeに移植してますがてんとう虫が出まくってます。
あと もし関数に渡す引数が評価されては、まずい場合はどうなんでしょうか?
985デフォルトの名無しさん:01/10/11 22:54
>>984
だから、マクロで全部解決するって・・
986Lisp板の753:01/10/11 23:20
(define-macro prove fexpr (wff)
(wang (addr (car wff) (line 0 nil nil nil nil)))
こんな感じでしょうか?
987デフォルトの名無しさん:01/10/11 23:50
)
define-macro: malformed definition
>
ちゃんちゃん
>malformed definition
    ↑
これもう見飽きました
Xlisp-statに帰ります。
988デフォルトの名無しさん:01/10/12 00:24
>>986
> (define-macro prove fexpr (wff)
> (wang (addr (car wff) (line 0 nil nil nil nil)))
> こんな感じでしょうか?

XLispってschemeじゃないよね。

< (defmacro prove (wff)
< `(wang (addr (car ,wff) (line 0 nil nil nil nil)))

じゃねーの? XLispにbackquoteあるかどうか知らんけど。
989デフォルトの名無しさん:01/10/12 00:31
Schemeでnilを定義するばあい、
(define nil '())
(define nil #f)
どっちがいいんでそ?
990デフォルトの名無しさん:01/10/12 00:35
Lispスレの765さん
>(define-macro fexpr (lambda rest body...))
これはマクロでfexprを定義しているって事ですよね?
カキコしながら またダメ
> (define-macro fexpr (lambda rest body))
> (define prove fexpr (wff)
(wang (addr (car wff) (line 0 nil nil nil nil)))
)
define: malformed definition
>         ↑
       ちゃんちゃん
991デフォルトの名無しさん:01/10/12 00:36
>>988
ありがとうございます
992Ruby戦隊:01/10/12 00:38
Ruby >>>>>>>>> Scheme
993Ruby戦隊:01/10/12 00:39
             
Ruby >>>>>>>> Scheme
994ruby!:01/10/12 00:39
Ruby!!!!!!!!
995Ruby!:01/10/12 00:40
るびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびー
るびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびー
るびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびー
るびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびー
るびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびー
るびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびー
るびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびー
996ああああああああ:01/10/12 00:41
                         
るびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびー
るびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびー
るびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびー
るびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびー
るびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびー
るびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびー
るびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびー
997Ruby戦隊:01/10/12 00:42
                        
るびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびー
るびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびー
るびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびー
るびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびー
るびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびー
るびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびー
るびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびー
998__ruby!__:01/10/12 00:43
_______________                       
るびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびー
るびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびー
るびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびー
るびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびー
るびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびー
るびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびー
るびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびー
999__RUBY__:01/10/12 00:43
^^^^^^^^^^^^_______________                      
るびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびー
るびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびー
るびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびー
るびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびー
るびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびー
るびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびー
るびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびー
10001000!:01/10/12 00:43
Ruby >>>>>>> Scheme
10011001
このスレッドは1000を超えました。
もう書けないので、新しいスレッドを立ててくださいです。。。