我正在尝试使用类似Python的func(*lst)
但使用Clojure,而不使用apply
函数。我公认的愚蠢用例是:
{:k1 v1 (cond exp '(:k2 v2) :else '(:k3 v3))}
因此,如果exp为true,则dict将包含{:k1 v1 :k2 v2}
,否则为{:k1 v1 :k3 v3}
。我基本上希望将Python-esque *
应用于cond
的返回值。我尝试用',`和〜来玩数据/代码模式,但没有找到解决方案。我可以针对基础cond
重复hash-map
个别参数,但这种情况会失败。
为什么呢?我认为如果Clojure可以轻松实现它会很酷。 :)
答案 0 :(得分:8)
没有。单个表单只能是一个表单:它不能奇迹般地是其中两个表单。如果这是可能的,各种各样的事情都会破裂。
在您的特定示例中,简单的答案是
(apply hash-map :k1 v1
(cond exp '(:k2 v2)
:else '(:k3 v3))
执行此操作的唯一方法是应用,将单个函数参数转换为零个或多个函数参数,方法是将它们展开为列表。它不能在源代码级别工作,以用于散列文字等。
编辑:我不太了解Python,但我很确定Python也不能这样做。你可以把事情搞砸到函数调用中,但不能直接进入源代码。你不能写
test_expr = ((x == 2), return x)
if *test_expr
或类似的东西 - 它是不可能的,因为编译器必须先分析if
才能理解如何处理test_expr
。同样在Clojure中,编译器必须先分析散列文字才能理解如何处理内部对象 - 它无法知道你“想要”它们以某种方式扩展到地图表达式中。