나는 다른 Lisps (특히 Scheme)에 대한 지식을 가지고 있습니다. 최근에 Clojure 에 대해 읽었습니다 . “기호”와 “키워드”가 모두있는 것을 알 수 있습니다. 익숙하지만 키워드에는 익숙하지 않은 기호.
다른 Lisp에 키워드가 있습니까? 다른 표기법 (예 : 콜론)이 아닌 다른 키워드와 기호가 어떻게 다른가요?
답변
키워드 및 기호에 대한 Clojure 설명서 는 다음과 같습니다 .
키워드는 스스로 평가되는 기호 식별자입니다. 그들은 매우 빠른 평등 테스트를 제공합니다 …
기호는 일반적으로 다른 것을 나타내는 데 사용되는 식별자입니다. 그들은 함수 매개 변수를 참조하고 바인딩, 클래스 이름 및 전역 변수를 참조하도록 프로그램 형태로 사용할 수 있습니다 …
키워드는 일반적으로 가벼운 “일정한 문자열”로 사용됩니다 (예 : 해시 맵의 키 또는 멀티 메소드의 디스패치 값). 기호는 일반적으로 변수와 함수의 이름을 지정하는 데 사용되며 매크로 등을 제외하고 직접 개체로 조작하는 것은 일반적이지 않습니다. 그러나 키워드를 사용하는 모든 곳에서 기호를 사용하는 것을 막을 수있는 것은 없습니다 (항상 인용하는 것이 마음에 들지 않는 경우).
차이를 볼 수있는 가장 쉬운 방법은 읽을 수 Keyword.java
와 Symbol.java
Clojure의 소스에서. 몇 가지 명백한 구현 차이가 있습니다. 예를 들어 Clojure의 Symbol에는 메타 데이터가 있고 키워드에는 없습니다.
단일 콜론 구문 외에도 이중 콜론을 사용하여 네임 스페이스로 한정된 키워드를 만들 수 있습니다.
user> :foo
:foo
user> ::foo
:user/foo
일반적인 Lisp에는 Ruby 및 기타 언어와 마찬가지로 키워드가 있습니다. 물론 해당 언어에서는 약간 다릅니다. 공통 Lisp 키워드와 Clojure 키워드의 일부 차이점 :
-
Clojure의 키워드는 기호가 아닙니다.
user> (symbol? :foo) false
-
구체적으로 규정하지 않은 키워드는 네임 스페이스에 속하지 않습니다.
user> (namespace :foo) nil user> (namespace ::foo) "user"
( 볼만한 것들에 대한 아이디어를 주신 Rainer Joswig 에게 감사드립니다 .)
답변
공통 Lisp 에는 키워드 기호가 있습니다.
키워드도 상징입니다.
(symbolp ':foo) -> T
키워드를 특별하게 만드는 이유 :
- : foo는 Common Lisp 판독기에서 symbol 키워드 :: foo로 구문 분석됩니다.
- 키워드는 다음과 같이 평가됩니다. : foo-> : foo
- 키워드 기호의 홈 패키지는 키워드 패키지입니다. keyword : foo-> : foo
- 키워드 KEYWORD에서 키워드를 내 보냅니다.
- 키워드는 상수이며 다른 값을 할당 할 수 없습니다
그렇지 않으면 키워드는 일반적인 기호입니다. 키워드는 함수의 이름을 지정하거나 속성 목록을 가질 수 있습니다.
기억하십시오 : 공통 Lisp 기호는 패키지에 속합니다. 이것은 다음과 같이 쓸 수 있습니다 :
- foo, 현재 패키지에서 기호에 액세스 할 수있는 경우
- 패키지 BAR에서 FOO 기호를 내보낼 때 foo : bar
- FOO 기호가 패키지 BAR에있을 때 foo :: bar
키워드 기호의 경우 : foo, keyword : foo 및 keyword :: foo는 모두 동일한 기호입니다. 따라서 후자의 두 표기법은 일반적으로 사용되지 않습니다.
따라서 : foo는 심볼 이름 앞에 패키지 이름을 지정하지 않으면 기본적으로 KEYWORD 패키지를 의미한다고 가정하고 패키지 KEYWORD에 포함되도록 구문 분석됩니다.
답변
키워드는 자체 평가되는 기호이므로 따로 인용 할 필요가 없습니다.
답변
: 키워드는 많은 컬렉션에서 특별히 처리되므로 실제로 편리한 구문을 사용할 수 있습니다.
(: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)