2010-08-02 4 views
4

공통 LISP에서 나는 할 수있다 : 나는고의적 인 Clojure 심볼 이름 제한 또는 상속?

(def a1 'a) 

(setf의이 수비력 다르게 작동한다는 사실을 무시하고) 첫 번째 작업을 수행 할 수 있습니다 Clojure의에서

(setf a1 'a) 
(setf 1a 'b) 

을하지만 두 번째로 오류가 발생합니다

(def 1a 'b) 

java.lang.NumberFormatException: Invalid number: 1a 

Clojure는이 제한을 Java에서 상속 받았습니까? 아니면 의도적입니까? (즉,이 스타일로 자바 클래스 이름, 변수 또는 메서드 이름을 가질 수 없습니다. 따라서이 언어가 방금 전수되었다고 가정합니다.)

+1

Common Lisp에서 부합하는 구현은 Clojure가 시도하는 것처럼 (심지어 큰 값으로 설정된'read-base *가 없어도) '1a'를 숫자로 파싱 할 수 있습니다. 10 이상). HyperSpec에서 잠재적 인 항목에 대한 항목을 참조하십시오. http://www.lispworks.com/documentation/HyperSpec/Body/02_caa.htm –

답변

11

Clojure의 기호 리터럴 are documented은 숫자가 아닌 문자로 시작해야합니다. 이것은 Java 식별자 나 숫자 리터럴 구문과는 아무런 관련이 없습니다. Clojure 심볼 리터럴은 clojure.lang.LispReaderread 메소드가 심볼로 읽으며 Java 식별자에서 허용되지 않는 Clojure 심볼 리터럴 내에 허용되는 문자 수 (예 : -, > ...도 있습니다.이 두 문자를 _GT_ (예 : > interop 용)과 같이 문자 시퀀스로 변환하는 체계가 있습니다. 오류의 직접적인 원인은 숫자를보고 즉시 readNumber으로 clojure.lang.LispReader/read을 파견하고 그 중 하나를 "되돌릴"방법이 없다는 것입니다.


완전성을 위해 접선 논의.

참고가 손으로 기호를 구성하는 경우, 당신은 바르 이름을 사용할 수 : 심지어

user> (eval `(defrecord ~(symbol "1foo") [])) 
user.1foo 
user> user.1foo 
user.1foo 
user> (user.1foo.) 
#:user.1foo{} 

처럼 펑키 물건을 할 수

;; Clojure's intern serves a different purpose to CL's intern, see (doc intern) 
user> (intern *ns* (symbol "1+") inc) 
#'user/1+ 
user> ((ns-resolve *ns* (symbol "1+")) 1) 
2 

...입니다 물론 완전히 미친 것 같지만

user> (in-ns (symbol "1foo")) 
#<Namespace 1foo> 
1foo> (clojure.core/refer-clojure) 
nil 
1foo> (defrecord Foo []) 
1foo.Foo 
1foo> (in-ns 'user) 
#<Namespace user> 
user> (1foo.Foo.) 
; Evaluation aborted. ;; can't do that 
user> (eval `(new ~(symbol "1foo.Foo"))) 
#:1foo.Foo{} 

나는 사람이 이런 종류의 일을 주장한다면 ngs, 궁극적으로 JVM 제한에 부딪 힐 것입니다. 어쨌든, 원래의 질문으로 돌아가서 1+에 의해 야기 된 오류는 기호 리터럴 구문과 관련이 있습니다.이 문자 리터럴 구문은 합리적인 "번역"이 존재할 정도로만 Java에 친숙합니다 . 펑키 한 이름을 사용하는 것은 다루기 힘들고 확실히 지원되지 않지만, 이름이있는 Clojure 객체는 그 이름이 잘 형성되어 있는지 또는 그렇지 않은지에 대해별로 신경 쓰지 않는다.

(위 예제의 user.1foo은 실제로 자바 클래스입니다. 다른 한편으로는 이름에 대한 JVM의 내부 제한 사항을 생각해 보았지만 실제로이 코드가 실제로 작동했는지 놀랍습니다.