Lisp Scheme Part41 (855レス)
上下前次1-新
551: はちみつ餃子 ◆8X2XSCHEME 2023/01/08(日)17:21 ID:/n9SAwLy(1) AAS
おおよそ似た雰囲気では書けたりするのかもしれないけど
単純に対応してるわけじゃなかったりもするからいいかどうかは状況によるんじゃないの。
552: 2023/01/08(日)18:49 ID:5ojqztS1(1) AAS
まんまじゃね?
とりあえず(macroexpand 'sb-int:named-let)はそのまんまlabelsに展開されたのでお試しあれ
どの処理系でも似たような定義が大体あるはず
1958年のオリジナルlispのlabelは、scheme界隈ではlet1という名前で見掛ける
当然だけど、ローカル定義が一つなので(自明には)相互再帰はできない
触って気付いたけど
(flet ((cons (a d) (list :cons a d))) (cons :a :d))
; (:CONS :A :D) clisp, sbcl
; (:A . :D) ecl
eclのこれバグ?
553(2): 2023/01/09(月)03:51 ID:0CyucYY1(1/3) AAS
触ったことないのでeclがどの程度cltl/ANSI/clhs等の標準をリスペクトしてるのかも分からないのだが
とりあえずgoogle play storeからeclのandroidポートらしいeql5 replを入れてみた
(list ;; attempt to shadow cl:cons
(flet ((cons (x y) (cons y x)))
(cons 'co '?ns))
(let ((cons (lambda (x y) (cons y x))))
(funcall cons 'co 'ns)))
((CO . NS) (NS . CO))
fletは謎挙動だね…
* shadowしない名前(xcons)ならok
* (flet ((cons (x) (1+ x))) (cons 42))がアリティ不一致で怒られる
から推測するに、普通cl packageの関数なんて弄られないだろうと踏んで、関数の名前解決を手抜きして最適化してるんだろう
値の名前解決は特に弄る意義もないので、scheme風にlambdaをletで値として束縛して呼べば問題ない
clを名乗る以上はオプションで切れるくらいの配慮はあるだろうから、eclにこだわるならマニュアル読んでみては
少なくともclhsはリスペクトしてないね
...flet can locally shadow a global function name, ...
外部リンク[htm]:www.lispworks.com
554: 2023/01/09(月)16:15 ID:2yNmR2Eh(1) AA×

555: 2023/01/09(月)16:36 ID:0CyucYY1(2/3) AAS
eclは有名だけど、embeddableの名前通りの用途で1MBちょいな処理系だから、そういうものと割り切って使うべき
funcallが冗長ならletのbodyにfuncallをconsするだけのmy-fletを作ればいいじゃない
(さらなる災禍を招きそう)
556: 2023/01/09(月)16:57 ID:0CyucYY1(3/3) AAS
eclのlocked packageなる概念やcompile-timeの意味論に関連しそうなissue
2 yeas agoだけど
外部リンク:gitlab.com
557(2): 2023/01/10(火)02:33 ID:/i8qCr3o(1/2) AAS
>>553
特定の名前の解決を決め打つ言語は多いし、そういうポリシーもありだと思う
普通でないのはcondition(warning)を挙げないところ
決め打つ名前(locked package?)が分かってる限りは、flet/labelsのレキシカル束縛リストから拾った名前がbody内の呼び出しformのcarに存在するか、ランタイムコストの無い自明な静的解析でconditionを挙げられるはず
558: 2023/01/10(火)03:18 ID:/i8qCr3o(2/2) AAS
>>550
等価と思って良いよ
伝統的なlisp(とcl)のように(let ((x '())) ...)を(let (x) ...)と略記できない、だとか細かい差異はあるけど
百聞は一見にしかずなので、構文の対応を見るのが手っ取り早い
あとeclのname collisionの件、consの例(>>553)はさすがにcontrived-exampleだと思うので、ついでにeclで破綻するように
letrec/nlet/labels で定義するラベルとして、所謂accumulatorイディオムにloop(他にはlp, iterとか)を使うのが慣例だけど、eclではcl:loopと読まれるのでは?と予想
;;; cl -- ok: cmucl, sbcl, clisp, gcl err:ecl (的中)
(defun fact (n)
(labels ((loop (k acc)
(if (= k 0)
acc
(loop (1- k) (* k acc)))))
(loop n 1)))
;;; scheme -- ok: guile
(define (fact n)
(letrec ((loop (lambda (k acc)
(if (= k 0)
acc
(loop (1- k) (* k acc))))))
(loop n 1)))
pcでテストはしたけど、スマホから手打ちなので変だったらごめん
559: はちみつ餃子 ◆8X2XSCHEME 2023/01/10(火)13:31 ID:TxpPtfKm(1) AAS
>>557
スクリプト言語 (処理系) 的な想定だと実行開始時にテキストの解釈から毎回やるので
静的解析もランタイムの一部みたいな感じになる。
この場合に限って言えばどちらにせよ名前のルックアップはやるのだからそのときにわかるだろうとは思うけど
静的解析を頑張らないという方針はあり得るんじゃないの。
560(2): はちみつ餃子 ◆8X2XSCHEME 2023/01/11(水)00:38 ID:s0T2WgwN(1/2) AAS
Gauche で検出されないエラーで (let ((0 1)) 0) みたいなのがあって、
実際にはオプティマイザが消去してしまうんだそうな。
文法の解析で通したものをオプティマイザがエラーとして弾くのも変な話だし、
オプティマイザが走査することがわかっているものを前段階でもチェックするのは二度手間だし、
オプティマイザを密結合してしまうのも保守しづらいし……
という葛藤があるのはわかる。
まあそれぞれに事情があるので原理的に可能だからといってそうすべきだとも言えない気がする。
561: 2023/01/11(水)00:49 ID:LBEzL6fs(1) AAS
0はシンボルじゃないから、文法解析を通しちゃ駄目だろw
562: 2023/01/11(水)01:29 ID:/IOcm4EW(1/8) AAS
そういう手では絶対書かないだろう変なコードも、マクロ書いてるとまれによく発生するから困る
563: 2023/01/11(水)01:59 ID:/IOcm4EW(2/8) AAS
カウンタ変数を捕捉更新しようとして、うっかり評価してしまったケースとか
564: 2023/01/11(水)02:21 ID:z40MB/0w(1) AAS
多分(let ((i (+ i 1))) i)が化けたのかな
565(2): 2023/01/11(水)02:34 ID:LWIYKuEk(1) AAS
letの時点でオプティマイザに通してんのかな
let系はlambdaまで落として((lambda(i) i) (+ i 1))とすれば間違えようがないと思うのだが
566: 2023/01/11(水)02:44 ID:/IOcm4EW(3/8) AAS
エスパー大会か?
(let ((i (+ i 1)))
(another-macro i))
another-macroは副作用目的で自明にiに展開したか、乗法的な関数を呼んだ(iの初期値0*n=0)
567: 2023/01/11(水)03:33 ID:4gRHy1NM(1) AAS
>>565
gancheは知らんけど、さすがにletはプリミティブな事が多いかと
むしろ最適化で読み飛ばすならlambdaまで還元してしまってはダメで、LETをヒューリスティックに認識する必要がある
仮に評価順を示す為にバッククォートでわざとらしく書くと
`(let ((,index ,(1+ stride))) ,(* index stride))
; (LET ((0 1)) 0)
(に等価な)展開とかがありがちかな
特に例に意味は無かったってオチだったりして
568: 2023/01/11(水)03:56 ID:/IOcm4EW(4/8) AAS
defmacro/macroexpand方式だと特にだけど、(let ((0 1)) 0)みたいな残骸から推論する技能はとても大事に思う
書く時もそうだけど、人が書いたモノの後始末なら前提知識が無いのでなおさら
これだけ想像を膨らませてくれる貴重な(let ((0 1)) 0)すら消し飛ばされるならもうお手上げ
なんて文句を言いつつ、schemeでもついslibのdefmacroに手が伸びてしまうのだが
569: 2023/01/11(水)06:03 ID:/IOcm4EW(5/8) AAS
>>565
論理的にどんなletが束縛リスト(とおそらくbodyも)を読み飛ばせるかについて補足
letフォームの評価値は最後のフォームの評価値(car (last 'let-form))のみで決まるけど、それが再束縛のできない自己評価オブジェクト(0, T/#t, :kw-symb etc)ならば、単にそれを返すだけで他を一切見る必要すら必要がない
(let dont-care/maybe-invalid self-evaluating)
→self-evaluating
もしそれ以上簡約してしまうと、(eq 'let (car 'let-form))と(car (last 'let-form))だけを見て決められない
570(1): 2023/01/11(水)06:21 ID:/IOcm4EW(6/8) AAS
一応値については正しいというだけで、もしbodyに(exit)や大域脱出が入ってても無視するのか?という問題はある
ill-formedな>>560すら無視するのだから、当然well-formedな(exit)も無視するのが自然だけど、実際のところはgaucheに訊いてください
571(1): はちみつ餃子 ◆8X2XSCHEME 2023/01/11(水)17:03 ID:s0T2WgwN(2/2) AAS
>>570
念のために補足しておくけど >>560 のケースは捕捉されないエラー
(現時点では捕捉することを意図的に諦めているエラー) であって
Gauche の仕様として正しいというわけではないよ。 結果は未定義。
直接的に書いてしまった場合にしてもマクロ展開結果でこうなるにしても
あくまでも誤っているプログラムだからね。
言いたかったのは >>557 に対してで、原理的に出来てもやらない事情の例として
(私は ECL のことは全然知らないので) Gauche での例を出したってだけ。
572(1): 2023/01/11(水)17:40 ID:/IOcm4EW(7/8) AAS
>>571
どうも、俺のも原理的には…という同じ意図の話だよ
eclやgaucheが有名実装では最もアグレッシブな感じなのかな?
(declaim (optimize (speed 0) debug safety)
が外せない俺には怖くて触れないよ
573: 2023/01/11(水)18:02 ID:/IOcm4EW(8/8) AAS
なおeclのlocked package?の件、標準の宣言を全て付けても有効な模様…
574: 2023/01/11(水)18:12 ID:qLQaVlgq(1) AAS
notinlineも効かないし独自機構だな
575: はちみつ餃子 ◆8X2XSCHEME 2023/01/14(土)01:01 ID:9ctkhBjT(1) AAS
>>572
> 有名実装では最もアグレッシブ
そんなことはないんじゃないかな。。
実行前の処理に時間をかけない (かけても総合的な性能向上にならない) という
判断でエラーチェックに消極的だけど最適化にも消極的だから。
576: 本田 2023/01/25(水)23:58 ID:PahnnjBC(1) AAS
UCB Scheme
外部リンク:people.eecs.berkeley.edu
UCB Scheme is a modified version of STk 4.0.1 by Erick Gallesio.
577: 2023/01/26(木)19:06 ID:lq03KzKz(1) AAS
USB Schemeじゃないのか
どっちかって言えばUSB Schemeが欲しいのだが
578: 2023/01/28(土)14:07 ID:BDgiT21v(1) AAS
nptcl
外部リンク:github.com
579: 本田 2023/01/29(日)22:24 ID:XMFhzyDs(1) AAS
アルゴリズム言語 Scheme 報告書 四訂版
H. Suzuki訳
外部リンク[texi]:groups.csail.mit.edu
580: はちみつ餃子 ◆8X2XSCHEME 2023/01/30(月)00:59 ID:kRDQpz8S(1) AAS
そのリンクがどうしたっていうんだ?
何か思うところがあるなら話題に挙げるのはかまわんが
ただリンクを置いて去るのはやめて欲しいな。
ニュース系のネタならお知らせの意味で貼ったのかなと思うところだが、
そういう感じでもないみたいだしな。
上下前次1-新書関写板覧索設栞歴
あと 275 レスあります
スレ情報 赤レス抽出 画像レス抽出 歴の未読スレ
ぬこの手 ぬこTOP 0.013s