Mahmud Adam
Mahmud Adam

Reputation: 3579

Futures in Clojure

I am having a hard time understanding the point of this example:

(let [result (future (println "this prints once")
                 (+ 1 1))]
   (println "deref: " (deref result))
   (println "@: " @result))

The author explains:

Notice that the string "this prints once" indeed prints only once, even though you dereference the future twice. This shows that the future’s body ran only once and the result, 2, got cached.

I don't get it; the string will print once even without dereferencing the future. What is this example supposed to teach?

Upvotes: 1

Views: 472

Answers (2)

Piotrek Bzdyl
Piotrek Bzdyl

Reputation: 13175

The future executes the enclosed code in a separate thread and starts the execution immediately so it will run the code even if you don't reference the result value.

I guess the author wanted to show that the future body won't be reexecuted when you dereference it more than once.

Upvotes: 2

jmargolisvt
jmargolisvt

Reputation: 6088

I agree this is subtle. The point of this is to show that future is a one-time evaluation. Sure, the println side effect occurs whether you deref "result" or not. In fact, the side effect occurs without later deref-ing "result" as you've noted. Merely binding "result" causes the println side effect to occur.

More importantly, the idea here is that deref-ing "result" twice explicitly does not cause it to be evaluated (or bound) twice. In other words, it does not cause the println side effect twice. You get the cached value of 2 both times you deref it.

One might expect deref-ing it twice would cause it to be bound twice, and therefore execute the println twice. But this is not the case. Instead, you get the cached, deref-ed value just once. The point here is more that the side effect occurs upon binding, not upon deref-ing, and that deref-ing twice does not incur a second binding.

Upvotes: 5

Related Questions