_评论由:zcaudate_ 提出
请考虑以下原因重新考虑此“修复”
- 为了一致性,需要修复 (keyword "foo/bar/baz")
- 它将破坏我的代码的用户
-
http://docs.caudate.me/adi/adi-guide.html -
http://docs.caudate.me/adi/adi-walkthrough.html#schoolyard
请参见下面对该主题的讨论
dm3 [5:04 PM]
为什么 `(read-string "a/b/c")` 可以正常工作,而用 `(clojure.tools.reader/read-string "a/b/c")` 就会报错“无效令牌”?
hiredman [5:04 PM]
有张票来修复 read-string
dm3 [5:05 PM]
所以正确的做法是失败吗?
hiredman [5:05 PM]
http://dev.clojure.org/jira/browse/CLJ-1530
dm3 [5:06 PM]
感谢,看来这是一个破坏性改动 :simple_smile
hiredman [5:07 PM]
文档已经有一段时间不再推荐符号如 a/b/c 了,而这些未指定符号的读取行为显然在某个时刻发生了改变
lucas [5:09 PM]
加入了 #clojure
zcaudate [5:16 PM]
@hiredman: 真是糟糕。我已经使用 `:a/b/c` 关键词一段时间了… 甚至为此写了一个完整的库来处理这个问题
http://docs.caudate.me/hara/hara-string.html#api---path (编辑)
[5:16]
现在他们要移除它了
[5:18]
我认为应该首先移除 `::foo/baz` 类型的关键词
[5:20]
```user=> (require '[clojure.walk :as walk])
nil
user=> ::walk/hello
:clojure.walk/hello
```
[5:20]
这会导致很多问题
[5:20]
尤其是与分析器一起使用时
[5:22]
https://github.com/jonase/kibit/issues/14
GitHub
Kibit 在命名空间关键词上出错 · Issue #14 · jonase/kibit · GitHub
如果代码中包含带有别名的外部命名空间关键词,则 Kibit 会报错并抛出“无效令牌”异常。以下代码展示了此问题 - ;;; foo.clj (ns foo) ;;; bar.clj (n...
[5:25]
@dm3 如果确实存在问题,你可以修补它
[5:25]
https://github.com/helpshift/hydrox/blob/master/lein/src/leiningen/hydrox/setup.clj
GitHub
helpshift/hydrox
hydrox - 深入探究你的代码
dm3 [5:31 PM]
是的,不幸的是,你可能还得修补 cljs.tools.reader :confused
[5:31]
我将尽力解决这个问题
bronsa [5:36 PM]
@zcaudate: `::foo/bar` 风格的关键词是故意保留的,不会移除,而 `:foo/bar/baz` 按照规范总是无效并且具有未定义的行为 (编辑)
[5:37]
@dm3: 改变未定义行为是否也算破坏性更改? :simple_smile
dm3 [5:37 PM]
破坏性更改,就是破坏别人代码 :simple_smile
[5:37]
例如,zcaudate
bronsa [5:38 PM]
如果它使用的是无效的 Clojure,那这代码就已经是错误的了。它只是不小心正常工作而已
dm3 [5:39 PM]
我从实用主义的角度来看这个问题。理论上你是正确的 :simple_smile
[5:40]
但我没有做出任何评判
bronsa [5:40 PM]
实用主义上讲,“:foo/bar/baz” 是一个等待发生的错误。`(namespace :foo/bar/baz)` 返回什么?
dm3 [5:40 PM]
目前它返回什么就返回什么?
[5:41]
我的意思是,它有点由实现来决定
sveri [5:41 PM]
@dm3 @bronsa 我甚至不同意你理论上的观点。一旦足够的开发者采用了这个有问题的代码,它就属于一种类似于普遍接受的“惯例”,这种惯例在双方之间维持了足够长的时间。
bronsa [5:42 PM]
那么 `(keyword "foo/bar" "baz")` 和 `(keyword "foo" "bar/baz")` 上的 `namespace` 又如何呢?
dm3 [5:43 PM]
我同意当前实现的语义是混乱的
[5:43]
但我的观点是,这仍然是一个破坏性更改
[5:43]
并不是说这是一个“不好的”更改
[5:43]
这是一个评判
bronsa [5:43 PM]
@sveri: 我同意你的观点,只要我们接受的未定义行为不会导致无法修复的语义。
[5:44]
这就是为什么,例如,使以数字开头的符号非法的修补回滚了
[5:45]
它破坏了现有代码,但它并没有造成奇怪的语义,所以它被回滚了。而 `:foo/bar/baz` 的情况并非如此
[5:45]
@dm3: 你可以这么说,修复任何错误都是破坏性更改 - 有的人可能依赖于那个错误。
dm3 [5:46 PM]
是的,我认为问题的关键在于错误行为是否明显以及有多少人依赖于它
bronsa [下午5:46]
如果文档明确指出“你可以在一个符号中使用 *一个* `/`”,那么如果你使用超过一个,你写的Clojure是不正确的,你应该预期它可能会出错(编辑过)
dm3 [下午5:47]
在使用Clojure的三四年间,我真的没有考虑过在符号中使用多斜杠(也没有注意到文档)
[5:47]
今天我最初的思考是它应该是允许的
[5:47]
并且命名空间应该是第一个斜杠之前的第一个部分(编辑过)
bronsa [下午5:51]
但是,这并没有太多意义。在Clojure中,`/`是命名空间分隔符。无论`FOO`和`BAR`是什么,如果我看到`FOO/BAR`,我就知道`FOO`是命名空间,`BAR`是名称。如果你想在关键字中使用路径,就像@zcaudate的lib中所做的那样,你应该在关键字中使用一个没有特殊意义的分隔符,比如`.`(例如`:foo/bar/baz` -> `:foo.bar.baz`或`:foo/bar.baz`)(编辑过)
dm3 [下午5:51]
我不想争辩语义。只是分享一个观点
bronsa [下午5:52]
我的观点是,只有在语义明确和没有歧义的情况下,才应该考虑现实主义的观点(尤其是当它们与当前文档相悖时)
sveri [下午5:53]
@bronsa:很好的解释,谢谢你:笑脸
dm3 [下午5:53]
是的:笑脸
[5:54]
我同意这一点,因为最后你必须做出决定
zcaudate [晚上9:07]
@bronsa:书面形式的交流有时会让人感觉事情比实际严重
[9:08]
说实话……我从1.6版开始就知道会有这种情况,因为edn reader开始破坏我的代码
[9:09]
可能是我没有早点沟通的错,但……我们都要顺应时代的发展
bronsa [晚上9:09]
@zcaudate:没问题,我只是因为你提到了你的库,所以用了你的库作为例子
zcaudate [晚上9:10]
不过,这么说来,你可能想象得到我的失望,因为我已经基于关键字`:foo/bar/baz`的功能(现在是错误)设计了一套完整的查询语义(编辑过)
[9:11]
http://docs.caudate.me/adi/adi-walkthrough.html#querying
[9:11]
你注意到我没有在文档中使用`(adi/select ds {:student/classes/teacher/name "Mr. Blair"})`
[9:12]
因为它开始崩溃了
jstew [晚上9:12]
@zcaudate:你发布的质量内容很多,我怀疑你从不睡觉!
1
bronsa [晚上9:12]
@zcaudate:幸运的是,修复应该很简单:笑脸:只需将`/`换成`.`即可
zcaudate [晚上9:12]
不!
[9:13]
问题是……datomic有类似`account.type/user`的东西
[9:13]
所以我必须做cljs的事情`account.type$user`
bronsa [晚上9:13]
(顺便说一下,这是高质量的文档,做得很好)
zcaudate [晚上9:14]
@bronsa:哈哈,谢谢你……也许你可以把它推到1.10
[9:14]
这样我还可以多几个月使用
[9:15]
这并不是什么大问题……但我认为`/`调用路径结构和映射嵌套之间有相似之处
[9:16]
这就像`{:student {:classes {:teacher {:name '(?fulltext "Blair")}}`
[9:17]
和`{:student/classes/teacher/name "Mr. Blair"}`
[9:17]
我认为这样更美观
bronsa [晚上9:17]
@zcaudate:对不起如果不是很清楚,但事实上我没有控制Clojure或者里面有什么,我只是个贡献者:笑脸:所以clojure/core团队可能会做出不同的决定,并实际上拒绝那个条目(如果真的是那样的话,我会非常失望的!)如果那样的话,我会明显地改变`tools.reader`,允许它们作为同样,(编辑过)
zcaudate [晚上9:18]
@bronsa:该死。
[9:19]
嗯……也许你可以强调这个事实
[9:19]
同时,如果在修复时修复了`(keyword "foo/bar/baz")`,也需要修复
bronsa [晚上9:20]
我觉得这件事永远也不会完成。验证`keyword`/`symbol`等输入已经多次被提出和讨论,但由于性能原因被不断拒绝
zcaudate [晚上9:20]
所以这是一个关于一致性的问题。
bronsa [晚上9:20]
(虽然我不认同这个决定,但Rich似乎不会改变对这个问题的看法)
[9:21]
@zcaudate:运行时符号/关键字可以是什么,与有效的运行时符号/关键字是什么有区别
zcaudate [晚上9:21]
此外,这意味着我可以设置一个读取宏#k foo/bar/baz 并达到相同的效果
[9:22]
虽然看起来非常丑陋,但我相信它会工作
bronsa [晚上9:23]
但关于`namespace`和`name`的模糊性仍然存在,所以我不懂
[9:23]
@zcaudate:无论怎样,如果
http://dev.clojure.org/jira/browse/CLJ-1530被接纳,无论是`:foo/bar/baz`还是`foo/bar/baz`都将不再有效
[9:24]
@zcaudate:顺便说一句,如果你强烈反对它,我建议你在那里的票据中留言
新消息
[9:25]
我推测回应将会是“你应该使用在Clojure中没有特殊含义的分隔符”,但我可能是完全错误的(我发现核心团队并不经常同意我的观点 :)),尤其是如果你指出你的库将会崩溃。(编辑后)
zcaudate [晚上9:30]
@bronsa:感谢提醒。我会留言,并为bdfl祈祷