私はずっと前から、他のLisp(特にScheme)についての知識を持っています。最近、私はClojureについて読んでいます。「記号」と「キーワード」の両方があることがわかります。私がよく知っているが、キーワードではない記号。
他のLispにはキーワードがありますか?キーワードは、表記が異なる(つまり、コロン)以外の記号とどのように異なりますか?
私はずっと前から、他のLisp(特にScheme)についての知識を持っています。最近、私はClojureについて読んでいます。「記号」と「キーワード」の両方があることがわかります。私がよく知っているが、キーワードではない記号。
他のLispにはキーワードがありますか?キーワードは、表記が異なる(つまり、コロン)以外の記号とどのように異なりますか?
回答:
ここだClojureの文書のキーワードと記号については。
キーワードは、それ自体を評価する記号識別子です。彼らは非常に高速な同等性テストを提供します...
シンボルは、他の何かを参照するために通常使用される識別子です。これらはプログラム形式で使用して、関数パラメーターを参照したり、バインディング、クラス名、グローバル変数を使用したりできます...
キーワードは一般に、軽量の「定数文字列」として使用されます。たとえば、ハッシュマップのキーやマルチメソッドのディスパッチ値などです。シンボルは通常、変数と関数に名前を付けるために使用され、マクロなどを除いて、それらをオブジェクトとして直接操作することはあまり一般的ではありません。しかし、キーワードを使用するすべての場所でシンボルを使用することを妨げるものは何もありません(常に引用することを気にしなければ)。
違いを確認する最も簡単な方法は、読むことですKeyword.java
し、Symbol.java
Clojureのソースで。いくつかの明らかな実装の違いがあります。たとえば、Clojureのシンボルはメタデータを持つことができ、キーワードは持つことができません。
シングルコロン構文に加えて、ダブルコロンを使用して名前空間修飾キーワードを作成できます。
user> :foo
:foo
user> ::foo
:user/foo
Common Lispにはキーワードがあり、Rubyや他の言語と同じです。もちろん、これらの言語では少し異なります。Common LispキーワードとClojureキーワードのいくつかの違い:
Clojureのキーワードはシンボルではありません。
user> (symbol? :foo)
false
特に限定しない限り、キーワードはどの名前空間にも属しません。
user> (namespace :foo)
nil
user> (namespace ::foo)
"user"
(見るもののアイデアをくれてくれたRainer Joswigに感謝します。)
(eval (eval ':a))
vs (eval (eval ''a))
。他に利点はありますか?パフォーマンスに関しては、それらは同じですか?
Common Lispにはキーワード記号があります。
キーワードも記号です。
(symbolp ':foo) -> T
キーワードが特別な理由:
それ以外の場合、キーワードは通常の記号です。したがって、キーワードは関数に名前を付けたり、プロパティリストを持つことができます。
注意:Common Lispでは、シンボルはパッケージに属しています。これは次のように書くことができます:
:foo、keyword:fooおよびkeyword :: fooがすべて同じシンボルであることを意味するキーワードシンボルの場合。したがって、後者の2つの表記は通常使用されません。
したがって、シンボル名の前にパッケージ名を指定しないと、デフォルトではKEYWORDパッケージが使用されると想定して、:fooは解析されてパッケージKEYWORDに含まれるようになります。
キーワードはそれ自体が評価する記号なので、引用することを覚えておく必要はありません。
:keywordsも多くのコレクションで特別に扱われるため、非常に便利な構文を使用できます。
(:user-id (get-users-map))
と同じです
((get-users-map) :user-id)
これは少し物事をより柔軟にします
キーワードはグローバルですが、シンボルはグローバルではありません。
この例はJavaScriptで記述されていますが、要点を伝えるのに役立つことを願っています。
const foo = Symbol.for(":foo") // this will create a keyword
const foo2 = Symbol.for(":foo") // this will return the same keyword
const foo3 = Symbol(":foo") // this will create a new symbol
foo === foo2 // true
foo2 === foo3 // false
Symbol
関数を使用してシンボルを作成すると、毎回個別/プライベートシンボルが取得されます。Symbol.for
関数を介してシンボルを要求すると、毎回同じシンボルが返されます。
(println :foo) ; Clojure
System.out.println(RT.keyword(null, "foo")) // Java
console.log(System.for(":foo")) // JavaScript
これらはすべて同じです。
関数の引数名はローカルです。つまり、キーワードではありません。
(def foo (fn [x] (println x))) ; x is a symbol
(def bar (fn [x] (println x))) ; not the same x (different symbol)