[表示 : 全て 最新50 1-99 101- 201- 301- 401- 501- 601- 701- 2chのread.cgiへ]
Update time : 05/09 18:10 / Filesize : 180 KB / Number-of Response : 714
[このスレッドの書き込みを削除する]
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧] [類似スレッド一覧]


↑キャッシュ検索、類似スレ動作を修正しました、ご迷惑をお掛けしました

Lisp Scheme Part25



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>






[ 続きを読む ] / [ 携帯版 ]

前100 次100 最新50 [ このスレをブックマーク! 携帯に送る ] 2chのread.cgiへ
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧]( ´∀`)<180KB

read.cgi ver5.27 [feat.BBS2 +1.6] / e.0.2 (02/09/03) / eucaly.net products.
担当:undef