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

欢迎!请参阅关于页面以获取更多有关如何使用本网站的信息。

0投票
语法和读取器
目前,除非映射包含偶数个文学形式,否则无法将unquote-splice插入到映射文本文档中,即使其中一个为零unquote (~@[])。

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

但是,在语法引号的环境中,映射文本文档不必在内部表示为映射,因为语法引号会发出构建映射的代码而不是映射本身。SyntaxQuoteReader上的syntaxQuote方法甚至不操作映射,而是操作交错键和值的扁平序列。

借助于元数据和LispReader全局Var,我们可以跟踪在语法引号中的一组元素将成为映射,并从SyntaxQuoteReader发出正确的代码形式。元数据文本文档存在一个小边缘案例,但通过包含原型映射的额外元数据,我们仍然可以在语法引号发出时生成适当的(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]

今天早上修订版——更多的测试,以及修复新捕获的情况的bug。

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中

用户> `{~@[: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投票
...