Lisp Scheme Part40 [転載禁止]©2ch.net
■ このスレッドは過去ログ倉庫に格納されています
>>495
高速ブン回しと違うけど、Lisp Flavoured Erlangとかだめ?
ttp://lfe.io ある程度大きな単位でならバインディング作って投げてしまえばいいんだけど、
ちまちまやると境界を超える部分のオーバーヘッドで逆効果になったりするので、
本格的にやろうとすると処理系自体がサポートする必要はあると思う。 Racketのプログラムを並列化して高速化したい。ハーランに書き直すのが1番手間かからずに高速化できるのだろうか 『scheme手習い』読み始めた
この本自体はめっちゃ面白いけど実際に自分のPCでschemeを走らせる方法が全く分からないのはどうすれば >>502
ぐぐったらGaucheじゃないかってGoogleに怒られた
チュートリアルがないみたいだけど絶版の『プログラミングGauche』を買った方がいいの? >>501
特にこだわりが無ければ、Racketが最も簡単なのでおすすめ。
ダウンロードしてインストールするだけでプログラミングに必要な環境が全て整うぞ。 >>505
簡単でいいね
言語選択はR5RSでok? 個人的にはそろそろ R7RS (の処理系) を前提にしてもいいんじゃないかと思ってるが、
総合的な開発環境の便利さとしては Racket が優勝だわな。
少なくとも初心者にすすめられるものとしては。 >>508
> 個人的にはそろそろ R7RS (の処理系) を前提にしてもいいんじゃないかと思ってるが、
R7RSはsmallの範囲は言語仕様書のドラフトが提出されたというのを何かで見た覚えがあるが
R6RSで巨大化した範囲に対応largeの部分の仕様書はドラフトでも出たのか?
あれがまとまるとは思えんのだが
それに処理系側もR7RSへの対処は結局はsmallだけへの対応で終わる…R6RSが処理系屋からほとんど無視されたように…のでは、と
個人的には予想している
そしてその予想が正しいならば、R5RS対応の処理系を使う前提で十分な気がする
(R7RSで言語仕様をsmall/largeの2階層モデルにした意図が、Come back! R5RS! Good bye R6RS! X-p にあるのは明らかだからね) >>509
Large の状況については >>494 の通り。
全部の議論が終わるのはまだかなり先のことになるだろうし、
処理系の対応がどうなるかはまだなんとも言えないところはあるのは確かだと思う。
でも、 R7RS Small については R5RS を少し拡張するにとどまったからこそ、
その程度の小さな差を導入することをためらわなくていいんじゃないかという意図だった。
R5RS でも十分といえば十分なのかもしれないけど
特にライブラリなんかは結局のところ R5RS 処理系でもそれぞれの処理系ごとに機構を持ってたりするし、
SRFI を使ったりするときに統一的な書き方ができた方が教える方もやりやすいよ。 >>510
詳しい説明どうもありがとう
なるほど、そういうことですか、了解しました ここはスレチかもしれんがGo言語の勉強兼ねてR7RS片手にScheme処理系組んでみようとしてるけどトークナイザ書くの面倒すぎて心折れそう、お前らどうやってコード書くモチベ維持してるの? schemeレベルで面倒つったら他の演算子入りの言語じゃどうなるんだ >>512
最初から完全である必要はないよ。
数値を整数だけにして文字列や識別子のエスケープも全部省略くらいのものから始めたらいいと思う。
限定的にでも動くものが目の前にあればモチベーションを維持しやすい。 >>515
なるほど、とりあえず簡単なとこからやるか 通常のletのように使うだけでgensym済みのlet文を生成するマクロ用コードを作ったのですが、このような挙動をする関数名を教えてください。
(let ((foo (gensym))) `(let ((,foo ,x)) ...)
が
(my-let* ((foo x)) ...)
と書ける感じです。再発明でなく役立つのであればここにCC0で貼りたいです。 On Lisp に with-gensyms っていうマクロが載ってるけど、
それとは違う? with-gensymsではたぶんこうなると思います。
(with-gensyms (foo) `(let ((,foo ,x)) ...)) 突然死しないうちにとりあえず貼りますね。
アカウントは消すのでいいものであればbase64で書き残します。
ttps://gist.github.com/lla/f9244aefb7eee18db4cd レキシカルスコープのletやlet*でgensym必要なの?
使い道が良く判らない こういう時に要ると思うのですが...。要りませんか?
ttp://www.sampou.org/scheme/t-y-scheme/t-y-scheme-Z-H-10.html#node_sec_8.2 `((lambda (foo) ...) ,x)と展開すりゃ要らないんじゃないの schemeでは衛生マクロを使うので不要だと思います。
commonlispでも仕様が中途半端なので不要だと思います。
そのまま書くのと手間が変わらないですし。 (define-macro (my-or a b) `((lambda (x y) (if x x y)) ,a ,b))
>>524 こうですか? 副作用に対してはより良いと思いますが、関数化した時lambdaが二重になって連続使用した時嬉しくないと思います。
>>525 仕様が中途半端という点、gensymのプレフィックスがないこと以外で何か不都合の起きる文があれば知りたいです。それともgensym名の変数は込み入った文や副作用でセットすることが多く、最初に全てのシンボルに値を入れられると不便ということでしょうか?
ネストが一つ減る程度の関数は不要ですか? そもそもgensymがなんで必要なのかを理解しているのかという >>527 once-only っていう定番マクロしらないの?
(defmacro square (x) (my-let* ((g x)) `(* ,g ,g)))
(defmacro square (x) (once-only (x) `(* ,x ,x)))
それは中途半端なonce-onlyの再発明なんよ and や orって短絡評価な気がして>>527はもやもやする
それと副作用のある式を同一式に並べるのは未定義だった気がする >>530
素敵です! ありがとうございます! これが探し求めていたものです。より良いものがあることを願っていました。 ((a b c) d)の評価順序は
a b cの順序は決まってなくて(a b c)の後にdが評価されるのだけは保証されている。で合ってるよね?
もちろんマクロや特殊形式の引数は除外だけど>>527の展開結果は(a b c)と同じことになってる
さらに(or a b c)ならaがtrueの時点で評価打ち切りでb cは評価されない(短絡評価)
(or a b c)がマクロなら以下のように展開されないといけない
((lambda(x k) (if x x (k))) a (lambda() ((lambda(x k) (if x x (k))) b (lambda() c)))) >a b cの順序は決まってなくて(a b c)の後にdが評価されるのだけは保証されている。で合ってるよね?
これ合ってないわ。評価されるからそれを見越して>>534の最後のように遅延評価を入れとくって話
もういいです。 評価されるから、じゃなくて評価の順序が決まってないから
それを見越して無引数lambdaを1つ挟む必要があるだった。 気持ち悪いからまとめると、
((a b c) d)のa b c dの評価順序は何も決まってないから気をつけてねって事。 最初の要素を最初に評価しないとマクロかどうか分からないかと思ってたが、その前の段階でマクロかどうかを判断することができるらしいんで、仕様では決まってないのか
((begin (display "1st\n") +) (begin (display "2nd\n") 2) (begin (display "3rd\n") 3))
をchezとgaucheで評価したら
2nd
3rd
1st
5
って順番だった。guileやchickenだと
1st
2nd
3rd
5
って順番になる。 最適化や諸々の都合で、同じ処理系でも順序が変わることはあるので、
単純な事例だけでは処理系の性質を推し量ることは出来ない。 (define-macro (my-once-only1 x . body)
(let1 tmp (gensym)
`(glet1 ,tmp ,x
(let1 ,x ,tmp ,@body) )))
(use srfi-1)
(define-macro (my-once-only vars . body)
(let ((names (map (lambda (_) (gensym)) vars)) )
`(glet* ,(zip names vars)
(let ,(zip vars names) ,@body)
) ))
念願のものが作れました…。これで心残りはありません。 Scheme でやるなら syntax-rules でやったほうが楽だと思うが。 >>533
> >>531
> 確か評価順が未定義なだけ。
少なくともSchemeではandやorでの式の評価順序は未定義でなくは左から順番に評価すると一意的に規定されているぞ
CLはどうだが知らんが >>542
そうだった。間違えた。
未定義なのは関数呼び出しの引数の評価順だね。 やっとリスト処理に慣れてgensymであーだこーだしてる人にsyntax-rulesは敷居高いと思う syntax-rulesはR7RS眺めてもよくわからんかった むしろSchemeから学ぶとマクロ入門にはsyntax-rulesしか書いてなくてdefine-macro&gensym触る機会が無かった 伝統的マクロの方が動作モデルを想像しやすくはあるかもね。 >>546
> むしろSchemeから学ぶとマクロ入門にはsyntax-rulesしか書いてなくてdefine-macro&gensym触る機会が無かった
>>547
> 伝統的マクロの方が動作モデルを想像しやすくはあるかもね。
Schemeの場合、何でもありのマクロを排除して意味や動作を形式的に定義でき、
展開結果の正しさ(変数が展開したとたんに突然バインドされたりしない等)を保証できる範囲に留めたいという発想が
根底にあるからね
だからsyntax-rulesなどSchemeでの「マクロ」はあくまでも構文の拡張(カスタマイズ)のためなんだよね
つまり字句レベルを勝手に弄らせるとどんなトラブルでも起こし得るから勝手に弄らせたくたくない、
プログラマがお好みの構文を既存構文を使って定義して追加したいというならそれは許してあげよう
(例えばCみたいにwhile文…ループ条件の判定が最初に行われる構文…がある言語にrepeat〜until文を追加したいなら
許してあげように相当)というのがSchemeの基本的なスタンス
つまり、Schemeの場合はソースレベル(テキストレベルと言っても良い)で好き勝手な操作を許す本来のマクロ
(ソースコードレベルのメタプログラミング手段)でなくて、抽象構文レベルでの変換規則を定義し使用する範囲だけに
限定しているんだと考えれば良いと個人的には思ってるけどね
だから(メタ)プログラムの動きで理解するタイプの人(プログラマには多い、特に優秀な人ほど)にとっては
古典的なマクロのほうが却って理解しやすく、逆に理屈が好きで系統的に理解したがる(代わりにプログラムの腕は
さほどでないのが多い)人間にはSchemeの構文拡張のほうが理解しやすくそちらを好む人が多い
もっともsyntax-rulesとかを提案して実現した向うの連中はプログラミングの腕力も上級者以上ばかりだけどね
(でも殆どの凡人は、プログラミングの腕か理屈かの高々どちらかしか得意でない、まあだからこそ凡人なわけでして
どっちも両立できちゃったらGuy Steele, Jr.みたいになれちゃうよね) syntax-rulesの動きがよくわからなくて理解できなかったけど古典的マクロなら単純で理解しやすかったな、準クォート使えば面倒でもなかったし(プログラムの腕はだめです) >>549 あくまでも構文の拡張のため
他のlispでもそうでしょ.具体的にそれ以外の他になにがある? >>551
他のLispに限らずマクロは構文の拡張と言えるほどの系統的な代物にはなってないでしょ
だからマクロを展開した途端にグローバルだったはずの変数が束縛されてローカルな変数に化けたりする(変数のキャプチャね)
つまり通常のマクロは(必要に応じて実行時と同じ計算も許して)ソーステキストという文字列データを処理しているだけ
それに対してsyntax-rulesなどに代表されるSchemeのは抽象構文上での操作とすることでテキストという文字でなく構文の句構造のレベルで扱い
変数のキャプチャなどを起こさないように保証するわけだ
ソースコードを文字データとして処理するのか句構造として処理するのかでは考え方も保証できる正しさや展開の安全性も全く違う >>552
> lispマクロは構文の拡張と言えるほどの系統的な代物にはなってない.
そんなお前定義しらんし,そんならsyntax-rulesも違う.
はなしが無限退行しそうだからもういいわ. Common lispにschemeのmatchマクロを移植したのないのでしょうか? さあ、わかんなくなってきました。
とにかくsyntax-rulesの方が高級で、実装がめんどくさくて、低機能で、とりあえずほとんどの用はたりる。 そのめんどくさいの一点だけでLISP系にsyntax-を導入する価値は微妙
パターンマッチだからLISPじゃなくていいわけよね
syntax-rule/caseを日本語で詳細解説した本とかWebページってない? なんだっけsyntax-rule/caseの他にもう2つぐらい別種があるんだよね
重複しないシンボル名の管理の観点では手間は同じだけど概念的にはより簡単な感じだったと思う case は削除されなかった?他の2つも結局どうなったんだか >>556
> そのめんどくさいの一点だけでLISP系にsyntax-を導入する価値は微妙
一概には言えない。
たとえば letrec のようなものをマクロで書こうとするとフォームを分解したり
衛生的にしたりする処理はいずれにしても必要なことで、
それを自動的にやってくれる syntax-rules だと簡単に書ける。
syntax-rules や syntax-case は言語のプリミティブな機能としては高級すぎるのは確かで、
これは低水準の部分でどのパラダイムを採用するかで意見が一致しなかった末の妥協案として
いきなり高級な機能を持ち込んだ結果。
参考: http://blog.practical-scheme.net/shiro?20100425-scheme-macro
実際の処理系では explicit renaming や syntactic closure を基礎に据えてその上に
syntax-rules や syntax-case のインターフェイスを実装している場合もよくある。 schemeだとread macroの定義ってどないなっとるん?
自分common lispとバージョンが上がるといつ消えるか解らないclojureのしか知らんのだけど。 >>560
リードマクロについては Scheme の仕様には含まれないし SRFI にもないし、デファクトスタンダードといえるものもない。
処理系が独自にやっている場合はあるけど。
私見だが、 Common Lisp に比べて Scheme はモジュール化を強く意識していると思う。
R6RS でフェイズの制御について一応の考え方が確立したものの、
リーダの適用範囲をうまく制御するにはまた別の軸を持ち込む必要があるので厄介なのだと思う。 >>561
あ、やっぱりなかったのか探しても定義みつらんわけだ
DSL書きたいので処理系の小さい実装のschemeでやろうとおもったのだけど駄目か orz
ありがとね schemeのリードマクロってCL踏襲じゃまずい理由でもあるの?
健全とか関係なくね? >>562
それはいっそプリプロセッサ的なものを書いてしまえばいいんでないかい? Lispの論文で英語表現とか定理の書き方みたいので参考になる論文ってどこらへんみればいいでしょう >>566
定理はともかく英語表現はRnRSの原本読んどけばいいんじゃないかな
後はこんなのとか
http://repository.readscheme.org/ftp/papers/ai-lab-pubs/AIM-353.pdf
wikipediaのScheme系の記事の参照元を読み漁るといいと思う RnRS は仕様書っぽい言い回しだけど論文と同じかなぁ、論文読む方に賛成 >>564
リードテーブルの状態によってプログラムの意味が変わってしまうのは不健全さを嫌うScheme的にはだめでしょ >>569 の主観なのかそれとも論文にまとまってたりするのか.
racket#!langはどうなる. >>570
そもそもRacketはScheme的にだめでしょ Chez Schemeの日本語ドキュメントないの〜? Chez Scheme について具体的に知りたいことがあればここで質問すれば簡単な回答くらいはつくかも? 最近のlisp webフレームワークで良いのって何でしょうか Kahuaなら知ってるが更新されてないっぽいし使ったことないからよくわからん 逆転ポインタなつい
ttp://qiita.com/kingshine/items/d74576886c067737ad18 Common lispのnilとfalse区別しないの気持ち悪いけど
Schemeでまともな処理系もう残ってない感じして
Common Lisp に移住するしかない 何をもってまともと言うのか、Gauche使ってるけど普通に安定してるぞ >>577-578
Kahua ほどダイナミックな運用はできないが Gauche-makiki は簡単に使えるし
活発に更新されているのでいいかも。 picrin使ってたのにgitのtipがビルド通らん…巻き戻すしか >>587
そんなスピードで何するの?
速いに越したことはないけどさ。 速いに越したことはないなら一番速いやつを選ぶじゃん >>592
picrin のどういうところが好き? >>594
他の条件が同じなら速いやつを選ぶけどさぁ、
そんなの用途によるだろ。 ■ このスレッドは過去ログ倉庫に格納されています