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

Clojure-将列表元素视为函数参数,clojure,Clojure,我试图做一些类似于Python的func(*lst)的事情,但是使用Clojure,而不使用apply函数。我公认的愚蠢用例是: {:k1 v1 (cond exp '(:k2 v2) :else '(:k3 v3))} 因此,如果exp为true,dict将包含{:k1v1:k2v2},否则{:k1v1:k3v3}。我基本上想要一个Python风格的*应用于cond的返回值。我试着用“,`,和~”来处理数据/代码模式,但没有找到解决方案。我可以重复cond,将单个参数添加到底层的哈希映射中,

我试图做一些类似于Python的
func(*lst)
的事情,但是使用Clojure,而不使用
apply
函数。我公认的愚蠢用例是:

{:k1 v1 (cond exp '(:k2 v2) :else '(:k3 v3))}
因此,如果exp为true,dict将包含
{:k1v1:k2v2}
,否则
{:k1v1:k3v3}
。我基本上想要一个Python风格的
*
应用于
cond
的返回值。我试着用“,`,和~”来处理数据/代码模式,但没有找到解决方案。我可以重复
cond
,将单个参数添加到底层的
哈希映射中,但这样做会破坏这一点


为什么??我只是觉得如果Clojure能轻松做到这一点,那就太酷了。:)

不。一个单一的形式只能是一个单一的形式:它不能神奇地是其中的两个。如果这是可能的,所有的事情都会破裂

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

(apply hash-map :k1 v1 
                (cond exp   '(:k2 v2)
                      :else '(:k3 v3))
唯一的方法是应用,将单个功能参数展开为列表,将其转换为零个或多个功能参数。它不能在源代码级别工作,以用于哈希文本之类的东西

编辑:我对Python了解不多,但我很确定Python也不能做到这一点。您可以将内容扩展到函数调用中,但不能直接扩展到源代码中。你不会写字

test_expr = ((x == 2), return x)
if *test_expr

或者类似的事情-这是不可能的,因为编译器必须先分析
if
,然后才能理解如何处理
测试expr
。同样,在Clojure中,编译器必须先分析哈希文本,然后才能理解如何处理其中的对象——它无法知道您是否“希望”它们以某种方式扩展到映射表达式中。

谢谢,我想。虽然apply函数最终并没有那么难看,但我还是喜欢花括号形式。一个小的修正是,如果v2和v3是变量,它需要是
`(:k2~v2)
,如果这是您想要的,当然;我修复了您的实际代码,而不是解释我认为您可能的意思<代码>`(:k2~v2)
可以工作,但是如果你想要的话,
[:k2 v2]
就容易多了。