Clojure - treat list items as functional parameters

I am trying to do something similar to Python func(*lst) , but with Clojure and without using the apply function. My admittedly stupid use case:

 {:k1 v1 (cond exp '(:k2 v2) :else '(:k3 v3))} 

So, if exp was true, the dict would contain {:k1 v1 :k2 v2} , otherwise {:k1 v1 :k3 v3} . I basically want to use Python-esque * for the return value of cond . I tried to play with data / code modes using "," and "~", although I did not find a solution. I can repeat cond for the individual parameters in the base hash-map , but this view defeats the point.

Why? I just think it would be great if Clojure can do it easily. :)

+4
source share
1 answer

No. A single form can be only one form: it cannot magically be two of them. If it were possible, all kinds of things would break.

In your specific example the easy answer

 (apply hash-map :k1 v1 (cond exp '(:k2 v2) :else '(:k3 v3)) 

The only way to do this is to apply, which turns one function parameter into zero or more function parameters , expanding them as a list. It cannot work at source level for use in things like a hash literal.

Edit: I know little of Python, but I'm sure Python can't do this either. You can break things down into function calls, but not directly to the source. You can not write

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

or something like that - it's just not possible because the compiler needs to test_expr if before it can figure out what to do with test_expr . Similarly, in Clojure, the compiler must parse the hash literal before it can figure out what to do with the objects inside - it cannot know that you "want" to extend them somehow in the map expression.

+8
source

All Articles