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 发布的评论:

这看起来是个坏主意,从纯宏编写角度看似乎有点道理,但语法引号(quote)在外部使用,这只会绕过重复键检查,我记得大约在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,在实践中没有发现这个问题,我对放宽这种约束持谨慎态度。如果我们允许这种行为,那么语法引号(quote)肯定永远不能从读取器中取出(可能有其他行为已经使得这种情况变得很困难甚至不可能,我不确定),实际上语法引号(quote)必须在数据从读取器中取出之前对数据进行操作,而如果语法引号(quote)中使用的映射是“良好格式”的,那么也许可以将语法引号(source of a lot of complexity in the reader)从读取器中移除,并对其已经读取进来的数据进行操作。

我几乎百分之百确信,将语法引号作为后置阅读宏不是任何形式的优先事项,但我只是提到它可能因为这类变化而被屏蔽,我开始认为与语法引号相关的任何事物都可以被认为是添加超出了数据之外的语法,这看起来是消极的。

所以无论如何,我对这种行为并没有太多痛苦,并且似乎“修复”可能会带来一些后续后果,所以一个可靠的动机示例会很好。

只是为了警告你不要浪费时间来想出一个动机示例,我所反对的每个特性都已提交,所以如果你忽略我,真的有可能会成功 :)

0 投票

[email protected] 发布的评论:

老实说,我忘记提交这项了。我想这归结于优先级原则——映射的实际语义是否应优先于概念语义?此时我反对我以前的观点,我认为映射的实际语义应该优先,正如现在所做的那样。尤其是在这是一个读者时。

0 投票
...