■ 2ちゃんねるは、ここのサーバを使ってるです。。。
 .jp ドメインお持ちのお客様大歓迎。maido3.jp
 .fm 取得代行します。(US) maido3.fm
 .ca 取得代行します。(US) maido3.ca
 .com .net .org 取得代行します。(US) maido3.com
 .cc .to .tv 取得代行はじめました。NEW
人気サイト
月々1,000円からの BinboServer.com 2ちゃんねるも使っている Big-Server.com
>> 2ちゃんねる、サーバ監視所

■掲示板に戻る■ ■過去ログ倉庫めにゅーに戻る■
LISP Scheme
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の時点で中断したいんだけど、何か良い手段はありますか?


3 名前: 2 投稿日: 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版」は?


8 名前: 2 投稿日: 2001/04/14(土) 00:43
>>5
なるほど。loopをifスコープ(?)の中で書いても良かったんですね。
有難うございます。
SchemeにはC言語でいうbreak/continueとかが無いみたいなんで困ってました。
(継続使えとか言われそうですが)


9 名前: 2 投稿日: 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))))))


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
ってのが見つかったんですが、なんか難しいですね。
(まだインデントの付け方もよくわからない・・)


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
こっから色々収集できます。


16 名前: 15 投稿日: 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
>>17 と同じ人のとこ
http://www.geocities.co.jp/SiliconValley-Oakland/1680/xyzzy_lisp.html


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のソース載せます。


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))
です。


34 名前: Sage 投稿日: 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で制限してない?



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]
うーん、括弧の対応付けが判って多少は良くなったかな?
ただ、初めて見る人にとっては、「なんじゃこりゃ?」って印象でしょうね・・(汗


39 名前: デフォルトの名無しさん 投稿日: 2001/04/20(金) 23:12
スーパー括弧 [] はコードを入力するときには使うけど、
pp するときには普通の表示が良いなあ。


40 名前: 37 投稿日: 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

妻子と読むのですといいですね。



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
バランス木かどうかわかりませんが、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に直せちゃうくらい強力だが…



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みても良く判りませんでした(→多分マクロが返る)
「形式的シンタックス」とか、後ろの方意味不明・・(汗


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


77 名前: 74 投稿日: 2001/04/27(金) 04:32
)


78 名前: デフォルトの名無しさん 投稿日: 2001/04/27(金) 07:26
>>73
Common Lispでも普通はコンパイラが末尾再帰を処理してくれる。
コンパイルしないとスタックオーバーフローになってもコンパイルすればOKな事が多い。


79 名前: デフォルトの名無しさん 投稿日: 2001/04/27(金) 23:37
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
というか「読んだ人が使っている」というくらい普通に読んでると思うが。


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は除いて。


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の辺りはよく分かりませんが、これをマクロでテンプレートにしたら
結構使えそうです。


97 名前: 89 投稿日: 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の仕様では無理。)


105 名前: 104 投稿日: 2001/05/03(木) 01:23
補足
>変数や関数の
→無視
>Cの仕様では無理
→Cでも処理系依存な方法ですがスタックアドレスを取得して、
フレームをコピーすれば可能です。


106 名前: 104 投稿日: 2001/05/03(木) 01:26
つまり継続が使えるScheme独特のコードと言うことです。
(LispだとCと同様な事が起る。)


107 名前: 104 投稿日: 2001/05/03(木) 01:27
ああ、
>(LispだとCと同様な事が起る。)
これは確認したわけでは無いので違ってたらすいません。


108 名前: 104 投稿日: 2001/05/03(木) 01:33
これがあるお陰で、Lispでは専用の構文が用意されている構造体、
クラスも、Scehmeでは限られた言語仕様の中で表現できます。


109 名前: デフォルトの名無しさん 投稿日: 2001/05/03(木) 03:06
相互リンクしてみる
http://mentai.2ch.net/test/read.cgi?bbs=prog&key=963134110&ls=100


110 名前: デフォルトの名無しさん 投稿日: 2001/05/03(木) 12:55
>>108
少なくともCommon Lispならできるよ。


111 名前: 104>110 投稿日: 2001/05/03(木) 19:20
なんのことですか?
letの環境の辺りの事かな?


112 名前: 104>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


