开发者

A Clojure binding question

开发者 https://www.devze.com 2023-04-07 04:29 出处:网络
just looking to re factor some simple code I have a function (defn foo ([x y] (let [line [x y]] (...)) ([x y z]

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 lets 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.

0

精彩评论

暂无评论...
验证码 换一张
取 消