##@rui314 本郷に進学した時の自己紹介で、「箪笥のようなアナログシンセを手作りしました」と言った同級生がいた時は「おいらワクワクしてきたぜ」と思ったものです。
#将来の Gauche に識別子マクロを導入する予定は無いのでしょうか? もしあるのだとしたら bar が 識別子マクロのとき (define-syntax foo bar) のように書くと bar を展開した結果を foo の変換子にするのか、 bar の変換子そのものの別名に foo とつけるのかが曖昧になるのではないかと思いました。
#するどい。Gaucheのセマンティクスでは、bar部分は普通の式としてマクロ展開時に評価する、というつもりでいました。従ってbarが識別子マクロであって、その式までに見えていれば、展開されます。
#(define-syntax ^ lambda) において、特別扱いされるのは^の束縛がマクロ展開フェーズに起きる、ということだけで、lambdaの評価はこれまでのGaucheと変わりません。つまり#<syntax> に評価されます。
#その点ではやっぱりGaucheの拡張ってことになりますね。RnRSではlambda単独では評価できませんから。
#より一般的には、
#(define-syntax name expr) の形は、(1)exprをマクロ展開時に評価する。その結果はsyntax handlerにならなければならない。(2)結果のsyntax handlerをマクロ展開時にnameに束縛、というセマンティクスになります。
#syntax handlerの具体的な表現はユーザには隠されていますが、(syntax-rules ...) を評価するとsyntax handlerになることは保証されます。あと、#<syntax>や#<macro>が返ってくるような式ですね。
#R6RSのdefine-syntaxではexprが「一引数の手続き」に評価されると決めてしまってて、これは実装の自由度を奪う失敗だったと思ってます。せめて (define-syntax name (syntax-transformer (lambda (x) ...))) みたいに一段フォームをかませてくれたら柔軟性が上がったのに。
#Gaucheでは「R6RS互換モード
#」でR6RS式のdefine-syntax「も」サポートする、という予定。
#なるほど。 Gauche 的には今までと大差ないんですね。 フェーズを分けただけで。
#はい。差が出るとすれば、フェーズを厳密に扱うようになった場合、lambdaのバインディングはexpandフェーズでのみ有効で、runフェーズではunboundになる、ということは考えられますが、フェーズを厳密に分けるのがいいのかどうかまだ思案中です。
#そういえばしばらく前に、にちゃんねるで Ypsilon では syntax-rules を評価した結果が手続にならないのは r6rs 的にどうなのって話題が出てたんですが、 r6rs でのマクロ変換子は構文オブジェクトを受け取って構文オブジェクトを返す手続きって理解でいいのかな。 その場ではマクロ変換子が手続きがどうかは明記されてないみたいなレスもあったんですけど。
##R6RSの記述がとても紛らわしいのですが、
#(1) 本体の方ではsyntax-rulesやidentifier-syntaxが評価された結果である
#transformerがどういうオブジェクトかについては定義されていない
#(2)ライブラリ仕様の方(section 12.3)では、"A transformer is a transformation procedure or a variable transformer. A transformation procedure is a procedure that must accept one argument, a wrapped syntax object (section 12.2) representing the input, and return a syntax object (section 12.2) representing the output." と明記されている。
#一応ライブラリ仕様とコア仕様はセットなので、私としては後者がtransformerの明示的な定義と考えるしかないとは思うのですが、「コア仕様の上にライブラリ仕様が乗っかってる」形になってない
#(逆転している)のが気持ち悪いところです。
#なるほど。 記述はあるんですね。