丁寧な解説ありがとうございました。 エラー検出を省略する場合があるのですね。知らなかったので不正でない値なのかどうか迷いました。 推測に関してはご明察通りです。具体的に何か作っているわけではないのですが、機能を試していたら気になったので。 おかげさまでスッキリしました。 2018年11月18日(日) 21:54 Shiro Kawai <shiro****@gmail*****>: > そのcase-lambdaフォームは不正ですが、Gaucheがエラーを出していないだけです。 > > 1) (case-lambda ((<formals> <body> ...) ...)) > で、<formals>に来ることができるのは、R7RSの(lambda <formals> <body> ..) の > <formals>と同じです。つまり > > (<variable> ...) > (<variable> ... . <varlable>) > <variable> > > > のいずれかの形式しか許されません。問題のcase-lambdaの最初の節では<formals>が((a))になっていて、これは許される形式ではありません。 > > 2) > Gaucheは実行に差し支えない場合にエラー検出を省略することがよくあります。case-lambdaのコンパイルでは、各節の<formals>が受け取る引数の個数を数えてディスパッチテーブルを作るのですが、その時は単に数だけ数えていて引数の部分が実際に<variable>になっているかどうかをチェックしていません。なので((a))も(b)も「引数がひとつの場合」と解釈され、どちらか一方のみが有効になります(今回の場合は最初の節)。そして、その節内ではaはローカル変数とは認識されておらず、グローバルなaが参照されます。 > > なお、仕様としては、不正なプログラムを実行した場合の挙動は未定義です。なので元が不正なら何が起きても「想定どおり」です。 > > 3) おそらく元のコードは、パターンマッチで (f 1) と (f '(1)) > を区別したいという意図だったのではありませんか。RnRS内でそれを一発でやるフォームはありませんが、util.matchのmatch-lambda*を使えば可能です。 > > (use util.match) > (define f > (match-lambda* > [((a)) (print "a:" a)] > [(b) (print "b:" b)])) > > gosh> (f 1) > b:1 > #<undef> > gosh> (f '(1)) > a:1 > #<undef> > > > > > > > > On Sun, Nov 18, 2018 at 2:32 AM akim muto <work.****@gmail*****> > wrote: > >> メーリングリストの皆さんはじめまして、akimと名乗っております。 >> >> (define a "global") >> (define f >> (case-lambda >> (((a)) (print a)) >> ((b) (print b)))) >> と定義して実行すると >> (f "1")→global >> という結果になるのですが、これはたまたまそういう結果になっているのでしょうか。それとも想定通りの動作なのでしょうか。 >> _______________________________________________ >> Gauche-devel-jp mailing list >> Gauch****@lists***** >> https://lists.osdn.me/mailman/listinfo/gauche-devel-jp > > _______________________________________________ > Gauche-devel-jp mailing list > Gauch****@lists***** > https://lists.osdn.me/mailman/listinfo/gauche-devel-jp -------------- next part -------------- HTMLの添付ファイルを保管しました... URL: <https://lists.osdn.me/mailman/archives/gauche-devel-jp/attachments/20181118/1a3462df/attachment-0001.html>