Java 故意的Clojure符号名称限制或继承?

Java 故意的Clojure符号名称限制或继承?,java,clojure,jvm,Java,Clojure,Jvm,在Common LISP中,我可以执行以下操作: (setf a1 'a) (setf 1a 'b) 在clojure中,我可以做第一个(忽略setf和def工作方式不同的事实) 但是第二次我犯了一个错误 (def 1a 'b) java.lang.NumberFormatException: Invalid number: 1a Clojure是从Java继承了这个限制,还是故意的?(也就是说,Java不能使用这种样式的类名、变量或方法名,所以我假设它刚刚被使用过。)Clojure的符号

在Common LISP中,我可以执行以下操作:

(setf a1 'a)
(setf 1a 'b)
在clojure中,我可以做第一个(忽略setf和def工作方式不同的事实)

但是第二次我犯了一个错误

(def 1a 'b)

java.lang.NumberFormatException: Invalid number: 1a
Clojure是从Java继承了这个限制,还是故意的?(也就是说,Java不能使用这种样式的类名、变量或方法名,所以我假设它刚刚被使用过。)

Clojure的符号文本需要以非数字字符开头。这与Java标识符或数字文字语法无关——Clojure符号文字是任何
Clojure.lang.LispReader
read
方法作为符号读入,并且Clojure符号文字中允许的字符数在Java标识符中是不允许的(例如,
-
..;还有一种方案可以将这些字符转换为字符序列,例如
\u GT\u
,以实现互操作)错误的直接原因是
clojure.lang.LispReader/read
在看到一个数字后立即发送到
readNumber
,无法“退出”


为了完整性而进行的无关紧要的讨论

请注意,如果手动构造符号,则可以使用它来命名变量:

;; 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> (eval `(defrecord ~(symbol "1foo") []))
user.1foo
user> user.1foo
user.1foo
user> (user.1foo.)
#:user.1foo{}
…这当然是完全疯狂的,尽管可能没有

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{}
user>(以ns(符号“1foo”)表示)
#
1foo>(clojure.core/参考clojure)
无
1foo>(defrecord Foo[]
1foo.Foo
1foo>(在ns的用户中)
#
用户>(1foo.Foo.)
;评估中止;;不能那样做
用户>(eval`(新的(符号“1foo.Foo”))
#:1foo.Foo{}
我想,如果坚持做这类事情,最终会遇到JVM的局限性。这样做当然没有什么好的目的……无论如何,回到最初的问题,
1+
引起的错误与符号文字语法有关,符号文字语法对Java的友好程度仅限于合理的“翻译”存在。有名称的Clojure对象不太关心这些名称的格式是否正确,尽管使用时髦的名称很麻烦,而且绝对不受支持


(上面例子中的
user.1foo
实际上是一个Java类——我有点惊讶地看到这个类实际上已经工作了,尽管另一方面我似乎记得JVM对名称的内部限制应该没有Java严格。)

请注意,在Common Lisp中,一致性实现可以将
1a
解析为数字,就像Clojure尝试解析一样(即使
*read base*
设置为大于10的值)。请参阅HyperSpec中关于潜在数字的条目:
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{}