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

欢迎!请访问关于页面以获取更多关于此信息。

0投票
语法和读取器
目前,无法将反引号拼接插入到除包含偶数个文本文献的映射中之外,即使其中一个文献是一个空反引号 (~@[])。

例如:`{~@[1 2]} ;=> RuntimeException 映射必须包含偶数个文献 clojure.lang.Util.runtimeException (Util.java:219)

然而,在语法引号的环境中,内部表示法中映射的文本文献不使用映射,因为语法引号生成构建映射的代码,而不是映射本身。SyntaxQuoteReader 中的 syntaxQuote 方法甚至不操作映射,而是一个交错键和值的扁平序列。

借助元数据和 LispReader-global Var,我们可以跟踪到语法引号内部之一的元素将在成为映射,并从 SyntaxQuoteReader 发出适当的代码形式。在元文献中有一个小的边缘情况,但增加了包含 proto-map 的元数据,我们仍可以在语法引号发出时生成适当的 (with-meta ...) 形式。

重要的是,所涉及的手势从不脱离阅读器, eval/compile 环境也不会察觉到。

这允许以下内容

`{~@[1 2]} ;=> 之后 eval:{1 2}
`^{~@[:foo :bar]} sym ;=> sym 的 eval 后的元数据:{:foo :bar}

但是不是
`~{1} ;=> RuntimeException ...

或者
{1} ;=> RuntimeException ...

`{~@[1]}`有与当前所必需的 `{~@[1] ~@[]}` 相同的语义
;=> IllegalArgumentException 未为键提供值:1 clojure.lang.PersistentHashMap.create (PersistentHashMap.java:77)

我的签入更改通过了所有现有测试,并包括一个针对新支持的映射反引号拼接形式的附加测试。

7 答案

0投票

评论者:[email protected]

从今晨开始修改——增加了更多测试,并对捕获到的新的案例进行了错误修复。

0投票

评论者:[email protected]

更新了补丁。

现在使用两个不同的路径来添加元数据。旧版本可能堆叠了-with-meta调用,这可能会导致丢失键。

0投票

评论者:hiredman

这看起来是个坏主意,从纯粹的宏编写角度来看,好像有点道理,但语法引号在宏之外使用,在这种情况下,这仅仅绕过了添加的重复键检查,我想这可能在1.3左右,也可能是1.4

http://dev.clojure.org/display/design/Allow duplicate map keys and set elements

0投票
_评论者:[email protected]_

实际上,非引号展开已经绕过了重复键检查,因为它展开为(apply hash-map ...)调用。

在Clojure 1.7.0-alpha2

user> `{~@[:foo :bar :foo :bar] ~@[]}
;=> {:foo :bar}
user> '`{~@[:foo :bar :foo :bar] ~@[]}'
;=> (clojure.core/apply clojure.core/hash-map (clojure.core/seq (clojure.core/concat [:foo :bar :foo :bar] [])))
0投票

评论者:hiredman

是的,抱歉,我弄混了这个实现和相关已关闭的问题。您有没有这个动机的例子?我写了很多Clojure代码,并且没有在实际中发现这个问题,我对放松这些约束很谨慎。如果我们允许这种行为,那么语法引号绝对不能从读出器中取出(可能还有其他使这变得困难或不可能的行为,我不确定),实际上语法引号必须在对数据进行检查之前操作,而如果语法引号中的映射是“有效构建”的,也许可以将语法引号(读出器中的很多复杂性来源)从读出器中移除,并对其已经读入的数据进行操作。

我几乎100%确信将语法引号作为后读出器宏不是任何形式的优先级,但我只提到这一点,作为一种后续事项,这可能因为这类变化而被关闭,我已经开始将所有与语法引号有关的东西看作是添加语法而非数据的附加项,这似乎是不利的。

无论如何,我对这种行为感觉不到太多痛苦,而且这种“修复”可能有一些后续后果,所以一个好的激励示例会很不错。

为了防止您浪费时间来想一个激励示例,我已经承诺了所有我反对的特性,所以如果您忽略我,你真的有可能大功告成 :)

0投票
by

评论者:[email protected]

说实话,我已经忘记我提交了这个。我想这归结为优先级原则——映射的文字语义是否应该优先于概念的语义?在此阶段我希望改变我以前的观点,并且我认为映射的文字语义应该优先,就像它们目前所做的那样。尤其是在这些是读者所在之处。

0投票
by
...