Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Block encapsulation vs. local encapsulation - let

Tags:

let

clojure

When I have data relevant to a function that is independent of its arguments, when should I favor block encapsulation over local encapsulation?

When should I use:

(let [hello "Hello "]
  (defn do-greet
    "Print a greeting."
    [name]
    (println (str hello name))))

Versus:

(defn do-greet
  "Print a greeting."
  [name]
  (let [hello "Hello "]
    (println (str hello name))))
like image 882
ToBeReplaced Avatar asked Nov 02 '12 19:11

ToBeReplaced


1 Answers

The former is a reasonable option if you want to use the value like a static constant within a lexically scoped block of code. Typically you would do this if:

  • The value is expensive to compute, and you want to do it only once when the namespace is loaded
  • The value is genuinely constant, i.e. will not change across function invocations
  • The value will be used across multiple function definitions (i.e. you put multiple defns inside the let block)
  • (Possibly?) because you want to use the value inside a macro expansion, and embedding the let inside the macro expansion itself would add unnecessary complexity.

The latter version should probably be preferred in most other cases, it is good for several reasons:

  • It is more idiomatic
  • It allows the function definition to be at the top level, which is better for code readability / comprehension
  • It allows the value to vary on different function invocations
  • It better reflects the intent of using the value in a local context
like image 131
mikera Avatar answered Sep 23 '22 06:09

mikera