120 名前: 118 投稿日: 2001/05/04(金) 21:09
バグ
・removeはaddの逆の順番で呼ばないと、あるパターンでうまく削除されない。
また削除できても後の要素ができなくなる可能性がある。
・rehashを行なうとaddした順番が失われるので正常に削除できくなる。
よってremoveはそのままでは使えません。
removeの時に近隣の要素のhash値を調べて適当な場所に移動させていく必要があります。
(※ここで言う「適当」とは「デタラメ」の事ではない)


121 名前: 118 投稿日: 2001/05/04(金) 21:21
修正方法1
・rehashのロジックで削除要素以外を登録し直す。
→rehash分のコストが掛かる。実装は簡単。
修正方法2
>>120の「近隣の〜」を実装する。
→最悪、全ての要素を走査する必要がある。実装は面倒。

オープンアドレス法での要素の削除は、
あまり良い案が浮かびませんでした。


122 名前: 118 投稿日: 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から返されます。


141 名前: 140 投稿日: 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)))))


142 名前: 140 投稿日: 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))
    )))))


143 名前: 140 投稿日: 2001/05/07(月) 00:46
補足
・(gensym)は、環境に存在しないユニークなシンボルを生成する関数。
・*catch-handler-stack*の存在する場所は、
グローバル/ローカル環境どちらでも良い。


