2024 Clojure 状态调查! 中分享您的想法。

欢迎!请参阅 关于 页面以了解更多关于如何使用本站的信息。

0 投票
ClojureScript

ClojureScript:foo> (r/read-string ":0") "Error evaluating:" (r/read-string ":0") :as "cljs.reader.read_string.call(null,\":0\")" org.mozilla.javascript.EcmaError: TypeError: Cannot read property "0.0" from null (file:/home/chas/dev/clojure/cljs/.repl/cljs/reader.js#451)

关键字开头数字的话题是分开讨论的,因为Clojure已经支持一段时间了,但现在可以将其视为规范的一部分。请参见 CLJ-1286。

顺便说一句,这又是另一项(链接:https://github.com/reiddraper/simple-check/ 文本:simple-check)的胜利... :-)

11 个答案

0 投票
评论由:cemerick

这不是一个简单的正则表达式更改,正如我最近的Clojure热情所希望的。{{cljs.reader}} 中的符号模式忠实于Clojure HEAD,但匹配的处理不是。我认为可能没有必要确定修复现有的内容还是迁移{{clojure.tools.reader.impl.commons/parse-symbol}}(顺便说一句,它不使用正则表达式)……无论如何,留给另一个人做吧(或者如果他们愿意的话)。
0 投票

评论由:favila

我认为我修复了您提到的匹配处理问题(CLJS-775 CLJS-776)。然而,我对这一点和 CLJ-1286 仍然感到困惑。Clojure 读取器文档和 edn 规范仍然表示应该拒绝 :0,但 1.6.0 并不这么做。期望的行为是什么?规范会得到修复,或者clojure 读取器在被下游包修复之后修复?

0 投票
by

评论者:wagjo

据我所知,EDN规范不拒绝:0(没有规则说第二个字符不能是数字)。请参阅https://github.com/wagjo/serialization-formats,了解我对现有规范的解读。

0 投票
by

评论由:favila

啊,我想我明白了困惑的原因。EDN和clojure reader规范都说类似这样的话:“关键字类似于符号,但不以冒号开头。”困惑在于我们是否将其解释为

  1. 第一个字符是冒号,然后第二个字符及其之后与符号定义匹配。
  2. 第一个字符是冒号,整个形式与符号定义匹配。

CLJ-1003、CLJ-1252、CLJ-1286以及我自己都似乎是理解第一种含义。这可能是因为当我们说“关键字的第一个字符”时,我们通常指的是冒号之后的第一个字符,就像冒号是“特殊”的,而不是关键字的一部分(例如,如读取宏字符)。

然而,clojure 1.6似乎遵循第二种含义(并解释了为什么:0/a是可行的,但不是:0/0),并且我不确定从引用的票据和谷歌群组讨论中,这是否是因为下游损坏,或者这是预期的解释,CLJ-1252的补丁被Alex Miller错误地接受了。

注意,如果我们接受第二种解释,那么“一个符号可以包含一个或多个非重复的冒号”这一限制来自clojure reader文档,对于关键字是不正确的。(EDN似乎不允许命名空间展开的关键字,所以那里没有问题。)

此外,EDN允许符号中出现连续的冒号,而clojure 1.6和reader规范则不允许。

0 投票
by

评论由:favila

此外,clojure 1.6允许{{a/:a}}和{{:a/:a}}(其中名称部分违反了符号的第一个字符规则),即使规范没有这样的规定。(这在上面的表格中没有提及。不过,这是一项非常彻底的工作!我希望reader规范更加正规和明确……)

0 投票
by

评论由:favila

我认为这个模式符合规范

`

"(?x)

(?!///) # 边界情况:/ 只允许在名称部分。

符号或关键字的名称部分或命名空间部分

(?:
#除法符号
(/
#普通符号
|[a-zA-Z*!_?$%&=<>][0-9a-zA-Z*!_?$%&=<>\#:+.-]
# 以 [-+.] 开头的符号
|[-+.](?:[a-zA-Z!
!?$%&=<>#:+.-][0-9a-zA-Z*!_?$%&=<>#:+.-])?)
# 关键字
|(::?)([0-9a-zA-Z
!_?$%&=<>#:+.-]+))

当存在命名空间时,名称部分

(?:/(/ # 除号符号

|[a-zA-Z*!_?$%&=<>][0-9a-zA-Z*!_?$%&=<>\#:+.-]*
|[-+.](?:[a-zA-Z*!_?$%&=<>\#:+.-][0-9a-zA-Z*!_?$%&=<>\#:+.-]*)?))?

1: 符号名称或命名空间 2: 关键字冒号(s) 3: 关键字名称或命名空间

4: 关键字或符号名称(并且组1和组3是命名空间)"

`

问题

  1. 不强制执行无重复冒号规则(但匹配后易于验证)。
  2. 拒绝违反首字符规则的符号,clojure可以接受。
  3. 接受命名空间后面的冒号(与clojure不同)。
  4. 接受{{foo//}}或{{:foo//}},这些在规范中未明确说明。(Jozef的表格有更多背景)。这两个在Clojure 1.6中是允许的,但在1.5或(可争辩地)edn中则不允许。
0 投票

评论由:favila

另一个问题:接受{{:::a/b}},我认为根据规范是可以接受的,但在1.6中不能读取。疯狂的例子

`
user=> (require ['clojure.core :as (symbol ":a")])
nil
user=> :::a/map

RuntimeException 无效标记::::a/map clojure.lang.Util.runtimeException (Util.java:221)
user=> (resolve (symbol ":a" "map"))

'clojure.core/map

`

理论上我可能期望{{:::a/map}}被解析为{{:clojure.core/map}}?

0 投票

评论者:alex+import

将此问题升级,因为我刚才花了一个小时来找出这是罪魁祸首

0 投票
_评论者:dnolen_

Nicolás,这个问题的前提是,当Clojure文档清楚地说明这不是有效的关键字时,这应该被支持。Clojure实现恰好允许这样做。无论如何,这需要首先在Clojure中解决。
0 投票

评论由:favila

我认为CLJ-1527是目前追究这个问题的票据。

0 投票
...