I’m a big fan of the Clojure / functional approach of programming with immutable values.
However I’m unsure if a delay should be considered as an immutable value (assuming that you delay a pure function). I’m particularly interested in the case where there are one or more delays in a larger immutable data structure.
e.g. a vector containing a delay:
[1 2 (delay (reduce + (range 1000)))]
As far as I can see this behaves as if it is an immutable value in the sense that you can’t see the result of the delay until you force its evaluation – and then the result is cached and the value can never change after that.
Are there any issues with treating a delay as an immutable value in this way?
A delay models what’s usually called a thunk, a reference to a yet-to-be-evaluated expression that is replaced with its result once forced, and is thereafter immutable. Haskell uses such internally mutable thunks to model non-strict evaluation. The expression
[1, 2, foldl1 (+) [0..1000]]is nominally the same as its explicitly delayed equivalent in a language with strict evaluation.Provided of course the function used in the delay object is pure, there is no harm in treating it as immutable. You can think of this in a couple of ways:
A pure function can, by definition, be replaced with its result.
Local mutation (in this case, of the delay object) does not make a function impure.
Of course, Clojure does not distinguish between pure and impure functions, so it’s up to you as a developer to be diligent about it.