144 名前: 140 投稿日: 2001/05/07(月) 00:49
;;おまけ
(define-macro throw1
 (lambda (l)
  `(throw-value ,(cadr l) (cons 'prog1 ,(cddr l)))))


145 名前: 140 投稿日: 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)))
    )))))


146 名前: 140 投稿日: 2001/05/07(月) 00:58
おまけのthrow1、catch1 は、最初の評価結果を返す。


147 名前: 140 投稿日: 2001/05/07(月) 01:00
>>134-139
ネタを何か書込んでください。
>>138
少なくともわたしは使ってます。


148 名前: デフォルトの名無しさん 投稿日: 2001/05/07(月) 21:34
age


149 名前: デフォルトの名無しさん 投稿日: 2001/05/09(水) 05:21
http://www.eval-apply.com/


150 名前: デフォルトの名無しさん 投稿日: 2001/05/09(水) 23:57
http://www.call-with-current-continuation.org/


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);


156 名前: 153 投稿日: 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
古くてスマソ。「計算機プログラムの構造と解釈 第二版」
確かに名著。ただし非常に高度。読むときは本気で取り組まんとツライ。


164 名前: 159 投稿日: 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好きかも。


165 名前: 159 投稿日: 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


167 名前: 166 投稿日: 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
で拾えます。(わかってるかもしれないけど一応)


168 名前: 166 投稿日: 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))


169 名前: 166 投稿日: 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)


170 名前: 159 投稿日: 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は必ず必要だと思う。


188 名前: 184 投稿日: 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))


189 名前: 186 投稿日: 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わすれた。


190 名前: 184 投稿日: 2001/05/15(火) 23:16
>>199
なるほど、named-let->letrec->let->lambdaって風に
変換するみたいですね。手変換できるかも。ありがとうございます。
マクロはlispのdefine-macro形式ならわかるけど、
let-syntaxとかの構文はいまだに謎・・。
なんであれがschemeの標準マクロなのか不思議です。


191 名前: 184 投稿日: 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)


192 名前: 186 投稿日: 2001/05/16(水) 20:04
>>191 確かにうまくいってそうな気がする。だまされてるような気もする。
でも R5RSじゃ、やっぱり環境つくって set! してるみたいだ。
その方が素直だろ。letrecっつう関数型っぽいもので set!が出てくるのは
癪だけど。

確か R5RSの macroは hygenic(清潔?) っつーのが売りだったような。
Lispの macroだと新しく導入した symbolが既存の物とぶつかることもあるって
のが不潔なんだろうな。でも internしなきゃいい気もするが。忘れた。


193 名前: 184>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)で回避する問題を
自動でやってくれるって事ですか。
使いこなせればかなり便利そうですね。
(日本語の資料が不足ぎみ・・)


194 名前: 184> 投稿日: 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で検索)


198 名前: 133 投稿日: 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内で「マクロ生成の為だけの」コードを
書けるということなんですが。
(展開コードには余計なものは含まれません。)
これは実際に触わってみないと判らないかもしれない。


201 名前: 133 投稿日: 2001/05/19(土) 03:35
>>199
> マクロを展開してコードに直接埋め込む事ができます。(破壊操作)

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

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

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

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

とは違うのか?


202 名前: 133 投稿日: 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の部分はマクロ解釈コード。


204 名前: 133 投稿日: 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
http://www.shiro.dreamhost.com/scheme/trans/beating-the-averages-j.html


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"の様に文字列にすると、
生成するたんびにその分のメモリを消費するから、
シンボルは引用符を付けて表示させるのが良い。
シンボルなら同一性のテストが低コストで行なえるし。


214 名前: 213 投稿日: 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
http://piza.2ch.net/test/read.cgi?bbs=tech&key=989508360&st=147&to=147&nofirst=true
累算変数ってなんですか?


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 そのものが累積変数。だと思われ。


220 名前: 218 投稿日: 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内で参照できます。


227 名前: 226 投稿日: 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内部定義の場合分けを増やす事によって、柔軟な構文を許す事ができます。


228 名前: 226 投稿日: 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
 ))


229 名前: 226 投稿日: 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)
 ))


230 名前: 226 投稿日: 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
=>()


231 名前: 226 投稿日: 2001/05/23(水) 20:18
ずれちゃった・・
補足:
マクロの展開処理は普通のlispの記号処理と同程度のコストが掛かるので、
記述が長くなると不利ですが、コンパイラや直コード埋め込み、マクロキャッシュ
などを持っている処理系ならば、実行時に展開を行なう回数は0〜1回に抑える
事ができます。
(逆を言えば、これらの機能の無い処理系上ではマクロを積極的に使うことは考えられない。)


232 名前: 226 投稿日: 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))))


233 名前: 226 投稿日: 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はダミーシンボルです。
ダミーシンボル自体には意味はありませんが、
ここでは簡単な構文チェックに使用しています。


234 名前: 226 投稿日: 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
 ))


235 名前: 226 投稿日: 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だよ。


251 名前: 250 投稿日: 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はいーかげんなデータ構造簡単に作れるからいいね。
それを探索するのも簡単だし。


256 名前: 246 投稿日: 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)))))))


278 名前: 277 投稿日: 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なら、三つ目の引数は評価しないとか出来るし。


297 名前: 295 投稿日: 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
>>331

GOOPS
http://www.gnu.org/software/goops/goops.html


336 名前: デフォルトの名無しさん 投稿日: 2001/06/20(水) 23:44
SICPにデータ主導プログラミングの方法が載ってるけど
あれでは駄目ですか?>331


337 名前: 331 投稿日: 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を作りたがる傾向にある。
これも一般向けしない理由。
実装コストがあまりかからず、機能拡張が他の言語に比べて易しい。


435 名前: Perl信者 投稿日: 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が絡むと厄介だね>トランスレータ


450 名前: 439 投稿日: 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
ある程度の定石さえ知っていれば、色んな処理がお手軽に書けるから、とか。
それと、自分にフィットする様に、言語自身に手直しを加える事が簡単なんだよ。
これはライブラリを作っていく様な事とは違う達成感がある。


460 名前: 457 投稿日: 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


476 名前: 475 投稿日: 2001/07/22(日) 00:43
まちがえた
s/x/z/g


477 名前: 475 投稿日: 2001/07/22(日) 00:54
で、>>469は(let()・・・)で作成した空のフレーム環境を使って
外部ファイルをloadして、そのフレームを返すclosureを作り、
そのclosureをpkg-nameにdefineする。
そのまま475のaがフレームに変わったと思えばいい。


478 名前: 475 投稿日: 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)))) ))))


479 名前: 475 投稿日: 2001/07/22(日) 01:08
>>474
かなり前にがいしゅつっぽい


480 名前: 475 投稿日: 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
レキシカルスコープ/クロージャ
http://www.geocities.co.jp/SiliconValley-Oakland/1680/xyzzy_lisp/xyzzy25.html


499 名前: 名無λ式 投稿日: 2001/07/27(金) 05:02
>>496
わざと仰々しく書いている文章上の遊びを無視すると、
「Lisp におけるリスト用語は、これ以上分割することは不可能であり、
プログラム中においても同じ意味であり続ける。
数や `+' のようなたった一文字の記号と同じように。」

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

要するに、car, cdr, cons, nil, (, ), ドット対のドット, "cons cell"などは、
数と四則演算のように、基本的でかつ身近なもので、
carが「フィボナッチ数列を計算する関数」の名前になるなんて事はありえない、
それほどLispとLisperにとって"list"は身近なもんなんだ、ということ。


500 名前: 500! 投稿日: 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))
という風に一時変数を挟めば評価順序を自分で制御できます。


