I’m trying to do something similar to Python’s func(*lst) but with Clojure, and without using the apply function. My admittedly silly use case is:
{: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 a Python-esque * applied to the return value of cond. I tried playing around with data/code modes with ‘, `, and ~, though didn’t find a solution. I can repeat the cond for the individual parameters to the underlying hash-map but that kind of defeats the point.
Why? I just think it’d be cool if Clojure can do it easily. 🙂
No. A single form can only be a single form: it cannot magically be two of them. If this were possible, all kinds of things would break.
In your particular example, the easy answer is
The only way to do this is apply, which turns a single function parameter into zero or more function parameters, by expanding them as a list. It cannot work at the source-code level for use in things like a hash literal.
Edit: I don’t know much Python, but I’m pretty sure Python can’t do this either. You can splat things into function calls, but not straight into source. You can’t write
or anything like it – it just isn’t possible because the compiler has to analyze the
ifbefore it can understand what to do withtest_expr. Likewise in Clojure, the compiler has to analyze the hash literal before it can understand what to do with the objects inside – it can’t know that you “want” them expanded into the map expression somehow.