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


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

CommonLisp Scheme Part11



1 名前:デフォルトの名無しさん mailto:sage [04/08/02 23:13]
過去スレ
Part1: piza2.2ch.net/tech/kako/987/987169286.html
Part2: pc.2ch.net/tech/kako/1002/10025/1002584344.html
Part3: pc.2ch.net/tech/kako/1008/10082/1008220265.html
Part4: pc.2ch.net/tech/kako/1016/10162/1016211619.html
Part5: pc3.2ch.net/tech/kako/1023/10230/1023091882.html
Part6: pc3.2ch.net/tech/kako/1031/10315/1031560687.html
Part7: ruku.qp.tc/dat2ch/0311/20/1042167213.html
Part8: pc2.2ch.net/tech/kako/1058/10582/1058263391.html
Part9: pc2.2ch.net/test/read.cgi/tech/1069594582/
Part10: pc5.2ch.net/test/read.cgi/tech/1075630259/

関連リンクは>>2-10あたり


205 名前:デフォルトの名無しさん mailto:sage [04/09/02 14:12]
cl の loop が,*短ければ* 読みやすさも書きやすさも両立してて,
すごくいいことを知りました.
lisp らしくないからと拒んでいた自分が悲しいです.
; グレアム氏の入門書が偏っているせいかと w

ところで,ファイルを丸々 string にする方法を探していたところ,
make-string したところに read-sequence を
使って書き込んでいくやつを見つけました.
でも,これしか無いんですか?

get-output-string-stream の input-stream 版が無いのは残念ですね.

206 名前:デフォルトの名無しさん mailto:sage [04/09/02 20:22]
そうこうしてるうちにOnLisp邦訳も更新されてたね。乙
後2章か、がんがれ

207 名前:デフォルトの名無しさん mailto:sage [04/09/02 21:38]
www.itmedia.co.jp/mobile/articles/0409/02/news048.html

208 名前:デフォルトの名無しさん mailto:sage [04/09/02 22:44]
>>207
なんだかなぁ... すべてが痛々しい

209 名前:デフォルトの名無しさん mailto:sage [04/09/02 23:53]
>>205
骨格だけ。
with-outpt-to-string (out)
(loop for line = (read-line stream) do (write-line line out)
とか。eofをどうするか(whileにするかエラー捕まえるか)は好きにすれ。
loopはcollect intoとかfor acrossとかfinallyとか使い出すと妙に可読性が
上がるので結構多用してるカモ。Lispらしからぬ見た目になるけどね。

210 名前:デフォルトの名無しさん mailto:sage [04/09/03 00:04]
3年前はロン毛だったと記憶してるんだけど・・・これヅラだよね?普通に考えて。

211 名前:デフォルトの名無しさん mailto:sage [04/09/03 01:07]
>>209
read-line は改行を消してしまうね.
「行の区切り」を指定できるスペシャル変数があればいいのに.
; awk みたいだ...

212 名前:デフォルトの名無しさん mailto:sage [04/09/03 01:30]
学生時代に授業でSchemeをちょこっとやったんですが、
最近CommonLispをいじってます。
で、CLのlambdaなんですが

(lambda (x) (* x 2)) => error
#'(lambda (x) (* x 2)) => anonymous closure

これにすごい違和感があります。この「#'」はナニモノで
何故必要なんでしょう。

213 名前:デフォルトの名無しさん mailto:sage [04/09/03 02:00]
>>212
このページが大変参考になる。
www.ice.nuie.nagoya-u.ac.jp/~h003149b/lang/comparison.html



214 名前:デフォルトの名無しさん mailto:sage [04/09/03 02:28]
LISP-1か2の違い。

215 名前:デフォルトの名無しさん mailto:sage [04/09/03 04:24]
数ヵ月前に見た時もロン毛だったよ>ドクターT。



216 名前:デフォルトの名無しさん mailto:sage [04/09/03 13:12]
cmuclで関数の実行時間をはかりたいのですが、何を使うのが適当でしょうか?
変数にとりたいのですが、timeマクロは出力してしまうから使えず、
get-internal-run-timeは秒単位らしくて粗すぎて使えず、です。



217 名前:デフォルトの名無しさん mailto:sage [04/09/03 14:43]
>>216
(get-output-string-stream)
で作ったストリームで *standard-output* を let で上書き,,,でできますか?

218 名前:デフォルトの名無しさん mailto:sage [04/09/03 15:44]
cmucl でコンパイルすると,結果がおかしくなりました.

(let ((alist '((:file . "foo.txt")
(:bar))))
(with-open-file (istrm (cdr (assoc :file alist)))
(rplacd (assoc :bar alist) 6))
(format t "~S~%" (assoc :bar alist))
(format t "~S~%" (car (assoc :bar alist)))
(format t "~S~%" (cdr (assoc :bar alist))))

