bbatsov / clojure-style-guide

A community coding style guide for the Clojure programming language
https://guide.clojure.style
3.99k stars 279 forks source link

Destructuring in function definition #81

Open nidu opened 10 years ago

nidu commented 10 years ago

Hello.

Is it recommended to destructure arguments in function definition or in let inside the function? The first approach affects readability though shortens the function. Any thoughts about this? E.g. compare

(defn distance-to-unit 
  [{:keys [scale units-per-pixel] :as viewer} dim value])

and

(defn distance-to-unit 
  [viewer dim value]
    (let [scale (:scale viewer)
          units-per-pixel (:units-per-pixel viewer)]))
ToBeReplaced commented 10 years ago

It depends. Make the function arguments self-documenting for the caller. If the argument is best understood as a viewer, the arglists should show that. I would use:

;;; Good: let binding inside function
(defn distance-to-unit
  [viewer dim value]
  (let [{:keys [scale units-per-pixel]} viewer]
    ...))

;;; Also good: Fix the arglists.
(defn distance-to-unit
  {:arglists '([viewer dim value])}
  [{:keys [scale units-per-pixel]} dim value]
    ...)

In the case of "options", I would do the destructuring in the function definition (and not alter the arglists) so that the keys show up in the function documentation automatically.

nidu commented 10 years ago

@ToBeReplaced i like the approach you provided with let. Definition is cleaner and you don't spread parameters definitions among multiple blocks.

Notice also that when you destructure parameters in function definition - you specify some kind of implicit protocol. You can say from it what keys should input arguments contain.

kliph commented 10 years ago

+1 for @ToBeReplaced suggestion for clear arguments.