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投票

评论者:wagjo

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

0投票

由favila发表的评论

啊,我想我看出困惑的原因了。EDN和Clojure阅读器规范都说一些类似于“关键字就像符号,只是以冒号开头”的东西。困惑在于我们是否将这理解为意味着

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

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

然而,Clojure 1.6似乎遵循第二个意思,并解释了为什么:0/a是正确的,但不正确的是:0/0,我不确定从引用的票务和谷歌群体讨论中,这是否是因为下游的破坏,或者这是否是预期的解释,并且从CLJ-1252的补丁被Alex Miller错误地接受。

注意,如果我们接受第二个解释,那么Clojure阅读器文档中的限制“一个符号可以包含一个或多个不重复的冒号”对于关键字是不正确的。(EDN似乎不允许命名空间展开的关键字,所以这不成为问题。)

此外,EDN允许符号中连续的冒号,而Clojure 1.6和阅读器规范则不允许。

0投票

由favila发表的评论

此外,Clojure 1.6允许{{a/:a}}和{{:a/:a}}(其中名称部分违反了符号的第一个字符规则),尽管规范不提及这一点。(这在你提供的表格中没有提及。不过,你的工作非常详细!我希望阅读器规范更正式化、更明确……)

0投票

由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 中不能被读取。疯狂的例子

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

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

'clojure.core/map

`

理论上,我可能预期 {{:::a/map}} 会被读取为 {{:clojure.core/map}}?

0投票

由:alex+import 评论

提升这个问题,因为我刚刚花费一小时找到这是罪魁祸首

0投票
_由:dnolen_ 评论

Nicolás,这个工单的前提是这应该在规范清楚指出有效的关键字不能这样做的情况下被支持。Clojure 的实现只是碰巧允许它。无论如何,这个问题首先需要解决在 Clojure 中。
0投票

由favila发表的评论

我认为 CLJ-1527 是目前正在追踪这个问题的工单。

0投票
参考: https://clojure.atlassian.net/browse/CLJS-677 (由 cemerick 报告)
...