2024 Clojure狀態調查中分享您的想法!

欢迎!请查阅关于页面以获取更多信息。

0
语法和读取器
目前,除非映射包含偶数个文法形式,否则无法在映射文法中进行缩写拼接,即使其中一个形式是空项 (~@[])。

例如:`{~@[1 2]} ;=> RuntimeException Map literal must contain an even number of forms  clojure.lang.Util.runtimeException (Util.java:219)

然而,在内嵌的语法引号上下文中,映射文法不需要内部表示为映射,因为语法引号生成代码来构建映射,而不是映射本身。SyntaxQuoteReader中的syntaxQuote方法并不操作映射,而是一个扁平化的交织键值序列。

借助元数据和一个LispReader-gloabal Var,我们可以追踪语法引号内的元素集合将成为一个映射,并从SyntaxQuoteReader生成正确的代码形式。在元数据文法中有一个小的边缘情况,但是通过添加一个包含原型映射的额外元数据,我们仍然可以在语法引号发射时生成适当的(with-meta ...)形式。

重要的一点是,所有的空话都不会逃出读取器,并且评估/编译环境也不会变得更加聪明。

这允许以下操作

`{~@[1 2]} ;=> after eval: {1 2}
`^{~@[:foo :bar]} sym ;=> metadata of 'sym after eval: {:foo :bar}

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

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

而且 `{~@[1]} 与当前必需的 `{~@[1] ~@[]}` 具有相同的语义
;=> IllegalArgumentException No value supplied for key: 1  clojure.lang.PersistentHashMap.create (PersistentHashMap.java:77)

我的补丁的更改通过所有现有测试,并包含对新支持的映射缩写拼接形式的附加测试。

7 回答

0

评论者:[email protected]

与今晨的内容相比 - 更多的测试,以及针对新捕获到的案例的bug修复。

0

评论者:[email protected]

更新了补丁。

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

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

用户> `{~@[:foo :bar :foo :bar] ~@[]}
;=> {:foo :bar}
用户> '`{~@[: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
...