现在就分享你的想法吧,参与 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。

BTW,这又是一个(链接: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*!_?$%&=<>\#:+.-]rupt
#以 [-+.] 开头的符号
|[-+.](?:[a-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
by

评论来自: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
by

评论由:alex+import

将此问题提升,因为我刚刚为了找到这个原因而困惑了一个小时

0
by
_评论由:dnolen_

Nicolás,该票的假设是应该支持它,尽管Clojure关于有效关键字的文档明确表示不应支持。Clojure实现恰好允许它。无论如何,这个问题需要在Clojure中先解决。
0
by

评论来自:favila

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

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