1

ここに私の小さなプログラムがあります:

(let-syntax ((alpha (lambda (x)
                      (list (syntax quote)
                            (list)))))
  (alpha))

そしてguileはそれを実行し、()を返します。しかし、mit-scheme は以下を出力します:

;Syntactic binding value must be a keyword: alpha
;To continue, call RESTART with an option number:
; (RESTART 1) => Return to read-eval-print level 1.

なんで?

(私のバージョンは: リリース 9.1 || マイクロコード 15.3 || ランタイム 15.7 || SF 4.41 || LIAR/i386 4.118 || Edwin 3.116)

4

2 に答える 2

1

リンク先のドキュメントは、let-syntax で構文規則を絶対に使用する必要があることを明示的に示しています。これが正確な構文コントラクトです。

    <macro block> ==>
          (let-syntax (<syntax spec>*) <body>)
         | (letrec-syntax (<syntax spec>*) <body>)
    <syntax spec> ==> (<keyword> <transformer spec>)
    <transformer spec> ==>
          (syntax-rules (<identifier>*) <syntax rule>*)

仕様上、syntax-rules 以外を使用してもエラーが発生することは期待できません。これが Guile ではなく MIT スキームでエラーを生成する唯一の理由は、MIT スキームの例外の適用がより多用されているためです (つまり、MIT スキームの let-syntax は、構文規則を指定したことを明確に確認するように見えます)。これは単純に有効な R4RS コードではなく、R4RS 互換の Scheme 実装では機能しないはずです。

于 2012-11-10T06:19:11.333 に答える
1

MIT スキームはsyntax-rules、 、構文クロージャ、および構文トランスフォーマを定義するための明示的な名前変更のみを提供します。後者の 2 つの場合は、sc-macro-transformerまたはer-macro-transformerフォームのいずれかが必要です。構文オブジェクトを使用する場合は、 RacketGuilesyntax-caseなどの構文オブジェクト (通常は に付属) をサポートする実装を使用する必要があります。

ところで、構文オブジェクトを使用する言語でも、構文ではなくトランスフォーマーからリストを返すため、マクロ定義が機能しない場合があります。また、リンク先の Web ページはかなり古い標準です。TSPL4など、マクロに関するより最近のソースを読みたいと思うかもしれません。

于 2012-11-10T23:37:33.407 に答える