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

Kev*_*vin 4 clojure

我正在尝试使用类似于Python的东西,func(*lst)但使用Clojure,而不使用该apply函数.我公认的愚蠢用例是:

{:k1 v1 (cond exp '(:k2 v2) :else '(:k3 v3))}
Run Code Online (Sandbox Code Playgroud)

因此,如果exp为真,则dict将包含{:k1 v1 :k2 v2},否则{:k1 v1 :k3 v3}.我基本上想要一个Python-esque *应用于返回值cond.我尝试用',`和〜来玩数据/代码模式,但没有找到解决方案.我可以重复cond针对底层的个别参数,hash-map但这种情况会失败.

为什么?我认为如果Clojure可以轻松实现它会很酷.:)

ama*_*loy 8

不可以.单一表格只能是一种形式:它不能神奇地成为其中两种形式.如果这是可能的,各种各样的事情都会破裂.

在您的特定示例中,简单的答案是

(apply hash-map :k1 v1 
                (cond exp   '(:k2 v2)
                      :else '(:k3 v3))
Run Code Online (Sandbox Code Playgroud)

执行此操作的唯一方法是apply,它将单个函数参数转换为零个或多个函数参数,方法是将它们扩展为列表.它不能在源代码级别工作,以用于哈希文字之类的东西.

编辑:我不太了解Python,但我很确定Python也不能这样做.你可以把事情搞砸到函数调用中,但不能直接进入源代码.你不能写

test_expr = ((x == 2), return x)
if *test_expr
Run Code Online (Sandbox Code Playgroud)

或类似的东西 - 它是不可能的,因为编译器必须先分析if它才能理解如何处理test_expr.同样在Clojure中,编译器必须先分析散列文字才能理解如何处理内部对象 - 它无法知道你"想要"它们以某种方式扩展到地图表达式中.