2016-08-09 11 views
0

変数が現在定義されているかどうかを実行時に決定する方法はありますか?チキンスキームに変数が存在するかどうかを調べる方法は?

(let ((var 1)) 
(print (is-defined? var)) ; #t 

(print (is-defined? var)) ; #f 

EDIT:XY problem。

コードを生成するマクロを作成しています。この生成されたコードは、相互再帰でマクロを呼び出す必要があります。マクロを呼び出すだけでは動作しません。マクロが再帰的に呼び出されるとき、最初に呼び出されたときとは異なる振る舞いをする必要があります。ネストされた関数を使用しますが、それはマクロです。

ラフ例:

(defmacro m (nested) 
(if nested 
    BACKQUOTE(print "is nested") 
    BACKQUOTE(m #t) 

(はい、私は、スキームはdefmacroの使用していないけど、私は、Common Lispのから来ている。また、私はそれなしでここにすべての予定をバッククォートを置くように見えることはできません。 )

マクロのINITIAL呼び出しでは、再帰的に呼び出されたときにのみ意味を持つ余分な引数を取ることは望ましくありません。私は他の手段でそれを知りたい。

最初のマクロ内でネストされ、コールサイトに存在しないマクロを呼び出すために、生成されたコードを取得できますか?たとえば、(macro)の代わりに(,other-macro)を呼び出すコードを生成しますか? Schemeはレキシカルスコープされているので

しかし、機能があるように、マクロはファーストクラスのオブジェクトではないので、それは、動作しないはず...

+0

これはコンパイル時/書き込み時に知っておく必要があります。 XY?それをどうする予定ですか? – Sylwester

+0

私は質問に詳細を追加しました。 –

答えて

0

は、一般的にそれをする方法はありません。参照されている未定義の変数がエラーである場合に変数が定義されているかどうかを調べることは、あまり意味がありません。

トップレベル/グローバル変数の場合は、symbol-utils eggを使用できますが、モジュール内のグローバル変数もまた別のものに書き換えられることを考慮すると、おそらく期待通りに動作しません。

おそらくと言うことができる場合は、実際にはの代わりに解決策をお手伝いできます。

+0

キーワードとオプションのパラメータをサポートする 'destructuring-bind'マクロを書こうとしています。このためには、コードを再帰的に生成する必要があります。再帰呼び出しはキーワードモードであるかどうかを知る必要があります。ネストされたメソッドを使用することはできません。マクロであり、マクロを再度呼び出すコードを再帰的に生成する必要があるからです。マクロがモードパラメータを受け入れることは意味がありません。なぜなら、最初のインスタンスではヌル引数で呼び出さなければならないからです。私が必要とするのは、存在するかもしれないし、存在しないかもしれない字句的結合であり、それに応じて反応する。 –

1

再帰的なマクロを書くと、マクロ展開(m a b ...)がになる(m-helper a (b ...))になるという印象を受けます。つまり、ではなく、が直接再帰的です。なぜなら、コードをコードに変換してマクロを含むことになるからです。

destructuring-bindでは、実際には2つの変数を追跡するだけです。 carの一つとcdr用とフォームから来ていないものの名前を変更し、これhygenicされる暗黙の名前を変更するマクロで:

(define-syntax destructuring-bind 
    (ir-macro-transformer 
    (lambda (form inject compare?) 
    (define (parse-structure structure expression optional? body) 
     ;;actual magic happens here. Returns list structure with a mix of parts from structure as well as introduced variables and globals 
     ) 

    (match form 
     [(structure expression) . body ] 
     `(let ((tmp ,expression)) 
      ,(parse-structure structure 'tmp #f body)))))) 

入力から何かがあなたが供給compare?手順を使用するのと同じシンボルであるかどうかを確認するには。例えば。 (compare? expression '&optional)

+0

これは本当です。マクロはオプションの引数を取ることができます。あるいは、 'let-syntax'を使って、ローカルに見えるマクロを作成することができます。また、低レベルのマクロからヘルパープロシージャを呼び出すことができます。マクロが他のマクロだけを呼び出す必要はありません。 'use-for-syntax'を使ってライブラリをロードするか、' syntax-for'の形で自分自身を定義してください。インスピレーションを得るには、[matchable](http://wiki.call-cc.org/eggref/4/matchable)の卵の実装を見てください。これはこれに非常に近いものです。そして、[bindings](http://wiki.call-cc.org/eggref/4/bindings)の卵があります。 – sjamaan

関連する問題