508 名前: 507 投稿日: 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) )))


509 名前: 507 投稿日: 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))
という風に展開される。


510 名前: 507 投稿日: 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) )))


511 名前: 507 投稿日: 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ありがたく使わせてもらいます。)
こういうのメタプログラミングっていうんですね。


514 名前: 507 投稿日: 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
>>518
http://siag.nu/
http://www.gnu.org/software/guile/guile.html
http://www.gimp.org/scripts.html
あたりも。


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 について質問。
というかだれかお助けを。

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

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

どなたかおねがいです。


564 名前: 562 投稿日: 2001/08/06(月) 21:04
MIT Scheme の Reference に 15.8 TCP Sockets というのが
ありましたね。

本当は UDP がしたいんだけどな。


565 名前: 563 投稿日: 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
なにげにスゲー便利だった。>関数呼出し一発ロード


573 名前: 18 投稿日: 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
JACAL
http://www.swiss.ai.mit.edu/~jaffer/JACAL.html


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
soft-scheme
http://www.intertrust.com/star/wright/code.html


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
Schemeでモナド
http://www.lh.com/~oleg/ftp/Scheme/misc.html#monadic-io


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
http://xarch.tu-graz.ac.at/autocad/lisp/FAQ-link/msg00505.html


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 を見ようね。


666 名前: 665 投稿日: 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


671 名前: 667 投稿日: 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" なんですよ。


694 名前: 639 投稿日: 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内部でも同じ様な事してるわけだけど。


707 名前: 700 投稿日: 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などが有名です。
詳しくは関数型言語スレで。


713 名前: 700 投稿日: 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
や、過去ログに載ってるような本を参照してください。


717 名前: 716 投稿日: 01/08/30 23:58 ID:rGyCxIX.
>>715じゃなくて>>713


718 名前: 716 投稿日: 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 はなんか違う気がする。


720 名前: 711 投稿日: 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というのがあるので、それで代用できると思います。


723 名前: 715 投稿日: 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は標準であるよ。


727 名前: 713 投稿日: 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


729 名前: パンティーはいたまま排便、好きな人 投稿日: 01/09/01 01:59 ID:OK9pI4Co

パンティーはいたまま排便、好きな人
パンティーはいたまま排便、好きな人
パンティーはいたまま排便、好きな人
パンティーはいたまま排便、好きな人
パンティーはいたまま排便、好きな人
パンティーはいたまま排便、好きな人
パンティーはいたまま排便、好きな人
パンティーはいたまま排便、好きな人
パンティーはいたまま排便、好きな人
パンティーはいたまま排便、好きな人
パンティーはいたまま排便、好きな人
パンティーはいたまま排便、好きな人
パンティーはいたまま排便、好きな人
パンティーはいたまま排便、好きな人
パンティーはいたまま排便、好きな人
パンティーはいたまま排便、好きな人
パンティーはいたまま排便、好きな人
パンティーはいたまま排便、好きな人
パンティーはいたまま排便、好きな人
パンティーはいたまま排便、好きな人
パンティーはいたまま排便、好きな人
パンティーはいたまま排便、好きな人
パンティーはいたまま排便、好きな人
パンティーはいたまま排便、好きな人
パンティーはいたまま排便、好きな人
パンティーはいたまま排便、好きな人
パンティーはいたまま排便、好きな人
パンティーはいたまま排便、好きな人


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がいいと思うけど。


745 名前: NIL 投稿日: 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な実装をするときに困る)
自力でできないことは無いけど
標準化されてるに超したことないし


778 名前: デフォルトの名無しさん 投稿日: 01/09/09 02:59
改行を含む文字列をCommon Lispでどうやってかくの?
リテラルで。。(リテラルとはいわないみたいだけど)

へたれな質問ですんまそ。。へたれsage。


779 名前: デフォルトの名無しさん 投稿日: 01/09/09 03:12
>>778
文字なら
#\returnまたは#\newline
文字列はそのまま改行するんでは?
"改行を含む文
字列"


780 名前: デフォルトの名無しさん 投稿日: 01/09/09 03:17
>>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
http://srfi.schemers.org/srfi-20/srfi-20.html


783 名前: デフォルトの名無しさん 投稿日: 01/09/10 03:47
http://www.cs.indiana.edu/scheme-repository/code.oop.html
http://www.cs.cmu.edu/afs/cs/project/ai-repository/ai/lang/scheme/oop/0.html


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引数以降の型も区別させたい)
良い方法ありますか?


