1 名前:デフォルトの名無しさん mailto:sage [2009/01/13(火) 23:16:33 ] ※ ここはCommon Lisp、SchemeをはじめとするLisp族全般のスレです ※ Part24: ttp://pc11.2ch.net/test/read.cgi/tech/1224939205/ Part23: ttp://pc11.2ch.net/test/read.cgi/tech/1215875388/ Part22: ttp://pc11.2ch.net/test/read.cgi/tech/1211381920/ Part21: ttp://pc11.2ch.net/test/read.cgi/tech/1207300697/ Part20: ttp://pc11.2ch.net/test/read.cgi/tech/1205021786/ Part19: ttp://pc11.2ch.net/test/read.cgi/tech/1200237296/ Part18: ttp://pc11.2ch.net/test/read.cgi/tech/1186922295/ Part17: ttp://pc11.2ch.net/test/read.cgi/tech/1177065699/ Part16: ttp://pc11.2ch.net/test/read.cgi/tech/1172404795/ Part15: ttp://pc10.2ch.net/test/read.cgi/tech/1151025773/ Part14: ttp://pc8.2ch.net/test/read.cgi/tech/1132275726/ Part13: ttp://pc8.2ch.net/test/read.cgi/tech/1115901841/ Part12: ttp://pc8.2ch.net/test/read.cgi/tech/1100229366/ Part11: ttp://pc5.2ch.net/test/read.cgi/tech/1091456033/ Part10: ttp://pc5.2ch.net/test/read.cgi/tech/1075630259/ Part09: ttp://pc2.2ch.net/test/read.cgi/tech/1069594582/ Part08: ttp://pc5.2ch.net/tech/kako/1058/10582/1058263391.html Part07: ttp://pc5.2ch.net/tech/kako/1042/10421/1042167213.html Part06: ttp://pc3.2ch.net/tech/kako/1031/10315/1031560687.html Part05: ttp://pc3.2ch.net/tech/kako/1023/10230/1023091882.html Part04: ttp://pc.2ch.net/tech/kako/1016/10162/1016211619.html Part03: ttp://pc.2ch.net/tech/kako/1008/10082/1008220265.html Part02: ttp://pc.2ch.net/tech/kako/1002/10025/1002584344.html Part01: ttp://piza2.2ch.net/tech/kako/987/987169286.html
438 名前:デフォルトの名無しさん mailto:sage [2009/03/05(木) 02:50:43 ] schemeのシンボルは文字列に毛の生えた特殊オブジェクトと思えばよろし。 プログラム内でそのシンボルに何が束縛されているかとは基本的に全く関係ない。
439 名前:デフォルトの名無しさん mailto:sage [2009/03/05(木) 07:25:51 ] R5RS の eval だと、その時点の環境での評価ができないから symbol-function の代わりにはできないし。
440 名前:デフォルトの名無しさん mailto:sage [2009/03/05(木) 12:06:53 ] あくまでも、定義中の名前はシンボルではなくただの変数の入れ物の 名前として使われる。また、プログラムを実行するには変数の位置を 表現できれば名前のような冗長な情報は必要ない。 よって名前は実行前のある時点でアドレスに変換されていると考えるべき。 evalやCLのsymbol-functionみたいな実行時にシンボルからその位置情報へ 変換する仕組みを作るとなると、処理系のインタプリタやコンパイラ相当を 必要時に起動するのと全く事になり、非常に馬鹿げたコストが掛かる。
441 名前:デフォルトの名無しさん mailto:sage [2009/03/05(木) 12:13:45 ] >>436 evalはともかくquoteはこの件と関係ない
442 名前:デフォルトの名無しさん mailto:sage [2009/03/05(木) 13:16:24 ] >>440 文章として突っ込みどころ多すぎw 内容的にも、後段のsymbol-functionについては、 特殊オペレータのfunctionと勘違いしているとしか思えない。 (defun foo () (print 'foo)) (flet ((foo () (print 'foolet))) (foo) (funcall (function foo)) (funcall (symbol-function 'foo)))) FOOLET FOOLET FOO
443 名前:デフォルトの名無しさん mailto:sage [2009/03/07(土) 12:49:38 ] 急に流れが止まったから釣りかと思ったが やっと>>422 の言っていることがわかった symbol-functionってグローバルな関数定義しか参照しないんだな
444 名前:デフォルトの名無しさん mailto:sage [2009/03/07(土) 13:48:24 ] schemeにシンボルが無いってことが少し分かってきた やっぱ Common Lisp 最強だな!
445 名前:デフォルトの名無しさん mailto:sage [2009/03/07(土) 14:16:03 ] >>442 (let ((foo #'(lambda () (print 'fooval)))) (flet ((foo () (print 'foolet))) (foo) (funcall foo) (funcall 'foo) (funcall (function foo)) (funcall (symbol-function 'foo)))) FOOLET FOOVAL FOO FOOLET FOO Common Lispは、symbol-valueとsymbol-functionが シンボルセル内の別スロット。 funcallは>>440 の後段のような処理は、 functionに任せて、関数呼び出しに専念する仕様。 funcallの第一引数は関数か、シンボル。 シンボルの場合symbol-functionの結果を使う。
446 名前:デフォルトの名無しさん mailto:sage [2009/03/07(土) 16:10:34 ] 何が真実なのかさっぱりわからんのでまとめてみたら カオスになった。つっこみ希望 ・evalは静的スコープにはふさわしくない 動的スコープなら1つしか環境を考えなくて良いためと想像 ・schemeのシンボルは文字列に毛の生えた特殊オブジェクト ・呼び出し (hoge)はレキシカルな環境での関数呼び出し(関数セル) (funcall hoge)はレキシカルな環境での関数呼び出し(値セル) (funcall 'hoge)は↓と同様。symbol-functionを使うため (funcall (symbol-function 'hoge))はグローバルに定義されたシンボルの関数呼び出し(関数セル) (funcall (function hoge))はレキシカルな環境での関数呼び出し(関数セル) レキシカル環境で同名の変数がある場合に グローバルなシンボルのsymbol-value(値セル)を参照する方法はなさそう >>442 氏の440へのコメント ここのあたりが一番わからない symbol-functionは(トップレベル変数が動的スコープのため) 動的スコープを参照出来る →functionのようにレキシカルスコープの変数を考慮しなくてよい →symbol-functionに関してはevalもそんなにコストかからんぜ、ってこと?
447 名前:デフォルトの名無しさん mailto:sage [2009/03/07(土) 17:43:08 ] >>446 442,445はCommon Lispのコードっていうのは分かってる? > ・evalは静的スコープにはふさわしくない これは俺も何が言いたいのかさっぱりわからんというか、 はっきり言って間違い。反証はScheme。
448 名前:デフォルトの名無しさん mailto:sage [2009/03/07(土) 19:15:47 ] > evalは静的スコープにはふさわしくない はLisp1.5世代の人の意見なのかな。
449 名前:デフォルトの名無しさん mailto:sage [2009/03/07(土) 20:28:14 ] 現在のevalはLispらしさを演出するためだけの存在だからな
450 名前:デフォルトの名無しさん mailto:sage [2009/03/07(土) 21:07:27 ] evalを使うってのは、速度的にも不利になるし、普通にlispでプログラムを組む人は 避けるところだと思うよ。避けないとすれば腕の悪い人という印象しかないな。少な くとも他の方法を探すだろう。
451 名前:デフォルトの名無しさん mailto:sage [2009/03/08(日) 10:41:58 ] 大抵マクロでおkだからな
452 名前:デフォルトの名無しさん mailto:sage [2009/03/08(日) 15:39:34 ] Qiは データ [] program () のカッコをわけたらlispの意味ないとは思わなかったんだろうか
453 名前:デフォルトの名無しさん mailto:sage [2009/03/08(日) 16:21:06 ] >>451 マクロでできることはevalでもできるみたいな言い方だな 第一印象はそんなものだろうけど それをいつまでも引きずっていていいのかな?
454 名前:デフォルトの名無しさん mailto:sage [2009/03/08(日) 16:40:18 ] 451じゃないけど違うの?
455 名前:デフォルトの名無しさん mailto:sage [2009/03/08(日) 16:49:10 ] Lispのマクロ機能はevalで実装されていると思うのだが・・・
456 名前:デフォルトの名無しさん mailto:sage [2009/03/08(日) 17:11:36 ] codepad.org/kiclBi61
457 名前:デフォルトの名無しさん mailto:sage [2009/03/08(日) 18:36:31 ] (display (eval (let1 'y 2 `(+ ,x y)))) これで動くよ 何が言いたいのかわからんが
458 名前:デフォルトの名無しさん mailto:sage [2009/03/08(日) 19:00:31 ] 言いたいことは >>443 >symbol-functionってグローバルな関数定義しか参照しないんだな と同じことがevalにも言えるということ。 evalは外側のローカル変数xの定義を参照できないから >>457 では、事前にxのところを値で置き換えたものをevalに渡している。
459 名前:デフォルトの名無しさん mailto:sage [2009/03/08(日) 19:58:27 ] つーかevalは他のローカル変数のことなんか知らんから。 関数の引数として渡されたコンテクストで評価するしかない。 それを知らせる手段として(current-environment)みたいなものが 処理系にあればやりたいことは実現できるんじゃないか。
460 名前:デフォルトの名無しさん mailto:sage [2009/03/08(日) 20:13:48 ] Schemeのevalの話? Common Lispでは、 (defvar x 1) (print (eval '(+ x x))) 2 (let ((x 10)) (print (eval '(+ x x)))) 20 Schemeのevalは渡された環境への変更に制限もあるよね。 ;; R5RSとR6RSで少し違う
461 名前:デフォルトの名無しさん mailto:sage [2009/03/08(日) 21:10:14 ] (let ((x 10)) (print (eval '(+ x x)))) *** - EVAL: variable X has no value
462 名前:デフォルトの名無しさん mailto:sage [2009/03/08(日) 21:15:34 ] >>460 が一見意図通り動いてるように見えるのは 最初のdefvarでxをスペシャル変数にしてるから。 schemeで同じことをする場合はfluid-letを使う。 (define x 1) (display (eval '(+ x x))) 2 (fluid-let ((x 10)) (display (eval '(+ x x)))) 20 x 1
463 名前:デフォルトの名無しさん mailto:sage [2009/03/09(月) 08:01:39 ] mzschemeで、CGIをPOSTメソッドで使いたいのですが(クライアント側)、うまくいきません。 たとえば、 en.wikipedia.org/w/api.php?action=query&meta=siteinfo&siprop=namespaces と同じことをしたいのですが(これはGETメソッド)、 (let* ((url (string->url "en.wikipedia.org/w/api.php ")) (post (string->bytes/utf-8 "action=query&meta=siteinfo&siprop=namespaces")) (port (post-pure-port url post)) (xml (read-string 1000 port)) ) xml) でいけると思ったのですが、エラーメッセージが帰ってきます。 どこがまずいのでしょうか?
464 名前:デフォルトの名無しさん mailto:sage [2009/03/09(月) 08:57:46 ] コンビネータパーサを作ったから せっかくなのでR5RSかR6RS準拠のパーサを書いてみようと思ったんだが 全体のBNFのリストってどこかにまとまってる? 仕様書をざっと見した感じでは、 ばらばらにちょっとずつBNFが載っているように感じるんだが 仕様書ってのはこんな感じのもん?
465 名前:デフォルトの名無しさん mailto:sage [2009/03/09(月) 09:02:30 ] Schemeの仕様書はこんな感じのもん。 まぁLispでBNFもくそもないが。
466 名前:デフォルトの名無しさん mailto:sage [2009/03/09(月) 17:51:26 ] Lisp系言語の場合、構文のフォーマルな定義がBNFとはちょっと合わない。書けなくはないけれど。 構文の定義はこんな感じのレイヤになってる。 (1)まずtokenに分解 (R6RSの用語ではlexical syntax) (2)S式として読み込み (R6RSの用語ではdatum syntax) (3)S式の中の特定の構造をプログラムの構文として認識 (R6RSの用語ではprogram syntax) このうち、(2)の出力は既に抽象的な木構造のデータなんで、(3)のレベルの構文定義っていうのは 木構造に対する定義になる。もちろん木構造にマッチする文法を書けばいいんだけど。 プログラムの字面に対するBNFとは違ってくるな。 例えば、"(if x y z)" と"(if . (x . (y . (z))))" は字面では違うけどdatum syntaxとして 読まれた後は全く同じ木構造になる。program syntaxはその木構造だけを見る。
467 名前:デフォルトの名無しさん mailto:sage [2009/03/09(月) 18:22:02 ] コンビネタ・パーザだとレキサも一体で書くスタイルが多い。 >>466 で言うと(1)と(2)が一体。 ただ演算子多重定義出来る言語じゃないと、 見た目がシンプルにならない。
468 名前:デフォルトの名無しさん mailto:sage [2009/03/09(月) 20:48:06 ] >>467 それは知ってるんだが、要点はそこじゃなくて(2)と(3)が分離してるってとこ。仕様からして。 >>464 は言語構文のBNF定義がまとまってないってことに違和感を覚えたわけだろ。 (1)-(3)までまとめて書くことはできると思うがきれいになるかな?
469 名前:デフォルトの名無しさん mailto:sage [2009/03/09(月) 21:39:11 ] (3)は、R5RSとR6RSでちょっと違うし、 内部表現的には変える必要ない上に、 read/evalの分離構造ともマッチしているから、 あえて混ぜる必要はないと思う。 >>449 そういえばEuLispにはevalがなかったな。 おもしろい試みだったけどあっさりと廃れたね。 YooTooはまだ更新されているみたいだけど。 R6RSのmoduleも一部影響受けてるね。
470 名前:デフォルトの名無しさん mailto:sage [2009/03/10(火) 06:01:07 ] >>463 ですが、自己解決しました。 このコードで動きます。 (let* ((url (string->url "en.wikipedia.org/w/api.php ")) (post (string->bytes/utf-8 "action=query&meta=siteinfo&siprop=namespaces&format=xml")) (header '("User-Agent: MzScheme" "Accept: application/xml" "Accept-Encoding: deflate" "Accept-Charset: utf-8" "Content-Type: application/x-www-form-urlencoded")) (port (post-pure-port url post header)) (xml (read-string 1000 port))) xml) すくなくともen.wikipedia.orgのサーバーは、Content-Typeを指定しないとCGIだと認識してくれないようです。
471 名前:デフォルトの名無しさん mailto:sage [2009/03/10(火) 23:41:18 ] >>465-469 ありがとう。こういうもんか 特に466の説明はとてもわかりやすい。 R5RSのほうはBNFついてそうだから こっちやってみよかな しかし、PDFって扱いにくいわ <hoge>って表記をテキストでコピペするとhhogeiになるし <で検索できんから不便
472 名前:デフォルトの名無しさん mailto:sage [2009/03/11(水) 05:03:58 ] ファイルの basenameを取得する関数ってありますか? "foo.txt" -> "foo" "foo.bar.txt -> "foo.bar" といった風に取得したいのですが 自分で書くなら 一文字ずつ後ろから文字比較して . が来るまで探して その部分を削除。とするんですが もし既にあるなら書くのも悲しいので どなたかご存知ありませんか?
473 名前:デフォルトの名無しさん mailto:sage [2009/03/11(水) 05:37:46 ] (pregexp-replace "(.*)\\.[^.]+" "foo.bar.txt" "\\1")
474 名前:デフォルトの名無しさん mailto:sage [2009/03/11(水) 05:49:52 ] pathname-name www.lispworks.com/documentation/HyperSpec/Body/f_pn_hos.htm
475 名前:デフォルトの名無しさん mailto:sage [2009/03/11(水) 06:47:07 ] >>473-474 レスありがとうございます。 環境を書いていませんでした申し訳ありません。 R5RSで行うにはどうすれば良いでしょうか?
476 名前:デフォルトの名無しさん mailto:sage [2009/03/11(水) 07:39:05 ] R5RSにそんな高レベルな標準関数ないと思う
477 名前:デフォルトの名無しさん mailto:sage [2009/03/11(水) 08:52:04 ] R5RSで動く出来合いのライブラリが欲しいってことかね
478 名前:472 mailto:sage [2009/03/11(水) 09:17:26 ] >>476-477 ありませんか…。 仕方がないので自分で書いてみました。 もうちょっとすっきり書けないもんかと思うんですが 今の自分にはこれが限界でした。 (define (chop str) (substring str 0 (- (string-length str) 1))) (define (basename str) (if (string? (basename-if-thereis str)) (basename-if-thereis str) str)) (define (basename-if-thereis str) (cond ((= (string-length str) 0) #f) ((eqv? (string-ref str (- (string-length str) 1)) #\.) (chop str)) (#t (basename-if-thereis (chop str)))))
479 名前:デフォルトの名無しさん [2009/03/11(水) 11:47:54 ] >>472 SRFI 13 使えばいいんじゃね (let ((i (string-index-right s #¥.))) (if i (substring s 0 i) s))
480 名前:デフォルトの名無しさん mailto:sage [2009/03/11(水) 14:19:19 ] basenameの本質って拡張子を省くことじゃなくてディレクトリパスの削除じゃないのかな? (my-basename "foo.txt") => "foo.txt" (my-basename "foo.txt" #t) => "foo" (my-basename "/foo/bar.txt") => "bar.txt" みたいな 472の例はgaucheではpath-sans-extensionという手続きが割り当てられている
481 名前:デフォルトの名無しさん mailto:sage [2009/03/11(水) 15:07:51 ] クラススロットを辞書のように自由に登録したいのですが、 何かいい方法はありませんか? 例えば、 (define-class <test> () (())) というクラスから (define foo (make <test> :xxx 0 :yyy 10)) (ref foo 'xxx) -> 0 (ref foo 'yyy) -> 10 を可能にしたいのです。
482 名前:デフォルトの名無しさん mailto:sage [2009/03/11(水) 16:09:20 ] >>481 処理系は?
483 名前:デフォルトの名無しさん mailto:sage [2009/03/11(水) 16:16:34 ] >>482 gaucheです
484 名前:デフォルトの名無しさん mailto:sage [2009/03/11(水) 18:23:09 ] 簡単にやるならこんな感じかな (use gauche.sequence) (use util.list) (define-class <test> () (%slots)) (define-method initialize ((self <test>) initargs) (next-method) (slot-set! self '%slots (map (lambda (x) (cons (string->symbol (keyword->string (car x))) (cadr x))) (slices initargs 2)))) (define-method ref ((self <test>) slot) (assq-ref (slot-ref self '%slots) slot)) (define-method (setter ref) ((self <test>) slot val) (assq-set! (slot-ref self '%slots) slot val)) ほんとうのスロットのようにふるまわせたいならMOP使わないとだめかも。
485 名前:デフォルトの名無しさん mailto:sage [2009/03/11(水) 19:37:09 ] >>484 それだとクラス内に辞書を確保して、 setterとgetterをスロット操作のようにエミュレートするってことですね。 なるほど〜 ありがとうございます。 ところで、Gauche本やリファレンスを見てもMOPの使い方がいまいち分からないのですが、 MOPを使うとどのようなソースになるのでしょうか? よかったら教えてください。 よろしくお願いします。
486 名前:472 mailto:sage [2009/03/11(水) 22:12:20 ] >>479 こういうライブラリがあるんですね、紹介ありがとうございます。 ただ、これだけのためにライブラリ入れるのも何なんで もう少し難しい文字列処理が必要になったら入れることにします。 >>480 そうですね、確かに言われてみれば。 名前は変えることにします。
487 名前:デフォルトの名無しさん mailto:sage [2009/03/12(木) 01:34:42 ] コンビネータの勉強がしたいんですが (expand S)とすると (fun x (fun y (fun z ((x z) (y z))))) が返ってくるような関数orマクロを作ろうとしたら 実質インタプリタを作るようなもんでしょうか? もし楽な方法(特定の処理系の拡張機能etc)等があるのであれば知りたいです
488 名前:デフォルトの名無しさん [2009/03/12(木) 08:19:24 ] lispな方はバージョン管理は何を使ってますか? git svn cvs
489 名前:デフォルトの名無しさん [2009/03/12(木) 08:23:19 ] >>488 darcs
490 名前:デフォルトの名無しさん mailto:sage [2009/03/12(木) 08:28:28 ] mercurial, git
491 名前:デフォルトの名無しさん mailto:sage [2009/03/12(木) 09:14:18 ] Bazaar
492 名前:デフォルトの名無しさん mailto:sage [2009/03/12(木) 11:02:23 ] 質問します。 組合せ問題、経路問題などの、記号処理問題をリストを使って解決するのに 相応しい言語を教えてください。 環境はできるだけ特定のOSに限定されない方が結構です。 グラフ表示は別の専門家が扱うのでロジック部分のみです。
493 名前:492 mailto:sage [2009/03/12(木) 11:15:29 ] すみません。誤爆です。"初心者のためのプログラミング言語ガイド Part14"に書き込む つもりでした。直前にこのスレを確認していたのでpasteされたURLがここになって いました。 このスレの方々は それはSchemeだ! っておしゃいますよねw
494 名前:デフォルトの名無しさん mailto:sage [2009/03/12(木) 11:16:25 ] cl-graph boost::graph
495 名前:デフォルトの名無しさん mailto:sage [2009/03/12(木) 11:54:50 ] >>492 「リストを使って解決するのに相応しい」って、その質問がすでにLISPを想定しているとしか。その名も、LISt Processer。 昔は人工知能を書くために使われていたので、ターゲット分野的にもぴったり。 LISPをはずすなら、Haskellかなぁ。 ただ、Haskellはマルチバイト文字の処理周りが痛いらしい。
496 名前:デフォルトの名無しさん mailto:sage [2009/03/12(木) 12:03:13 ] >>485 Gauche特有の話だし、wilikiででも質問してみたら?
497 名前:デフォルトの名無しさん mailto:sage [2009/03/12(木) 16:25:52 ] ものまね鳥をまねる、14000円つけてるなw 今図書館で借りっぱなしで催促の電話が何度もかかってる。 忙しくて読めなかったんです。 この場を借りて予約入れてる人に謝るよ。
498 名前:デフォルトの名無しさん mailto:sage [2009/03/12(木) 16:33:29 ] lispのラーメンタイマーだよ (require :pythononlisp) (py::py "import noodletimer;noodletimer.noodletimer")
499 名前:デフォルトの名無しさん mailto:sage [2009/03/12(木) 16:43:28 ] QiはQiからlispよぶのは簡単なのに Qiをdumpしてlispから呼ばせるにはコードいじれって書いてある 自動でできないものなんだろうか
500 名前:デフォルトの名無しさん mailto:sage [2009/03/14(土) 03:25:49 ] lispは、カッコばかりでみづらいとよく言われるけど これは、慣れだね 生産効率性については、まだよくわからないけど
501 名前:デフォルトの名無しさん mailto:sage [2009/03/14(土) 05:23:24 ] 入門者レベルなんですが、lambdaを使わないと書けないんでしょうか 練習問題 1 次の関数を再帰を使って書いてください。 3. リスト (ls) から要素 (x) を取り除いたリストを返す関数。 ; 3 模範解答 (define (remove x ls) (if (null? ls) '() (let ((h (car ls))) ((if (eqv? x h) (lambda (y) y) (lambda (y) (cons h y))) (remove x (cdr ls))))))
502 名前:デフォルトの名無しさん mailto:sage [2009/03/14(土) 06:56:30 ] >>501 (define (remove x ls) (cond ((eq? x (car ls)) (cdr ls)) (else (cons (car ls) (remove x (cdr ls))))))
503 名前:502 mailto:sage [2009/03/14(土) 08:50:42 ] Σ(゚д゚) ls の中に x が二回以上出る場合はこうだ。 (define (remove x ls) (cond ((null? ls) '()) ((eq? x (car ls)) (remove x (cdr ls))) (else (cons (car ls) (remove x (cdr ls))))))
504 名前:デフォルトの名無しさん mailto:sage [2009/03/14(土) 08:58:47 ] >>502 突っ込もうと思っていました 最初のは、(remove 5 '(1 2 3 2))でもコケますね ヒントで実装までできました ありがとうございました
505 名前:デフォルトの名無しさん mailto:sage [2009/03/14(土) 19:18:21 ] これ読んでいるとlispのほうが良さそうにみえるね www.unixuser.org/~euske/doc/python/python-lisp-j.html
506 名前:デフォルトの名無しさん mailto:sage [2009/03/14(土) 20:54:29 ] Schemeでスタックを書こうとした場合 スタックのデータはグローバル変数に置くのが普通ですか? 出来たらクロージャとかに閉じ込めたいのですが 引数を2個にして1個目でpush/pop判断だとpopの時は引数が一つ無駄だし 個別にクロージャを使うと環境が別々になるし。 Gaucheのオブジェクト指向拡張とかだと綺麗にかけるんでしょうかね 他に思いつくのは、モジュールを作って そこにスタック本体のデータを置くとかですが どれが良いと思いますか 環境はGauche0.8.14です
507 名前:デフォルトの名無しさん mailto:sage [2009/03/14(土) 21:08:09 ] どれがって、consセルで作れば簡単じゃないかと
508 名前:デフォルトの名無しさん mailto:sage [2009/03/14(土) 21:21:08 ] (define top car) (define pop cdr) (define push cons) じゃまずいですか?
509 名前:デフォルトの名無しさん mailto:sage [2009/03/14(土) 21:40:07 ] >>505 例外処理の項目の数値が未だに信じられない
510 名前:デフォルトの名無しさん mailto:sage [2009/03/14(土) 21:52:51 ] >>508 スタックをリストとして直接触らせたくないってことなんじゃね? まぁ、Gauche の OO 関連はそんなに効率が良くないので、 クロージャに閉じ込める方がまだ無駄は少いかもね。
511 名前:デフォルトの名無しさん mailto:sage [2009/03/14(土) 22:01:34 ] >>509 > まぁ、Gauche の OO 関連はそんなに効率が良くないので、 > クロージャに閉じ込める方がまだ無駄は少いかもね。 くわしく なにと比べて? 効率って生産効率?
512 名前:デフォルトの名無しさん mailto:sage [2009/03/14(土) 22:06:56 ] >>506-508 想像だけど、破壊的更新をしたいじゃないの? オブジェト志向なら、 a = stack.pop() stack.push(b) … とか書くわけジャン。
513 名前:デフォルトの名無しさん mailto:sage [2009/03/14(土) 22:14:32 ] >>511 速度とかメモリ効率とか。 メソッドのディスパッチも基本的には実行時にしか出来ないし。 どうでもいいけど、アンカ間違ってるぞ。 速度的には検証していないけど、 なんとなく>>506 がイメージしているものを想像して書いてみた。 Gauche には依存していないつもり。 (define (make-stack) (let ((stack (cons '() '()))) (lambda(proc) (proc stack)))) (define (push stack-obj elem) (stack-obj (lambda(stack) (set-cdr! stack (cons (car stack) (cdr stack))) (set-car! stack elem)))) (define (pop stack-obj) (stack-obj (lambda(stack) (if (null? (car stack)) '() (let ((elem (car stack))) (set-car! stack (cadr stack)) (set-cdr! stack (cddr stack)) elem)))))
514 名前:デフォルトの名無しさん mailto:sage [2009/03/14(土) 22:23:34 ] スタックはconsで実装するつもりだったし、 なんか話がかみ合わないと思ったら・・そういうことか、理解しました 自分がやりたかったのは510氏のいうような意味でして ちょっと調べてたら可変長引数なる便利なものがあるってわかったので これで実装出来ました。もう少し処理を追加したら自分の目的には使えそうな感じ (define (stack) (let1 val '() (lambda a (let-optionals* a ((b 'none)(c '())) (cond ((eq? b 'none) val) ((eq? b 'top) (if (eq? val '()) '() (car val))) ((eq? b 'push) (set! val (cons c val)) c) ((eq? b 'pop) (if (eq? val '()) '() (let1 r (car val) (set! val (cdr val)) r)))))))) (define a (stack)) (a 'push 1) (a 'push 2) (a 'push) (a) (a 'pop) (a)
515 名前:デフォルトの名無しさん mailto:sage [2009/03/14(土) 22:43:02 ] >>513 (規制されてて書き込みのタイミングが悪かったのですが・・) そういえば、Schemeのライブラリは、こういう形のほうが多いですね 参考にさせてもらいます ありがとうございました
516 名前:デフォルトの名無しさん mailto:sage [2009/03/14(土) 23:03:47 ] 最近のスタックインターフェースは、 top, pop, pushと三つに分けるのが主流だよ。 もはやイディオムになっているといっていい。
517 名前:デフォルトの名無しさん mailto:sage [2009/03/15(日) 00:08:39 ] ;; クロージャに閉じ込める (define (with-stack f) (let ((stack '())) (f ;; push (lambda (obj) (set! stack (cons obj stack))) ;; pop (lambda () (if (null? stack) '() (let ((obj (car stack))) (set! stack (cdr stack)) obj))) ;; top (lambda () (if (null? stack) '() (car stack)))))) (with-stack (lambda (push pop top) (push 1) (push 2) (push 3) (write (top)) (write (pop)) (write (top)) (write (pop)) (write (pop)) (write (pop))))
518 名前:デフォルトの名無しさん mailto:sage [2009/03/15(日) 00:10:58 ] topってなんや?
519 名前:デフォルトの名無しさん mailto:sage [2009/03/15(日) 00:11:52 ] 解決 あとemptyっていうのも重要っぽいね
520 名前:デフォルトの名無しさん mailto:sage [2009/03/15(日) 02:34:25 ] []も使うようにしたほうがいいの? 処理系によっては [] を () と同じように使えて、多少見かけを区別することができます: (let ([x (calculate-x a b c)] [y (calculate-y d e f)]) body ...) (cond [(predicate x) (do-something) (do-something2)] [(predicate y) (do-another-thing)] [else (do-whatever)]) 括弧の意味の多重化 (中段) practical-scheme.net/wiliki/wiliki.cgi?Lisp%3aS%E5%BC%8F%E3%81%AE%E7%90%86%E7%94%B1
521 名前:デフォルトの名無しさん mailto:sage [2009/03/15(日) 03:12:22 ] どうせそんなのはppしたら消えてしまうでしょ。 意味がある試みとは思えない。
522 名前:デフォルトの名無しさん mailto:sage [2009/03/15(日) 03:32:55 ] つーかカッコが何種類も入り乱れるのは激しくウザい
523 名前:デフォルトの名無しさん mailto:sage [2009/03/15(日) 04:59:08 ] 世間でC言語みたいなものが好まれるのは、 演算子を含む式と文とのバランスが良く、 メリハリが付くからだと思う。 LISPは書式が関数も式も文も全く同じ規則で さらにそれを括る括弧に極端に縛られる。 C言語でも関数呼び出しだけで書いていけば 同じ印象になるが、C言語では関数のネストなんて 書こうと思わなければほとんどする必要がない。 要するに括弧の形を変えたところであまり効果はない。 S式ベースでうだうだ考えるよりは、括弧に縛られない 都合の良い構文フロントエンドを作った方がマシである。
524 名前:デフォルトの名無しさん mailto:sage [2009/03/15(日) 05:20:32 ] 俺は好きでよく使っているけどなぁ。 処理系によっては()[]{}の3種類が使えるから、数学の式を書くときみたいな感覚で。
525 名前:デフォルトの名無しさん mailto:sage [2009/03/15(日) 05:34:48 ] ・よく言われる演算子の有無 前置記法である事と関係する。 a.b.cは (ref(ref a 'b)'c) 1 2 3 のような書き方になる。 見ての通り1を脳内スタックに積んで2を読み、 1を降ろして3と結合する、という思考を要求する。 また、aとb,cは同一に扱えない。 ((ref a b c)とは書けず、何かしら歪になる) 演算子があれば a.b.c 1 2 3 や a().b().c() 1 2 3 どちらも1から3まで、左から右へと目を動かすだけで良い。 修正が発生しても一箇所で済む。 これはS式というより、前置記法では解決できない問題と認識している。
526 名前:デフォルトの名無しさん mailto:sage [2009/03/15(日) 05:46:04 ] 前置記法を排除すればS式でも(a -> b -> c)と書ける。 ここで、aをマクロ的に加工して実装してしまう事も考えられる。 が、それが現実的ではない事も判っている。 自分で演算子を作り、管理するのと同じ事になる。
527 名前:デフォルトの名無しさん mailto:sage [2009/03/15(日) 05:58:26 ] また>>526 の(a -> b -> c)のように、 S式内で独自言語を構築する場合、 独自言語の構文としての括弧もあるので、 S式のくくりの括弧がどうしても邪魔に見える。 ここまでやるならもうS式である意味がない。 a->b->cと書きたいならそのまま書けばいい。
528 名前:デフォルトの名無しさん mailto:sage [2009/03/15(日) 06:25:55 ] だから、どうせやるなら>>523 に書いた通り、必要時にS式も扱えるような ちゃんぽん言語でもLISPで作ったらどうかというわけ。 不毛な縛りの中で何かやるよりはよっぽど健全ではないかと思う。 S式はデータとしてならともかく、コードとして出てくる必然性はあまりない。 >>520 とどっちが読みやすいだろうか? let x=calculate-x(a, b, c), y=calculate-y(d, e, f) in body ...; if (predicate(x)) { do-something(); do-something2(); } else if (predicate(y)) { do-another-thing(); } else { do-whatever(); }
529 名前:デフォルトの名無しさん mailto:sage [2009/03/15(日) 06:54:38 ] 入門者なんですが、shchemeでS式以外の書き方の標準構文ってあるんでしょうか? 人間のパターン認知力なのか、人間の適応力のすごさ、慣れなのか、よくわからないけど 今のままのほうがいい気がする 基本レベルの正規表現が使える人で、schemeを100時間触ってみて、それで真っ当な意見を聞きたいかも みんな、「このまままでいいんじゃねえ?」って言いそう 採用する理由になった論文の疑似コードもみてみたいところだが
530 名前:デフォルトの名無しさん mailto:sage [2009/03/15(日) 07:12:55 ] >>525 refが関数なら、(define ref* (lambda x (fold ref (car x) (cdr x))) で (ref* a 'b 'c) って書けるんじゃない。 つか一般に二項演算子があるならfoldしてやりゃ不定長でも扱えるでしょ。 マクロならマクロでくるんでやればいいだろうし。 まあquoteは必要だけど、それは別の話だよね。
531 名前:デフォルトの名無しさん mailto:sage [2009/03/15(日) 07:43:20 ] >>529 昔の Lisp の論文とかには M 式ってあったね。 en.wikipedia.org/wiki/M-expression Scheme の方だと SRFI 49 で I 式っていうのが提案されてる。 srfi.schemers.org/srfi-49/srfi-49.html 正規表現云々は知らないが、どっちもあまり流行ってない。
532 名前:デフォルトの名無しさん mailto:sage [2009/03/15(日) 10:10:46 ] そういえば、syntax が安定するまでは yacc を使って試行錯誤して 安定したら手書きの parser を使うという話を聞いたことがある。 lisper は逆に yacc より更に柔軟な方向に進もうとするのか。
533 名前:デフォルトの名無しさん mailto:sage [2009/03/15(日) 10:31:03 ] リードマクロがあるからね。
534 名前:デフォルトの名無しさん mailto:sage [2009/03/15(日) 11:54:13 ] >>528 マクロを忘れてるぜ。 コードがS式だからマクロ変換子は単なるリスト操作をすれば済むんだろう。 Scheme のマクロは単なるリスト操作じゃないけど、S式は大前提だ。 リーダーマクロにしたところで、内部的にはやっぱりS式だしな。
535 名前:デフォルトの名無しさん mailto:sage [2009/03/15(日) 12:13:45 ] リードマクロってキャラクタストリームベースじゃなかったっけ?
536 名前:デフォルトの名無しさん mailto:sage [2009/03/15(日) 21:58:23 ] ; M-x run-scheme で下のコードをC-x C-eすると、最後に添付するエラーになってしまいます (define (foo x) (if (= x 0) '() (cond ((= (modulo x 15) 0) (cons "FizzBuzz" (foo (- x 1)))) ((= (modulo x 5) 0) (cons "Buzz" (foo (- x 1)))) ((= (modulo x 3) 0) (cons "Fizz" (foo (- x 1)))) (else (cons x (foo (- x 1))))))) 環境 "GNU Emacs 22.3.1 (x86_64-unknown-linux-gnu) of 2009-03-10 on localhost.localdomain" guile> "1.8.0" ちなみにon emacsでloadすると、うまくいきます。 guile> (load "fizzbuzz.scm") guile> (foo 21) ("Fizz" "Buzz" 19 "Fizz" 17 16 "FizzBuzz" 14 13 "Fizz" 11 "Buzz" "Fizz" 8 7 "Fizz" "Buzz" 4 "Fizz" 2 1) また、gosh on emacsだと、こうなります gosh> (32 31 #0="FizzBuzz" 29 28 #1="Fizz" 26 #2="Buzz" #1# 23 22 #1# #2# 19 #1# 17 16 #0# 14 13 #1# 11 #2# #1# 8 7 #1# #2# 4 #1# 2 1) OS再起動してもダメでした エラー(長いので、一部略) guile> ... ... Display all 1922 possibilities? (y or n) ... Display all 1922 possibilities? (y or n) $abs EISCONN ERROR: Unbound variable: s ABORT: (unbound-variable) "Fizz"
537 名前:デフォルトの名無しさん mailto:sage [2009/03/15(日) 21:58:57 ] Backtrace: In current input: 307: 0* [foo 3] 304: 1 (if (= x 0) (quote ()) ...) <unnamed port>:304:1: In procedure memoization in expression (if (= x 0) (quote ()) ...): <unnamed port>:304:1: In line 303: Missing or extra expression in (if (= x 0) (quote ()) d ((= (modulo x 15) 0) (cons "FizzBuzz" (foo (- x 1)))) s "Buzz" (foo (- x 1))). ABORT: (syntax-error) ERROR: In procedure scm_lreadr: ERROR: #<unknown port>:307:24: unexpected ")" ABORT: (read-error) ERROR: In procedure scm_lreadr: ERROR: #<unknown port>:307:25: unexpected ")" ABORT: (read-error) guile> Display all 1922 possibilities? (y or n) $abs %app %cond-expand-features %cond-expand-table %get-pre-modules-obarray %guile-build-info ERROR: Unbound variable: s ABORT: (unbound-variable) 4 Backtrace: In current input: 308: 0* [foo 3]
538 名前:デフォルトの名無しさん mailto:sage [2009/03/15(日) 21:59:36 ] <unnamed port>:304:1: In procedure memoization in expression (if (= x 0) (quote ()) ...): <unnamed port>:304:1: In line 303: Missing or extra expression in (if (= x 0) (quote ()) d ((= (modulo x 15) 0) (cons "FizzBuzz" (foo (- x 1)))) s "Buzz" (foo (- x 1))). ABORT: (syntax-error) ERROR: In procedure scm_lreadr: ERROR: #<unknown port>:308:19: unexpected ")" ABORT: (read-error) ERROR: In procedure scm_lreadr: ERROR: #<unknown port>:308:20: unexpected ")" ABORT: (read-error) ERROR: In procedure scm_lreadr: ERROR: #<unknown port>:308:21: unexpected ")" ABORT: (read-error) ERROR: In procedure scm_lreadr: ERROR: #<unknown port>:308:22: unexpected ")" ABORT: (read-error) ERROR: In procedure scm_lreadr: ERROR: #<unknown port>:308:23: unexpected ")" ABORT: (read-error) guile>