Reputation: 1237
just looking to re factor some simple code
I have a function
(defn foo
([x y]
(let [line [x y]]
(...))
([x y z]
(let [plane [x y z]]
(...))))
I know I can write
(let [[x y :as point] [1 0]])
Is there a similar destructuring for functions such as foo
where I can write
[x y :as line]
or [x y z :as plane]
in the actual defn? (i.e plane would be assigned [x y z])
Upvotes: 1
Views: 116
Reputation: 106351
You can always build the let
s using a macro. This would enable you to two write something like:
(def foo
(build-foo-args [[x y] line]
(...))
(build-foo-args [[x y z] plane]
(...)))
Not sure how much this syntactic sugar really buys you though... the lets are pretty clear in the first place.
On the whole, I'd probably recommend rethinking your function signature:
If you genuinely need different behaviours for different arities then foo should probably be split into separate functions.
If the behaviour is the same for different arities, then I would use variadic args as suggested by Dave Ray, but call the combined argument something neutral e.g. "normal-vector" which can refer to multiple dimensionalities. You may find you don't actually need x,y,z to be named at all....
Upvotes: 2
Reputation: 40005
You can destructure in the arg list as well, but you'll have to use variadic args which means you can't have multiple signatures:
(defn foo [& [x y z :as plane]]
(...))
and then call like:
(foo 1 2 3)
but like I said above, with this approach the two and three arg forms become ambiguous so you'd have to have separate named functions.
Upvotes: 2