11

以下のマクロを考えると -

(defmacro defhello [fn-name body]   `(defn ~fn-name [~'name] ~body))

そして、呼び出されたときに定義された関数 -

(defhello greeting (str "Hello" name))

と呼ばれる

(あいさつ「ジョー」)

、 戻ります

Hello Joe

nameパラメータの前の ~' の使い方がわかりませんか? それは何をするためのものか?引用しない (') と引用しない (~) は互いにキャンセルしますか? 一緒に使うとどうなる?それらなしで名前を書いてみませんか?

4

3 に答える 3

9

つまり、 は の~場合と同様に、構文引用符で囲まれた形式で式を評価します~fn-name。この場合、評価する式は'nameであり、結果は修飾されていない記号nameです。

ただし、これを一度に 1 つずつ分解してみましょう。

非修飾シンボルしかない場合は、実行時に1nameと評価されます。これにより、フォームが正しくなくなり、コンパイラ例外が発生します。clojure.core/namedefn

(defn greeting [clojure.core/name] (str "Hello" name)) 

引用符で囲まれた非修飾シンボルしかない場合'nameでも、実行時に評価されます。違いは、 に展開されること(quote clojure.core/name)です。繰り返しますが、これは不適切なdefn形式になり、コンパイラ例外が発生します。

(defn greeting [(quote clojure.core/name)] (str "Hello" name))

最後に、 を使用~'nameすると、引用された形式がコンパイル時に評価され、修飾されていない記号 が生成されname、適切なdefn形式が得られます。

(defn greeting [name] (str "Hello" name))

name1 - これは、別の関数が存在しないことを前提としているため、この例に当てはまります。

于 2012-09-10T15:40:22.913 に答える
2

私が理解しているように、関数定義を引用しているので、マクロが定義されたときに評価されません。unquote演算子~を使用して、定義内の名前を評価します。名前が一種のリスト~@(引用符で囲まれていないスプライス)の場合、周囲の角かっこなしでリストの要素を評価します。

于 2012-09-10T13:25:11.820 に答える
1

名前の前の引用符は、記号が修飾されないようにするために使用されます。

対象となるものがわからない場合は、リーダーを参照してください

さらに、マクロのデバッグにmacroexpandを使用できます。

また、マクロについて詳しく知りたい場合は、OnLispを読むことをお勧めします。少し難しいかもしれませんが、マクロがどのように機能するかを教えてくれます。

于 2012-09-10T15:53:05.073 に答える