Hello,
While studying Clojure and trying to understand closures, I wrote the following code snippets:
(defn calculate-how-to-end-sentence []
(Thread/sleep 3000) ; just for test
(str "!"))
- first:
(defn create-greeting-function1
[greeting]
(fn [person-name]
(str greeting " " person-name (calculate-how-to-end-sentence))))
(def greeting-friend1 (create-greeting-function1 "Hi"))
(def greeting-neighbour1 (create-greeting-function1 "Hello"))
(greeting-friend1 "Tom")
; "Hi Tom!"
(greeting-neighbour1 "Nancy")
; "Hello Nancy!"
- second:
(defn create-greeting-function2
[greeting]
(let [end-of-line (calculate-something-that-takes-time)]
(fn [person-name]
(str greeting " " person-name end-of-line))))
(def greeting-friend2 (create-greeting-function2 "Hi"))
(def greeting-neighbour2 (create-greeting-function2 "Hello"))
(greeting-friend2 "Tom")
; "Hi Tom!"
(greeting-neighbour2 "Nancy")
; "Hello Nancy!"
It’s clear that if the calculate-how-to-end-sentence
function always returns the same output (it’s pure function), it’s better to execute it outside of the (fn ...)
. In my example it would be even faster to (def end-of-sentence (calculate-how-to-end-sentence))
instead of calculating it inside let
.
Could you please help me understand, when is the actual work (calculate-how-to-end-sentence
calculation) done in case of the second function? I know it is not done when I run greeting-friend2
. Which is good! But is it done when the program starts or when it is compiled?
Thanks!