有意识的Clojure符号名称限制还是继承?

haw*_*eye 4 java jvm clojure

在Common LISP中我可以做到:

(setf a1 'a)
(setf 1a 'b)
Run Code Online (Sandbox Code Playgroud)

在clojure中我可以做第一个(忽略setf和def工作不同的事实)

(def a1 'a)
Run Code Online (Sandbox Code Playgroud)

但是第二次我得到了一个错误

(def 1a 'b)

java.lang.NumberFormatException: Invalid number: 1a
Run Code Online (Sandbox Code Playgroud)

Clojure刚刚从Java继承了这个限制,还是故意的?(即你不能拥有带有这种风格的Java的类名,变量或方法名称 - 所以我认为它刚刚进行过.)

Mic*_*zyk 11

Clojure的符号文字都记录到需要启动一个非数字字符.这无关与Java标识符或数字文本语法-一个Clojure的符号文字是什么clojure.lang.LispReaderread一个符号方法读取并有一批不属于在Java中标识的受理条件(如Clojure的符号文字中允许的字符-,>. ..;还有还有用于翻译那些为字符序列,如方案_GT_对于>互操作的目的).错误的直接原因是在看到数字后立即clojure.lang.LispReader/read发送,readNumber并且无法"退出"该数字.


为了完整起见,进行切向讨论.

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

;; 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
Run Code Online (Sandbox Code Playgroud)

你甚至可以做像时髦的东西

user> (eval `(defrecord ~(symbol "1foo") []))
user.1foo
user> user.1foo
user.1foo
user> (user.1foo.)
#:user.1foo{}
Run Code Online (Sandbox Code Playgroud)

......这当然是完全疯狂的,尽管可能没那么多

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{}
Run Code Online (Sandbox Code Playgroud)

我想如果一个人坚持做这类事情,最终会遇到JVM限制.这样做当然没有好的目的......无论如何,回到原来的问题,由1+符号文字语法引起的错误只是在合理的"翻译"存在的程度上对Java友好.具有名称的Clojure对象并不关心那些格式正确的名称或其他名称,尽管使用时髦的名称是笨拙的并且绝对不受支持.

(user.1foo从上面的示例实际上是一个Java类 - 我有点惊讶地看到这个实际上有效,但另一方面我似乎记得JVM对名称的内部限制应该不如Java的那些.)