793 名前: 792 投稿日: 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)))))

解決にはなってないけど。


798 名前: 792 投稿日: 01/09/11 07:05
色々参考になりました >>794-797
なんとか修正できそうです。
BOSは小さい割に完成されている感じがするので
しばらく使ってみようと思います。


799 名前: デフォルトの名無しさん 投稿日: 01/09/11 07:25
multi-methodをsupportしてない言語で使われる
double dispatchと呼ばれるpatternだから、検索してみれ


800 名前: 792 投稿日: 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の書式と似てるね


802 名前: 792 投稿日: 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!


814 名前: デフォルトの名無しさん 投稿日: 01/09/14 16:13
>>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)


822 名前: デフォルトの名無しさん 投稿日: 01/09/15 18:56
>>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)


825 名前: 792 810 投稿日: 01/09/16 03:47
>>811-812
あれから、メソッド毎に枝分けする様に変えてみたら多少速くなりました。
普通の関数にはまだ及びませんが。
キャッシュする方法を考えてみます。


826 名前: デフォルトの名無しさん 投稿日: 01/09/16 04:10
自分でリストを表示するルーチンを作ってるのですが、
リストが巡回構造だと判定する良い方法はありますか?


827 名前: デフォルトの名無しさん 投稿日: 01/09/16 04:12
親を順番に検索していって自身が検索されたら巡回


828 名前: デフォルトの名無しさん 投稿日: 01/09/16 04:20
>>827
やっぱりそういう地道な方法しかないですか。
ありがとうございました


829 名前: デフォルトの名無しさん 投稿日: 01/09/16 04:40
探索の手間が惜しいなら、リミッタを付けるとかすれば?>828


830 名前: デフォルトの名無しさん 投稿日: 01/09/16 05:03
(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
すきいむ


834 名前: デフォルトの名無しさん 投稿日: 01/09/16 20:08
http://eiwa.excite.co.jp/sounds/NEW_EJJE/000897200040.wav


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


839 名前: デフォルトの名無しさん 投稿日: 01/09/18 13:25
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
というのをしたかったんです。
マクロでできるかな?


842 名前: shige 投稿日: 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)
という形式を変換するマクロがあったよ。


849 名前: デフォルトの名無しさん 投稿日: 01/09/21 09:22
>>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の事を分かっていただけない人に出会ったら、
この発言をコピペしていただければ幸いです。


855 名前: デフォルトの名無しさん 投稿日: 01/09/22 16:47
>>854
早速Delギコスレにコピペされていましたよ。よかったですね。


856 名前: デフォルトの名無しさん 投稿日: 01/09/22 17:29
Rubyはクソです。ゴミ箱逝きです。

いじょ


