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

欢迎!请参阅 关于页面 了解此如何工作的更多信息。

0
语法和读取器
目前无法在不包含偶数个文 literal forms 的映射文学理中 unquote-splice,即使其中一个是 null unquote (~@[]) 也行。

例如:`{~@[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 ;=> 。后 eval:sym 的元数据为 {:foo :bar}

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


{1} ;=> RuntimeException ...

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

我的补丁中的更改通过所有现有测试,并包括对支持的新映射 unquote-splicing 形式的额外测试。

7 回答

0

评论来自:[email protected]

从今天早上修改 - 更多测试,以及针对新捕获的情况的虫害修复。

0

评论来自:[email protected]

更新了补丁。

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

0

评论者:hiredman

这看起来不是一个好主意,从纯宏编写角度来看,它似乎有点道理,但是语法引号在宏之外使用,这时候这仅仅变成了绕过大键检查的替代方案,我认为这可能在1.3或1.4版本的时候就已经添加了。

http://dev.clojure.org/display/design/允许重复的映射键和集合元素

0
_评论者:[email protected]_

实际上,unquote-splicing已经绕过了重复键检查,因为它扩展为一个(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

评论来自:[email protected]

老实说,我已经忘了我已经提交了这个。我认为这归结于优先原则-映射的字面语义是否优先于概念语义?在这个问题上,我反对我以前的观点,我认为字面语义应该优先,就像现在所做的那样。特别是,因为这是在读者中。

0
...