A Clojure binding question
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 plan开发者_运维百科e]
in the actual defn? (i.e plane would be assigned [x y z])
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....
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.
精彩评论