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。

顺便说一下,这是simple-check(链接: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),而且我不确定从引用的工单和 Google 群组讨论来看,这是否是因为下游的破坏,或者这是预期的解释,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//}},这些在规范中并未明确说明。这两种在 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
参考:https://clojure.atlassian.net/browse/CLJS-677(由cemerick报告)
...