あなたが書くとき:
(def foo "a")
(def bar "b")
(def zip "c")
3つのシンボルを定義しました:foo
、bar
およびzip
値に関連付けられています:"a"
、"b"
および"c"
。
アソシエーションはnamsepaceテーブル内に格納されるため、REPLを使用する場合、名前空間はuser
デフォルトで使用されるため、ユーザー名前空間テーブルには次のものが含まれます。
{foo
#'user/foo
bar
#'user/bar,
zip
#'user/zip}
次のようにして、名前空間テーブルを表示できます。(ns-interns *ns*)
ここで、次のように記述します(foo bar zip)
。Clojure内では、リーダーがこれを読み取ることができる4つの異なる方法があります。どちらの方法で読むかを読者に指定する必要があります。そこで`
、'
そしてlist
登場します。
インジケーターがない場合:
(foo bar zip)
インジケーターなしで単純に記述された場合、リーダーはこれをS式として解釈foo
し、関数へのシンボルマッピングとして解釈し、関数bar
にzip
渡される値へのシンボルマッピングとして解釈しfoo
ます。
この場合、例外がスローされます。
java.lang.ClassCastException: java.lang.String cannot be cast to clojure.lang.IFn
これは、関数foo
が定義されておらず、IFn(Clojure関数)ではなく文字列であるfoo
に関連付けられていたためです。"a"
関数foo
が定義されている場合は、引数および。foo
として渡すことを呼び出します。"b"
"c"
の場合list
:
(list foo bar zip)
リスト記号を使用する場合、読者は実際にはこれをインジケーターなしの場合と同じように解釈します。つまり、にマップされた関連する値を引数として受け取る関数にマップされたシンボルを探していますlist
。この関数は、clojure.core名前空間内のClojureによって事前定義されています。引数のリストを返します。foo
bar
zip
list
したがって、リーダーがをlist
検索すると、clojure.core関数が検索され、次にfoo
シンボルが検索され、にマップされていることがわかります"a"
。シンボルのすべてのマッピングが見つかるlist
と、関連する値である。を呼び出して渡しfoo bar zip
ます"a" "b" "c"
。だから(list foo bar zip)
と同じ(list "a" "b" "c")
です。
の場合'
:
'(foo bar zip)
引用は、次の'
フォームがそのまま読まれることを読者に伝えます。この場合foo
、、、bar
およびzip
は記号であり、(foo bar zip)
記号のリストです。したがって、読者はこれを記号のリストとして解釈します。
そのため、実行する(apply str '(foo bar zip))
と、が呼び出さstr 'foo 'bar 'zip
れますfoobarzip
。つまり、シンボルのリスト内の各シンボルを文字列表現に変換してから、これらを1つの文字列に連結します。
そのままの形をとることにより、シンボルを評価することなく、つまり、それらが関連付けられているものを探すことなく、引数としてシンボルのリストを渡します。実行した場合は、(eval '(foo bar zip))
シンボルのリストをに渡し、シンボルを値に評価して、シンボルがマップされている値のリストを返します。したがって、引用符はコードをコードとして渡すものと考えることができます。eval
eval
'
の場合`
:
`(foo bar zip)
これはもう少し複雑です。読者はバッククォートを確認し`
、シンボルのリスト内のシンボルを再帰的に解決して、完全に修飾されたシンボルのリストを取得します。
基本的に、リーダーがシンボルのテーブル内のシンボルを検索するとき、それは現在の名前空間のシンボルのテーブルから検索します。完全修飾シンボルは、名前空間情報を含むシンボルです。したがって`(foo bar zip)
、リーダーを実行すると、これらの記号が完全に修飾された記号に置き換えられ、に変換され(user.foo user.bar user.zip)
ます。
リスト内の要素の一部を評価し、他の要素を完全修飾記号に変更するように読者に指示することができます。そのためには、評価するシンボルの前に次のように接頭辞を付けます~
。
`(foo ~bar zip)
あなたに与える
(clojure.foo "b" clojure.zip)
事実上、バッククォートは、評価しないという点でクォート`
と非常によく似ていますが、コード内のシンボルを完全に修飾することによって返されるコードを操作することを除いて、単にコードを返します。'
これは、マクロに影響を及ぼします。完全に修飾された参照が必要な場合や、別の名前空間からフェッチする場合があります。また、現在の名前空間でこのシンボルを探すという柔軟性が必要な場合もあります。