857 名前: デフォルトの名無しさん 投稿日: 01/09/22 18:25
Smalltalk氏「Rubyはカッコがオブジェクトじゃない。全てが
オブジェクト?笑わせないでくれ。(プ」

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

Perl氏「Rubyが綺麗だって?endの羅列で汚いじゃん。(ゲラゲラ」


858 名前: デフォルトの名無しさん 投稿日: 01/09/22 18:29
Perlに汚いって言われるなんて、言語として最大の屈辱だよな(藁


859 名前: デフォルトの名無しさん 投稿日: 01/09/22 18:33
でも事実だから仕方ないよ。


860 名前: デフォルトの名無しさん 投稿日: 01/09/22 18:39
ダメ人間共がRubyを煽ってるねー。
そんな事をして楽しいのかなあ。
857なんて全然わかってないし(藁
実用性ならRuby>>>>>>>>>>>>>>>>>>>>Smalltalk,Schemeだよね。
今時SmallTalkやSchemeで何作れっていうの?(プププ


861 名前: デフォルトの名無しさん 投稿日: 01/09/22 18:40
>>854-860
きみらスレ違いなのヨ


862 名前: デフォルトの名無しさん 投稿日: 01/09/22 18:49
しかしワラタ


863 名前: 1Rubyユーザ 投稿日: 01/09/22 20:29
Schemeなんかに実用性はありません。いじょ


864 名前: デフォルトの名無しさん 投稿日: 01/09/22 20:38
>>863
ハァ?
schemeで検索してみたら?
実用例が山ほど出てくるから。


865 名前: デフォルトの名無しさん 投稿日: 01/09/22 20:39
>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プログラミングなんて出来ないでしょ。


869 名前: 1Rubyユーザ 投稿日: 01/09/22 20:45
ね。おもしろいでしょ。
ちょっと扇ってやっただけでこの反応。
マイナー言語ユーザの結束の固さ(大爆笑)には毎度ながら驚くよ。(嘲笑)


870 名前: デフォルトの名無しさん 投稿日: 01/09/22 20:45
866=867なんかに実用性はありません。いじょ


871 名前: デフォルトの名無しさん 投稿日: 01/09/22 21:02
Rubyに実用性で負けているのは事実です。
ですが、わざわざここに来て書き込む事ではないでしょう。
Rubyスレッドに戻ってください。


872 名前: デフォルトの名無しさん 投稿日: 01/09/23 01:03
868みたいなのはRuby使ってもScheme使っても
「DB」なんていじれないし、「GUIプログラミング」とやらもできないだろうな。


873 名前: デフォルトの名無しさん 投稿日: 01/09/23 03:11
なんだ?
なんでruby厨房がこんなところに?


874 名前: デフォルトの名無しさん 投稿日: 01/09/23 05:06
>>848
そのサイトってなんか色々あるね


875 名前: まじれっさ 投稿日: 01/09/23 05:51
>>867
scheme も ruby も、他に意味を持った単語なんだから
検索して出てくるものすべてが、プログラミング言語である scheme や ruby
を指しているわけじゃないので、それってちょっと意味無いと思うよ。


876 名前: ruby 投稿日: 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


887 名前: デフォルトの名無しさん 投稿日: 01/09/27 13:27
slibというものを落としてみましたがどういうものかさっぱり分かりません。


888 名前: デフォルトの名無しさん 投稿日: 01/09/27 20:40
>>887
じゃあなんで落としたの?


889 名前: 887 投稿日: 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))
こういうのが欲しい。可能?


897 名前: デフォルトの名無しさん 投稿日: 01/10/02 22:04
>>896
どうしてわざわざくっつけたいの?


898 名前: デフォルトの名無しさん 投稿日: 01/10/02 23:45
>896
マクロでできる。
本気で考えてるなら、リーダーを自分で作るとかした方が良い。


899 名前: デフォルトの名無しさん 投稿日: 01/10/03 00:35
>>898
できたとしても、適用できる範囲が狭そうだから無駄な労力に
なるかも・・・


900 名前: デフォルトの名無しさん 投稿日: 01/10/03 00:47
\\\     \ \\
   \\ヾ__ ∧_∧_ヾ\
\   \ \ (*´∀`)_\ \
\\     | ̄ ̄∧∧  |  ヾ
\\\ ヾ   |\ ミ;゚Д゚ ∧_∧
  \\\      | ̄ ̄ ( *・∀・) 今だ!900番ゲットォォォォ!!!
   \\\ ヾ  |\ ̄/っ y っ\
     \\       |  ̄ ̄ ̄ ̄ ̄ |


901 名前: デフォ 投稿日: 01/10/03 03:45
SICPをチョット前から読み始めて、同時にSchemeも始めたのですが…
今更になって、今まで使ってたS式自体がリストだって事に気づいた
すごいね…の一言

SICPでは、継続とかマクロとか出てこないみたいなんですけど、
知ったら、やっぱり、すごいと感じるのでしょうか?


902 名前: デフォルトの名無しさん 投稿日: 01/10/03 05:15
> 今まで使ってたS式自体がリストだって事に気づいた

すまん。どうすごいんだ?


903 名前: デフォルトの名無しさん 投稿日: 01/10/03 05:24
すごいよ。マクロのおかげでいろんなことが出来る。
様々なことが出来ることこそが、SchemeがC++やJavaなどより
圧倒的に強力な所以。


904 名前: デフォルトの名無しさん 投稿日: 01/10/03 16:25
>>893
Windowsならコンパイラがほしい。
UNIXだとインタプリタで十分だと思うんだけど
(速さを求めなければそれで良いから、perl,pyhton,rubyのアプリも沢山ある)、
Windowsで何か作って配布でもしようとすると(私がそうするというわけではなく)、
どうしてもコンパイラ言語になる、ということが多いと思う。


905 名前: デフォルトの名無しさん 投稿日: 01/10/03 19:22
>>904
バイトコードっつーか、実行するコードをメモリイメージにしといて、
1つのEXE作るってのはやった事あります。
(コンパイラと名乗れるほど高級じゃなかった。)
そのイメージを適当に圧縮しとけば、まあEXE覗かれたとしても
普通の人はわかんないし。w
そのEXEは、まんまLISPエンジンが載ってるので、
当然ながら外部のLISPコードも読みこめます。

SchemeだとSIODって処理系がたしかEXEつくってくれたんじゃないかと思います。


906 名前: 905 投稿日: 01/10/03 19:25
これです
http://people.delphi.com/gjc/winsiod.html


907 名前: 904 投稿日: 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でやったら、変数宣言して代入して計算してその結果を代入しなおしてその変数を計算して...となる。


911 名前: デフォルトの名無しさん 投稿日: 01/10/03 23:28
>>910
君、なんか違うよ。


912 名前: デフォルトの名無しさん 投稿日: 01/10/03 23:31
>>910
なるほど


913 名前: デフォルトの名無しさん 投稿日: 01/10/03 23:33
>>912
違うってば…


914 名前: デフォルトの名無しさん 投稿日: 01/10/03 23:39
>>908
lisp = 人工知能じゃないです
どのへんも糞もありません

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

>>909
マクロとかで便利


915 名前: デフォルトの名無しさん 投稿日: 01/10/04 01:45
>>914
lispて人工知能言語だってよく聞くけど、それはなぜ?
人工知能とどういうふうに関係あるのか聞きたいです。
煽りではなくマジレスで。


916 名前: 914 投稿日: 01/10/04 02:01
あ、どのへんが人工知能言語?って話ね。
えーと、なんで人工知能の研究に使われてた(る)んだろうねぇ?
正直、よく知らないです。
記号処理が人工知能研究に向いてるとかでしょうか?

フォローしてくれ > 識者様


917 名前: デフォルトの名無しさん 投稿日: 01/10/04 02:05
人工知能だとか、そういう研究的なことは、普通
のプログラムに比べて極端に難しくて複雑な考え方を
使うわけよ。
だから、言語として一番柔軟性があって記述力のある
Lispが主流ってこと。


918 名前: デフォルトの名無しさん 投稿日: 01/10/04 02:11
>>916
LISPを設計したJ・マッカーシーが人工知能やってたからじゃないの?
一応、マッカーシーは人工知能向けに考えて作ったとの話。
詳細はジョン・マッカーシーで検索
あと、スタンフォード大学にマッカーシーのWebサイトがあったはず。


919 名前: デフォルトの名無しさん 投稿日: 01/10/04 02:26
>>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
ところでこの本はいったいなんですか?サスマンの本なのですが


922 名前: デフォルトの名無しさん 投稿日: 01/10/04 08:08
まあ自分で自分を拡張してゆくというか
自分で自分のプロうグラムを書き換えてるような所が
昔は人工知能への近道に思えたんでしょうね


923 名前: デフォルトの名無しさん 投稿日: 01/10/04 09:39
>>903
うーん、>>896はまだそこに気づいてないんだな。
S式はsimpleだから便利で強力なんだ。(, ), car, cdr, cons, null, これだけ。

単純な事が力になる、これはよくあることだな。The Internetのbest effort deliverとかさ。


924 名前: デフォルトの名無しさん 投稿日: 01/10/04 17:42
普通は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もよろしく.


930 名前: デフォルトの名無しさん 投稿日: 01/10/05 13:36
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 でステップ実行したらえらいことになった。


933 名前: Ruby! 投稿日: 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
>>935
ごめん... 詳しくはこれ...

ftp://publications.ai.mit.edu/ai-publications/pdf/AIM-349.pdf


937 名前: デフォルトの名無しさん 投稿日: 01/10/06 11:52
板違いだけど、pdfをテキストかhtmlに変換して
英和翻訳してくれるサイトってありませんか?


938 名前: デフォルトの名無しさん 投稿日: 01/10/06 11:55
英語読めないのか...(プ


939 名前: デフォルトの名無しさん 投稿日: 01/10/06 14:14
>>938
ごめんよ(w
英語はまあ、翻訳サイトあるからいいけど、pdfが通らない。


940 名前: デフォルトの名無しさん 投稿日: 01/10/06 14:20
>>938
あ、よかったら要約してちょ(はぁと


941 名前: 無名λ式 投稿日: 01/10/06 14:20
ほい>>937
http://www-6.ibm.com/jp/software/internet/king/download.html


942 名前: デフォルトの名無しさん 投稿日: 01/10/06 14:24
>>941
すいません。
うちの環境がクソすぎて、ソフトはもういれらんないのです。
これ以上はスレの迷惑になるので諦らめます。
他の方法を模索します。(パソコン買い替えるなど)
ご迷惑お掛けしました。


943 名前: デフォルトの名無しさん 投稿日: 01/10/06 18:28
以前 bitに Sussmanさんだかに Schemeの生い立ちのインタビュー記事が
ありました。2ヶ月にわたって載ってた。
何年何月号だったかわ今はわかりませんけど、そこに >>935 さんの言って
たような事が書いてありましたよ。
デッカクなる前の bit だったと思います。


944 名前: 943 投稿日: 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)
てどっちが速いの?


954 名前: デフォルトの名無しさん 投稿日: 01/10/08 17:18
>>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)って無かったっけ。


958 名前: デフォルトの名無しさん 投稿日: 01/10/09 00:18
>>957
!!!ありがとうございます!!!
これを知らずに何日苦労したことか・・・


959 名前: デフォルトの名無しさん 投稿日: 01/10/09 01:08
>>958
Ctrl-D(=端末からのEOF)でもOK。


960 名前: デフォルトの名無しさん 投稿日: 01/10/09 04:44
そろそろ次スレ立てて欲しいところなんだけど、
その前にリンクの整理と参考書籍をまとめようよ!


961 名前: デフォルトの名無しさん 投稿日: 01/10/09 08:40
>>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
SICPへのリンクは?

http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-4.html#%25_toc_start


965 名前: デフォルトの名無しさん 投稿日: 01/10/09 17:45
すいません、検索結果へ直接は飛べないみたいです。
ごめんなさい。


966 名前: デフォルトの名無しさん 投稿日: 01/10/09 19:30
>>963
Web で読めるよ


967 名前: デフォルトの名無しさん 投稿日: 01/10/09 19:30
>>966
http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-4.html#%_toc_start


968 名前: 964 投稿日: 01/10/09 19:35
>>967

俺の書いたのと何が違うんだ?まあいいけど。


969 名前: Part2の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
>>978


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) ふにゃふにゃ)

で可変個引数にしてもいいです。


984 名前: Lisp板の753 投稿日: 01/10/11 22:41
>>983さん
Thanx
今問題のソースPLT Schemeに移植してますがてんとう虫が出まくってます。
あと もし関数に渡す引数が評価されては、まずい場合はどうなんでしょうか?


985 名前: デフォルトの名無しさん 投稿日: 01/10/11 22:54
>>984
だから、マクロで全部解決するって・・


986 名前: Lisp板の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
ありがとうございます


992 名前: Ruby戦隊 投稿日: 01/10/12 00:38
Ruby >>>>>>>>> Scheme


993 名前: Ruby戦隊 投稿日: 01/10/12 00:39
             
Ruby >>>>>>>> Scheme


994 名前: ruby! 投稿日: 01/10/12 00:39
Ruby!!!!!!!!


995 名前: Ruby! 投稿日: 01/10/12 00:40
るびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびー
るびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびー
るびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびー
るびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびー
るびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびー
るびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびー
るびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびー


996 名前: ああああああああ 投稿日: 01/10/12 00:41
                         
るびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびー
るびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびー
るびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびー
るびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびー
るびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびー
るびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびー
るびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびー


997 名前: Ruby戦隊 投稿日: 01/10/12 00:42
                        
るびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびー
るびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびー
るびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびー
るびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびー
るびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびー
るびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびー
るびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびー


998 名前: __ruby!__ 投稿日: 01/10/12 00:43
_______________                       
るびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびー
るびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびー
るびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびー
るびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびー
るびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびー
るびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびー
るびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびー


999 名前: __RUBY__ 投稿日: 01/10/12 00:43
^^^^^^^^^^^^_______________                      
るびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびー
るびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびー
るびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびー
るびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびー
るびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびー
るびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびー
るびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびーるびー


1000 名前: 1000! 投稿日: 01/10/12 00:43
Ruby >>>>>>> Scheme


1001 名前: 1001 投稿日: Over 1000 Thread
このスレッドは1000を超えました。
もう書けないので、新しいスレッドを立ててくださいです。。。



2ちゃんねるは、ここのサーバを使ってるです。。。