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

欢迎!请参见关于页面以了解更多关于它的工作方式的信息。

0
语法和读取器
目前,除非映射包含偶数个文本形式,即使其中一个是空省略符(~@[]),否则无法将省略的拼接插入到映射文本中。

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

然而,在语法引号的环境中,映射文本内部不一定必须表示为映射,因为语法引号会输出构建映射的代码而不是映射本身。语法引号读取器的syntaxQuote方法甚至不操作映射,而是一个交错键和值的扁平序列。

借助元数据和LispReader全局Var,我们可以跟踪语法引号中的元素集合将变为映射,并且从语法引号读取器中输出适当的代码形式。在元数据文本中有一个小的问题,但是通过包含原始映射的附加元数据,我们仍然可以在语法引号输出时间生成适当的(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]

从今天早上修改 - 更多测试,以及针对新情况发现的问题修复。

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]_

实际上,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
by

评论者为:[email protected]

老实说,我已经忘记了提交这件事。我想这归结为优先级原则——映射的文本语义是否应该优先于概念语义?在这个节点上,我反对我以前的观点,我认为应该优先考虑文本语义的 ,正如目前那样。尤其是由于这在上。

0
by
...