これは,clisp ではコンパイルしてもしなくても
(:BAR . 6)
:BAR
6
となりますし,cmucl でもコンパイルしなければ同じ結果になります.しかし,

# lisp -eval '(compile-file "foo.lisp")' -eval '(quit)'
...
# lisp -load foo.x86f -eval '(quit)'
(:BAR . 6)
:BAR
NIL

となります.cdr 部はどこへ行ってしまったのでしょうか.困ってしまいました... (⊃д`)
バージョンは以下です (起動時のメッセージの一部).
CMU Common Lisp CVS release-19a 19a-release-20040728 + minimal debian patches, running on

219 名前:218 mailto:sage [04/09/03 15:45]
追記.with-open-file を外せば直ります.

220 名前:デフォルトの名無しさん mailto:sage [04/09/03 19:44]
>>218
リテラルリストを破壊的に変更しちゃいかんよ。


221 名前:218 mailto:sage [04/09/03 20:35]
>>220
結果は処理系依存ということなんですか.
最初の alist を,
(list (cons :file "foo.txt")
      (cons :bar nil))
に変更すればいいのでしょうか.

こういうのを警告してもらう方法がありましたら教えてください.

222 名前:デフォルトの名無しさん mailto:sage [04/09/03 20:39]
(rplacd (assoc :bar alist) 6))

(setf alist (cons (cons :bar 6) alist))

223 名前:218 mailto:sage [04/09/03 22:16]
>>222
assoc で引かれることがないとしても,なんとなく違和感がありませんか?
こういうのを普通に感じるて初めて中級者なのでしょうか.



224 名前:デフォルトの名無しさん mailto:sage [04/09/04 02:10]
リテラルを書き換えちゃだめってのは別にLispに限らない、プログラミング言語
一般(とくにコンパイラが介在するもの)に言えることでしょう。
Cでも文字列リテラルには手は出せませんし。


225 名前:デフォルトの名無しさん mailto:sage [04/09/04 03:01]
> Cでも文字列リテラルには手は出せませんし。

んなこたあない。

普通はしないけど。

226 名前:デフォルトの名無しさん mailto:sage [04/09/04 03:09]
OS-9 の C言語処理系は literalが code module (だっけ?) に
置かれるので、書き換えちゃだめでした...

昔話かつ lispじゃないので sage


227 名前:デフォルトの名無しさん mailto:sage [04/09/04 08:18]
>>225
> > Cでも文字列リテラルには手は出せませんし。
> んなこたあない。

いや、んなことあるよ。
リードオンリーなセグメントに置かれるので、変更しようとするとbus errorになる。
そうしないとリテラルはプロセス間で共用することも実行ファイルを直接バッ
キングストアにしてmmapすることもできなくてメモリ利用上非効率。
よしんばそうでなくとも複数の同じ内容の文字列リテラルは一つにまとめられるので、
そういうものだと変更すれば当然悪影響が出る。


228 名前:デフォルトの名無しさん mailto:sage [04/09/04 13:43]
古き悪しきお行儀の悪いやつ用のコンパイルオプションも大抵用意されてはいるけどね

229 名前:デフォルトの名無しさん mailto:sage [04/09/04 23:18]
警告も何も出ない?
セルにimmutableフラグとか付いてないのか。
tinyschemeだか何かの処理系はそういうフラグがあって、
破壊代入するとエラーか何か出た記憶がある。
LISPの場合大抵は複製するから、個人レベルでは対策しなくても
あんま問題にはならないけど、時間置いて使うとたまにやってしまったりするな。
こういう場合の処方で処理系にセーフティレベル上げるとか何らかの
モードがある場合もあるが、実際は目先の速度に気を取られて
気付かない&あえて無視する可能性が高いんだよな。
結局デバッガ立ち上げて原因がわかると。
cmuclレベルの処理系なら何らかのオプションがあると思う。

230 名前:デフォルトの名無しさん mailto:sage [04/09/05 17:46]
InterLispって良く見るんですが、これはLisp方言の一種ですか?
それともCL実装の名前ですが?

231 名前:デフォルトの名無しさん mailto:sage [04/09/05 17:52]
foldoc.doc.ic.ac.uk/foldoc/foldoc.cgi?Interlisp


232 名前:デフォルトの名無しさん mailto:sage [04/09/05 22:03]
>>217
折角教えていただいたのですが、出力文字列を解釈しなくちゃいけなくて大変そうで、
unix-gettimeofdayでusecをとってごまかしてしまいました。
プロセス時間じゃなくて実時間ですが。
経験値を上げてもうちょっと賢くなったらトライしてみます。


233 名前:デフォルトの名無しさん [04/09/05 22:49]
WindowsでLISPでマルチメディアが扱える
処理系ってないのでしょうか



234 名前:デフォルトの名無しさん mailto:sage [04/09/05 23:48]
マルチメディアってなんなんやー?

235 名前:デフォルトの名無しさん mailto:sage [04/09/06 00:37]
メディアが複数同時に使えることでは?

236 名前:デフォルトの名無しさん mailto:sage [04/09/06 02:06]
フロッピーとハードディスクのファイルを読み書きできるとかか。

237 名前:デフォルトの名無しさん mailto:sage [04/09/06 03:12]
クイックディスクを忘れないで欲しい。

238 名前:デフォルトの名無しさん mailto:sage [04/09/06 06:22]
えっと、lispacheの苫米地氏とオウム事件「逆洗脳」の苫米地氏って、
同じ人なんですか??

239 名前:デフォルトの名無しさん mailto:sage [04/09/06 10:34]
>>234-238
おまえら、いい加減にしろw

>>233
やっぱりACLじゃないの?
なんでもできそうだけど。

240 名前:デフォルトの名無しさん mailto:sage [04/09/06 15:00]
gauche用のsdlラッパというのが一番ありがちなパターンに見えるなあ

241 名前:デフォルトの名無しさん [04/09/06 15:39]
>>233
LISPならxyzzy,SCHEMEならHandySchemeのMCI関数でどうよ?


242 名前:233 mailto:sage [04/09/06 22:15]
ACLインストールしました
HandyScheme は知りませんでした
なんかゲームの挙動をLISPで書いて
細かい部分をCで書いて、みたいな
ことを考えてるんですけど・・・
とするとgauche の sdlラッパというのがよさげですね
有難うございました

243 名前:デフォルトの名無しさん mailto:sage [04/09/06 23:52]
>>238
t

>>233=242
Corman Common Lispも見てみれば? IDE使わなきゃ無料だしWindows APIと
仲良くするのも結構得意だというのを聞いた希ガス。実体験ではないので本当のトコロが
どんなもんか知らんけど。
マニュアル眺めた限りではDLL作ったりとかインラインアセンブラ使ったりとかWindowsが
主環境であればそれなりに使えそうだったよ。SDLも誰かライブラリ作ってたはずだし。



244 名前:233 mailto:sage [04/09/07 00:48]
>>243
有難うございます
いつも不思議に思うのですが
私も結構Lisp関連のサイトをこまめに
調べてはいるのですがそういう情報にたどり着けない・・・
どこでそういう情報を得るのですか?
英語圏を調べろってことですかね・・・欝

245 名前:デフォルトの名無しさん mailto:sage [04/09/07 07:22]
Cormanは日本語が通らないのが難点。ゲームとか作るんなら要らないかも知れないが。
それとも今は通るようになったのかな?


246 名前:243 mailto:sage [04/09/07 21:19]
どこでって普通にググるとかcomp.lang.lisp読むとか。
英語圏避けてたらLisp関連サイト調べてないのとほぼ等価と思われ。
ってか折角ただでいろんな情報転がってるのに自分で枠狭めてちゃもったいない。
RCE関連サイトにはロシア語圏にディープなのが多いね。

247 名前:デフォルトの名無しさん mailto:sage [04/09/07 22:41]
Arcの話題ってこことは違う?

248 名前:デフォルトの名無しさん mailto:sage [04/09/08 00:46]
ここでいいんじゃないの。何か進展あった?

249 名前:デフォルトの名無しさん mailto:sage [04/09/08 02:20]
slime 1.0
ttp://common-lisp.net/project/slime/

250 名前:デフォルトの名無しさん [04/09/08 05:53]
gaucheってそもそも Windows に正式対応してたっけ?
Windows 2000 + cygwin でなんとかコンパイルできる段階みだいだけど、
ちゃんと使えてる人いる?




251 名前:デフォルトの名無しさん mailto:sage [04/09/08 09:17]
XP + Cygwin でとりあえず gosh が起動しますが
それ以上の確認はしてないっす

252 名前:デフォルトの名無しさん [04/09/08 10:19]
普通に使える
GLも使える
問題なし

253 名前:デフォルトの名無しさん [04/09/08 17:50]
>> 251-252
有難う。
どうやら、家のCygwinは古いようなので新しいやついれて
ためしてみます。




254 名前:デフォルトの名無しさん mailto:sage [04/09/09 05:26]
今日はFranzセミナーですね。終わったら報告キボンヌ

255 名前:名無しさん@ mailto:sage [04/09/09 08:26]
前から気になってたんですが、CLOSにはコンストラクタってないんでしょうか?

256 名前:デフォルトの名無しさん mailto:sage [04/09/09 09:39]
:initformじゃだめ?
だめなら make-instanceをオーバーライド。



257 名前:デフォルトの名無しさん mailto:sage [04/09/09 09:44]
gauche-sdl
michaelvess.com/text/index.html?section=code


258 名前:デフォルトの名無しさん mailto:sage [04/09/09 14:42]
Win XP + ACL 6.2 + slime 1.0 + Meadow-2.10-dev (ASAGAO)
を使っているんですが、日本語が表示できる設定おしえてください。




259 名前:デフォルトの名無しさん mailto:sage [04/09/10 00:40]
>>256、に限らず
:initformと:initargsって何か使い分けるのに明確な基準とかある?
make-instanceをオーバーライドするんじゃなくてmake-fooみたいなのdefunして
その中でmake-instanceして細工したオブジェクト返すのはよくやるけど、CLOS的には
ダサいっすか?

260 名前:デフォルトの名無しさん mailto:sage [04/09/10 07:24]
ダサいというより、しっかりドキュメントしとかないと(していても)忘れそうじゃない?
間違ってmake-instance単独で使われたときに検出してエラーを出すようにしないと、
しばらくたって保守するときとかにやばそう。


261 名前:デフォルトの名無しさん mailto:sage [04/09/10 08:10]
>>255
> 前から気になってたんですが、CLOSにはコンストラクタってないんでしょうか?
どの言語のコンストラクタを想定しているのか分からないけど、make-instanceが
それにあたのるのかな。あるクラスに固有の初期化はそのクラスに特化した
make-instance(やinitialize-instance, reinitialize-instanceなど)のメソッドを
定義して行います。

>>259 :デフォルトの名無しさん :04/09/10 00:40
> >>256、に限らず
> :initformと:initargsって何か使い分けるのに明確な基準とかある?
スロットオプションの:initformと:initarg、それとクラスオプションの
:default-initargsにはそれぞれ微妙な使い分けの基準となりそうな違いが
あります。

簡単に言ってみると、
:initformは、あるスロットの初期値だけを指定するのに使う。
:initargは、initialization argumentの宣言に使う。
:default-initargsは各スロットの初期値の指定と、初期化メソッド群が
とるinitialization argumentのデフォルト値を一箇所にまとめて指定するのに使う。
つまり、必ずしもスロットの初期化に直接かかわらないものも指定できる。
initialization argumentを宣言したことにはならない。

initialization argument名の宣言がされていると、make-instanceと
その手下である関数が呼び出された時に、引数チェックに引っかからなくなる。

規格のココを読むと書いてあります。
7.1 Object Creation and Initialization
www.lispworks.com/reference/HyperSpec/Body/07_a.htm

262 名前:233 mailto:sage [04/09/10 23:05:30]
gauche Windowsで使う方法がいまいちわからない・・・

ところでこういうCのライブラリのラッパをSchemeで
使えるようにする手順て以下のようなものでしょうか

(1) C でgauche から呼ぶためのdllを作成
(2) gauche から それを呼び出す

(2)の方法が良くわからないのですがCのライブラリに
gaucheからアクセスするのは簡単なのですか?
だとしたら自分で使いやすいようにラッパを作っても
いいんですけどね・・・

263 名前:デフォルトの名無しさん mailto:sage [04/09/10 23:44:32]
>>262
Gauche は examples/spigot/ が参考になるかと



264 名前:233 mailto:sage [04/09/11 01:41:51]
>>263
(2)は define-module, select-module, dynamic-load, provide
の手順でいけるんですね
gauche が理解できる形でstubというのを作ってそこから引っ張るんですね
なんとなくわかったような・・・

@GOSH@ ってのは そのstubというのをつくるコマンドですか?
GOSH getstub $<
スタブとか言葉は聞いたことあるけど実はあんまりわかってないw

265 名前:264 mailto:sage [04/09/11 16:06:15]
gauche インストールしました
gosh ってgouche のリスナーの名前だったんですね・・・
お恥ずかしい


266 名前:デフォルトの名無しさん mailto:sage [04/09/11 22:18:30]
>>258
(process-send-string proc (string-make-unibyte string))
string-make-unibyte してちゃ日本語は無理だよな。
さて、どうするか

267 名前:デフォルトの名無しさん mailto:sage [04/09/12 00:16:38]
>>258 266
とりあえず、次ので日本語できたっぽい。
Mac OS X, OpenMCL でだけど
diff -r1.397 slime.el
1430c1430
< (set-buffer-multibyte nil))
---
> (set-buffer-multibyte t))
1439c1439,1440
< (let* ((msg (concat (slime-prin1-to-string sexp) "\n"))
---
> (let* ((msg0 (concat (slime-prin1-to-string sexp) "\n"))
> (msg (encode-coding-string msg0 'euc-jp-unix))
1442c1443
< (process-send-string proc (string-make-unibyte string))))
---
> (process-send-string proc string)))
1502c1503,1504
< (let ((string (buffer-substring start end)))
---
> (let* ((string0 (buffer-substring start end))
> (string (decode-coding-string string0 'euc-jp-unix)))


268 名前:デフォルトの名無しさん mailto:sage [04/09/12 01:00:18]
うおおお
sortがでけた

269 名前:デフォルトの名無しさん mailto:sage [04/09/12 16:27:08]
Corman Lispの作者のCormanさんから宣伝メールが来たよ。
Lispの処理系売って食ってくというのは苦労してるんかね。
とにもかくにも日本語がちゃんと扱えないことにはねえ。


270 名前:デフォルトの名無しさん mailto:sage [04/09/13 16:15:43]
前から思っていたんだけれど、
スペシャルフォームをファーストクラス・オブジェクトにすることはできない
だろうか?
スペシャルフォームを引数にとったり、関数の戻り値としたりできないだろうか?

> or
<#special form>  <-- 通常なら syntax error
> (or #f 3)
3

こんな感じで、スペシャルフォームが単独で入力されても文法エラーに
ならないようにすれば、うまく行くような気がするのだけど、どうでしょう?

271 名前:デフォルトの名無しさん mailto:sage [04/09/13 16:32:46]
>>270
Gaucheだとできてしまう。

gosh> set!
#<syntax set!>
gosh> define
#<syntax define>
gosh> (define hoge #f)
hoge
gosh> (set! hoge define)
#<syntax define>
gosh> (hoge x 1)
x
gosh> x
1


272 名前:270 mailto:sage [04/09/13 16:37:59]
ええー!Gauche って便利なのね。すごーい!

と言うか、なんで PetiteChezScheme だとできないのだろう??
何か不都合があるのでしょうか?
使えるほうが、絶対便利だと思うのだけど。

273 名前:270 mailto:sage [04/09/13 16:55:53]
すると Gauche では、こんなこともできちゃうのでしょうか?

gosh> ((lambda (x y) (x #f y)) or 3)
3

スペシャルフォームは、car の位置にきたときだけ機能するようにすれば
こういう書き方も ok だと思うのだけど。



274 名前:デフォルトの名無しさん mailto:sage [04/09/13 16:56:18]
もはやGaucheは、かつてgccがCじゃなかったくらいにschemeじゃない気がする。
gccの場合はしばらくしたら標準が追い付いてきたので、
schemeもあと十年くらい待てば>>270みたいのが標準で使えるようになるかもよ。


275 名前:デフォルトの名無しさん mailto:sage [04/09/13 17:01:39]
>>273
やってみた。

gosh> ((lambda (x y) (x #f y)) or 3)
*** ERROR: invalid application: (#<syntax or> #f 3)
Stack Trace:
_______________________________________
gosh> (let ((hoge or)) hoge)
#<syntax or>
gosh> (let ((hoge or)) (hoge #f 3))
*** ERROR: invalid application: (#<syntax or> #f 3)
Stack Trace:
_______________________________________

意外とよわよわだったな、Gauche……。


276 名前:270 mailto:sage [04/09/13 17:17:52]
>>275
あれれ、残念。
shiro さん、もし見てたら、ご検討お願いします。

277 名前:デフォルトの名無しさん mailto:sage [04/09/13 17:18:15]
guile> ((lambda (x y) (x #f y)) or 3)
3

できました

278 名前:270 mailto:sage [04/09/13 17:20:20]
>>277
おお!さすが何でもありの Guile!

279 名前:デフォルトの名無しさん mailto:sage [04/09/13 19:01:09]
それにしても、こんなに便利そうなのに、どうして標準になっていないのだろう?
何か問題があるのだろうか?

280 名前:デフォルトの名無しさん mailto:sage [04/09/13 19:59:08]
そりゃSchemeが便利ならなんでもありとは対極にあるような言語だからだろ


281 名前:デフォルトの名無しさん mailto:sage [04/09/13 20:17:07]
マクロの展開についての根深い対立が…。

282 名前:デフォルトの名無しさん mailto:sage [04/09/13 20:32:55]
夢の中で問題点を一つ思い付いた。関数はまず全部の引数を評価してしまうが、
syntaxはそうではない。わかりやすいところではand, or, begin, ifなど。

(define foo #f)
(or #t (begin (set! foo 3) foo))
とこれ↓を比べてね:
((lambda (x y) (x #t (begin (set! foo y) y))) or 3)

そう考えるとトップレベルでのみ別の名前に束縛できるというのは
それなりに意味があるかも。
しかしguileだと後者も難なくこなしてしまうようだ。どうなっとるんだ。

guile> (define foo 1)
guile> ((lambda (x y) (x #t (begin (set! foo y) y))) or 3)
#t
guile> foo
1
guile> ((lambda (x y) (x #t (begin (set! foo y) y))) and 3)
3
guile> foo
3

きっと、こんなことやってるからguileは遅いんだな……。


283 名前:デフォルトの名無しさん mailto:sage [04/09/13 20:34:59]
>>279
(or a b) はaがtrueならbが評価されないってところが大事なところでしょ。
手続きとして使いたければormapとかanyとかあるわけだし、自分でも作れる
わけだし。
構文は、実行前に意味が確定できることが肝なんであって、>>277みたいのを
標準にする意義がわからん。






284 名前:270 mailto:sage [04/09/13 20:45:37]
>>282
すばらしい!Guile のその挙動こそ、私が望んでいたものです。

>>283
それが、『Scheme手習い』の「lambdaは最高だ」に、スペシャルフォームを引数に
取れたら非常にシンプルに書けるような例が出ていたのです。
(実際はできないから、本では相互再帰を行って何とか解決していた)

285 名前:270 mailto:sage [04/09/13 20:48:12]
>>282
Guile の実装はぜんぜん知りませんが、
きっとスペシャルフォームを実行するのは car の位置に来たときだけ、という
ルールでやっているのじゃないかなあ。

そんなに速度も落ちないのじゃないかと思うのだけど。

286 名前:デフォルトの名無しさん mailto:sage [04/09/13 21:36:01]
実行時に展開と評価時に展開じゃ速度にかなり違いが出るような気が。

287 名前:デフォルトの名無しさん mailto:sage [04/09/13 21:41:43]
"special formを実行する" のは構文を parseするときではないのか?

>>277みたいなのは parseするときに決まってないんだからだめじゃん。

Haskellの世界にでもくれば shortcutなんかわざわざ意識しないでいいよ :-)


288 名前:270 mailto:sage [04/09/13 22:02:21]
うー、そういう問題があるのですか…。

スペシャルフォームを引数に取れると便利だという例をちょっと
書いてみました。
関数と違い、すべての要素を評価しないスペシャルフォームなので、
途中で結果がわかれば、リストを最後まで評価せずに止まります。

テストはしておりませんので、バグっていたらごめんなさい。

;関数を返す関数。引数に and か or を取る。
(define make-function
 (lambda (s-form)
  (lambda (list0)
   (s-form (atom? (car list0))
       ((make-function s-form) (cdr list0))))))

;リストにアトムが含まれるか?
(define has-atom? (make-function or))

;リストの要素がすべてアトムか?
(define all-atom? (make-function and))


289 名前:270 mailto:sage [04/09/13 22:03:35]
もしかして、Haskell のように遅延評価がデフォルトだと、
スペシャルフォームのほとんどは不要になるのでしょうか?

290 名前:デフォルトの名無しさん mailto:sage [04/09/13 22:14:28]
>>274
標準 (R5RS) では未定義あるいは実装依存とされている領域を利用しているだけだから
scheme ⊃ Gauche だよ

291 名前:デフォルトの名無しさん mailto:sage [04/09/13 23:13:29]
ふと気づいたのだけど、マクロもスペシャルフォームの一種だよね?
Guile って、マクロも実行時に展開しているんだろうか?
だとしたら、遅いのも道理だなあ…。

どなたかGuileユーザの方、確かめていただけませんか?

292 名前:デフォルトの名無しさん mailto:sage [04/09/13 23:34:50]
guile> (define-syntax my-or
    (syntax-rules ()
     ((_ x y) (or x y))))

guile> ((lambda (s-form y) (s-form #t (display y))) my-or 3)

これを試していただけませんか?
#t が返ってくるなら、マクロを実行時に展開していると思う。


293 名前:デフォルトの名無しさん mailto:sage [04/09/14 00:00:24]
>>292
Unbound variable: define-syntax
とか怒られた。



294 名前:デフォルトの名無しさん mailto:sage [04/09/14 00:06:55]
あれ?当然エラーは 2つ目の式で出たんですよね?
1つ目のdefine-syntax の式の実行で出たのではないですよね?

するとやはり Guile は他と同じで、パース時にマクロを展開するのかな?

295 名前:293 mailto:sage [04/09/14 00:14:21]
>>294
ごめん。(use-syntax (ice-9 syncase))忘れてた。
2つめの式で
ERROR: invalid syntax my-or
って出た。

296 名前:デフォルトの名無しさん mailto:sage [04/09/14 01:24:16]
了解。いずれにせよ、マクロ展開は実行時ではなく、解釈時なのね。
どうもありがとう。

そうしてみると、first class objectとして扱える special form はGuile の
場合、システム組み込みのものだけなのか。
ユーザ定義のマクロと、システム組み込みの special form を区別せずに扱えるのが
Lisp の良さの一つなのに、これでは価値半減だなあ。
実行してみるまで区別がつかないから、わかりにくいバグの元にもなりそうだ。

これなら、special form に別名を付けることしかできない Gauche の方が現実的な
落としどころのような気がする。

special form を first class として扱うためには、マクロ展開を実行時に行っても
構わないような、マシンパワーのあまりある時代を待つしかないのかもしれない。

297 名前:デフォルトの名無しさん mailto:sage [04/09/14 01:28:42]
まてよ。Gauche でも、マクロには別名は付けられないよね?
(define new-or my-or) は syntax error になると思う。

すると、ChezScheme のように、special form を一切拡張しないのが一番
現実的なのだろうか。何か寂しいなあ。

298 名前:デフォルトの名無しさん mailto:sage [04/09/14 01:39:04]
Gaucheではできる。Gaucheでは、コンパイル時に(手続き呼び出しではなく)
マクロだとわかるものならマクロ展開をしてくれるし、マクロの名前は
マクロそのものを返す。(define new-or my-or)も可能。

syntax classをapplicable objectにして、実行時に展開したら
おもしろいかも。evalが必要になるし、トップレベル以外の環境は
取得できないから無理だろうけどさ。

299 名前:デフォルトの名無しさん mailto:sage [04/09/14 05:00:28]
>>270
そういうのはマクロでやる。
実際、make-functionのコンパイル時にはs-formが構文かどうかは
わからないわけだから、コンパイラは ((make-function s-form) (cdr list0))
を評価してからs-formを呼ぶってコードを出すしかないじゃん。

>>287
Lazyなセマンティクスなら評価順の問題は出ないけど、「構文を
パラメタライズする」っていうのはもっと広い問題を含んでる。
Haskellでも、構文要素である '\' や '=' を関数引数として
渡すわけにはいかない。
構文のパラメタライズってのはメタプログラミングしてることになる。
Lispではマクロがメタプログラミングの道具。



300 名前:270 mailto:sage [04/09/14 10:38:48]
>>298
やっぱり Gauche はバランスがよく取れているということなのでしょうか。


>>299
そうか!マクロか!と思って、さっそく>>288 のコードをマクロ化してみました。

;元の関数
;(案の定バグがあった(停止しない)ので修正してある。)
(define make-function
 (lambda (s-form null-value)
  (lambda (list0)
   (if (null? list0)
     null-value
     (s-form (atom? (car list0)
         ((make-function s-form null-value) (cdr list0))))))))

;マクロ化したもの
(define-syntax make-function
 (syntax-rules ()
  ((_ s-form null-value)
   (lambda (list0)
    (if (null? list0)
      null-value
      (s-form (atom? (car list0))
          ((make-function s-form null-value) (cdr list0))))))))

そうしたら、マクロ展開が停止しないんです。再帰的定義なのに停止条件がないから。
この場合、どう書いたらよいのでしょうか?ヘタレですみません。

301 名前:270 mailto:sage [04/09/14 13:12:00]
『On Lisp』邦訳 10 マクロのその他の落し穴 10.4 再帰(P81)を読んでみました。
思ったより、解決は難しそうです…。

302 名前:デフォルトの名無しさん mailto:sage [04/09/14 15:30:55]
>>300
> やっぱり Gauche はバランスがよく取れているということなのでしょうか。

つーより、事前にコンパイルするんじゃguileみたいな挙動は不可能じゃね?
S式をそのまま解釈実行するのでないと。当然その場合実行速度は遅くなる。


303 名前:デフォルトの名無しさん mailto:sage [04/09/14 15:58:30]
なんか似たような話を見たことあるなあ……と思ってたんですが、
これなんか参考になりませんか? Common Lisp だけど。

ttp://home.comcast.net/~bc19191/blog/040527.html



304 名前:デフォルトの名無しさん mailto:sage [04/09/14 16:14:46]
>>270
実行時の停止条件と展開時の停止条件をごっちゃにしてると思われ。
停止を実行時に判断するなら、ループは実行時手続き呼び出しになる。

(define-syntax make-function
(syntax-rules ()
((_ s-form null-value)
(rec (f list0)
(if (null? list0)
null-value
(s-form (atom? (car list0))
(f (cdr list0))))))))

recはsrfi-31ね。letrecを使ってもよい。

停止を展開時に判断する場合は、実行しないでも停止条件がわかる
ことが必須。たとえば引数がリテラルリストで与えられているとか。
その場合はsyntax-rulesで再帰を書けばいい。

(syntax-rules ()
((_ s-form null-value val0)
(s-form (atom? val0) null-value))
((_ s-form null-value val0 val1 val2 ...)
(s-form (atom? val0)
(make-function null-value val1 val2 ...))))







305 名前:270 mailto:sage [04/09/14 22:43:09]
ありがとうございました。言われてみれば『On Lisp』そのままの話でしたが、
具体的に書いていただくまで分かりませんでした。お恥ずかしい。

rec という構文は初めて知りました。
ChezScheme ではそのままでは動かなかったので、少し変えました。

;; rec 版
(define-syntax make-function
 (syntax-rules ()
  ((_ s-form null-value)
   (rec f
    (lambda (list0)
     (if (null? list0)
       null-value
       (s-form (atom? (car list0))
        (f (cdr list0)))))))))

;; 名前つきlet (letrec)版
(define-syntax make-function
 (syntax-rules ()
  ((_ s-form null-value)
   (lambda (list0)
    (let loop ((list0 list0))
     (if (null? list0)
       null-value
       (s-form (atom? (car list0))
        (loop (cdr list0)))))))))

(define has-atom? (make-function or #f))

(define all-atom? (make-function and #t))






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

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

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