Clojure - 将列表元素视为函数参数

时间:2011-08-19 07:17:51

标签: clojure

我正在尝试使用类似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可以轻松实现它会很酷。 :)

1 个答案:

答案 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中,编译器必须先分析散列文字才能理解如何处理内部对象 - 它无法知道你“想要”它们以某种方式扩展到地图表达式中。