1 :
デフォルトの名無しさん :
2001/04/13(金) 22:41 '(hello world)
2 :
デフォルトの名無しさん :2001/04/13(金) 23:46
ちょっと質問なんですが、 (lambda (init) (let loop ((var init)) ...(if (...) x) ... (loop (- var 1)))) こういうループをxの時点で中断したいんだけど、何か良い手段はありますか?
書き忘れましたが言語は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版」は?
>>5 なるほど。loopをifスコープ(?)の中で書いても良かったんですね。
有難うございます。
SchemeにはC言語でいうbreak/continueとかが無いみたいなんで困ってました。
(継続使えとか言われそうですが)
;継続を使った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))))))
10 :
2 :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)))
11 :
2 :2001/04/14(土) 01:11
ってのが見つかったんですが、なんか難しいですね。 (まだインデントの付け方もよくわからない・・)
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
16 :
15 :2001/04/14(土) 14:11
LISPの日本語のポータルサイトってあります?
>>15 みたいな所
Schemeは(比較的)良く見つかるんだけど
17 :
デフォルトの名無しさん :2001/04/14(土) 23:58
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と違うようなので使っていません。
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
25 :
デフォルトの名無しさん :2001/04/17(火) 22:08
>>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
など
>>23 試したところ日本語シンボルOKだった。GCL 2.2.1。
もとになったKyoto Common LISPを作った萩谷先生の文章が
他のスレで紹介されてた。
28 :
デフォルトの名無しさん :2001/04/18(水) 09:33
29 :
デフォルトの名無しさん :2001/04/19(木) 20:55
LISP/Schemeでの双方向リストの実装について質問なんですが、 (item next prev)というリンクを作ると、リストが巡回構造になって このままだとリストがまともに表示されなくて困ってます。 こういう場合、どういう風に作るのが良いんでしょうか。 次にSchemeのソース載せます。
30 :
29 :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))
31 :
29 :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 ))))
32 :
29 :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 .... これをなんとかしたいんです。
33 :
29 :2001/04/19(木) 21:03
あ、データ構造は dlist : (front back) link : (item (next . prev)) です。
表示させなきゃいいんじゃ.
>>29 つーか普通の処理系は表示するとき nest levelで制限してない?
36 :
29>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)))))) ・[を置いておくと、)が閉じてない場合]の位置で強制的に[に対応するまで閉じる。 ・対応しない]がある場合、閉じてない'('括弧を全て閉じる。 って解釈でいいのかな。(自身なし
38 :
37 :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] うーん、括弧の対応付けが判って多少は良くなったかな? ただ、初めて見る人にとっては、「なんじゃこりゃ?」って印象でしょうね・・(汗
スーパー括弧 [] はコードを入力するときには使うけど、 pp するときには普通の表示が良いなあ。
40 :
37 :2001/04/20(金) 23:29
[]挟むだけでなんかメリハリが付く感じで良いですね>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木など)に変換する方法を考えています。 英語のホームページを片っ端から調べてみても見つかりませんでした。 お分かりになる方はよろしくお願いします。
なんて読むんだ>xyzzy 臭い爺?
47 :
デフォルトの名無しさん :2001/04/24(火) 19:10
>なんて読むんだ>xyzzy 妻子と読むのですといいですね。
48 :
44 :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
50 :
>45 :2001/04/24(火) 21:32
あと、有名なサイトは
>>15 のサイトから辿れます。
51 :
デフォルトの名無しさん :2001/04/24(火) 22:24
>48 Cの#defineと同じだよ。 機能がむちゃ強力なだけ。 FORTRAN表記をLispに直せちゃうくらい強力だが…
52 :
44>51 :2001/04/24(火) 23:10
ですねー。 マクロの引数の解釈に手間取りましたが(汗 (car l) => もしもだよ (cadr) =>(< 0 1) (caddr) =>$t (cadddr) =>$t 構文拡張した気分になれます。 if->もしもだよみたいな単純なsyntax名の置き換えなら (マクロ定義 もしもだよ (lambda (l) (cons 'if (cdr l] で良いみたいですが。
53 :
44 :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)
55 :
44>54 :2001/04/25(水) 00:11
うちの処理系ではclosureやprimtiveはdefine置き換えできますが、 ifやletみたいなsyntaxだとエラー吐いちゃうんでマクロにしてます。 Iispのfexpr型の様なlambdaがあればできそうですが。
56 :
54>55 :2001/04/25(水) 00:26
Linux上のguileとSTkではエラーになりません。 R5RSとかではどうなってるんだろう。
57 :
55>56 :2001/04/25(水) 01:54
あ、 (define もしもだよ if) がエラーになるってのは、単に↓を評価した場合 if =>error:Unbound symbol 'if これがインプリメントされてないからです。 いいかげんに作ってあるので・・(環境を返す様にすれば直る) R5RSみても良く判りませんでした(→多分マクロが返る) 「形式的シンタックス」とか、後ろの方意味不明・・(汗
あげ
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とかは何よ、って思うけど。
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など)は
*継続*という概念で定義できるみたいです。(反則的な気がしますが)
(call-with-current-continuation
75 :
デフォルトの名無しさん :2001/04/27(金) 02:11
lispって関数型っていわれるといやーん。 CLOSなんて object systemもあるんだし。 Smalltalk並みに柔軟な、自分自身に手を入れられる環境が魅力では。 と言うことで単なる schemeはあまり触ってなかったり。 仕様的に美しいのは納得するんだけどねえ。
76 :
デフォルトの名無しさん :2001/04/27(金) 02:27
77 :
74 :2001/04/27(金) 04:32
)
78 :
デフォルトの名無しさん :2001/04/27(金) 07:26
>>73 Common Lispでも普通はコンパイラが末尾再帰を処理してくれる。
コンパイルしないとスタックオーバーフローになってもコンパイルすればOKな事が多い。
call/cc>74
80 :
Be名無しさん :2001/04/27(金) 23:37
Scheme使ってる人で「計算機プログラムの構造と解釈」を読んだことある人います? これよんで感動しました。お勧めです。
81 :
デフォルトの名無しさん :2001/04/27(金) 23:55
>>76 の3番目のリンクがそれのオンラインで読めるやつだよ
>>80 英語だけど。
訳本はなかなか図書館にも置いてないなあ。
82 :
デフォルトの名無しさん :2001/04/28(土) 00:08
LispやSchemeで複数行のコメント付けるにはどうしたらいいですか? ;←しかないですか?
83 :
82 :2001/04/28(土) 00:12
あと、C言語の #ifdef __UNIX__ ; #else ; #endif の様な物は無いでしょうか。
84 :
デフォルトの名無しさん :2001/04/28(土) 01:29
>>80 というか「読んだ人が使っている」というくらい普通に読んでると思うが。
86 :
>82 :2001/04/28(土) 01:41
例えばですが、/*〜*/を解釈する様にreadを上書きするとかはできる様です。 SLIBのtrnscrpt.scmを見ていてそう思いました。
87 :
>82 :2001/04/28(土) 01:46
がんばれば#ifdef〜#endifも自分で作れるんじゃないかと思います。
>>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
91 :
デフォルトの名無しさん :2001/05/01(火) 00:47
92 :
デフォルトの名無しさん :2001/05/01(火) 01:05
初心者の質問です。 LISPって大学や研究機関、あるいは個人の趣味以外で 仕事で利用されたりしてるのでしょうか? sawfish,emacsは除いて。
93 :
89 :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を買った人いる?いくらなんだろ?
95 :
89>92 :2001/05/01(火) 01:32
わたしは残念ながら聞いたこと無いです。 LispやSchemeのコード納品する様な仕事ってどんなのでしょう(汗 cgiの部品としてperl/Pythonコードとかはある様ですが。 まあScheme->Cとか、変換ツールは結構出回ってる様なので、 元がLisp/Schemeって事例はあるかもしれません。
96 :
89 :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の辺りはよく分かりませんが、これをマクロでテンプレートにしたら
結構使えそうです。