views:

109

answers:

2

I'm studying programming language theory and I can't figure out a solid reason why lazy languages don't have mutation. Anyone know the reason?

+1  A: 

Mutation means you cannot be sure of the state of the program at any time and will have to worry about side effects from any action. I've actually thought about it and I can't think of any way to have a completely lazy language that supports mutation. (I am no computer scientist though.)

ChaosPandion
thank for the answer
forellana
+5  A: 

Laziness means that a function is not actually evaluated until (or unless) its return value is used. This means that function calls aren't necessarily evaluated in the order in which they appear in the code. It also means that there can't be void-functions because they would never be evaluated (as its not possible to use a return value that does not exist).

However for functions that perform side-effects (like mutation, but also just printing to the screen) it does matter in which order they're executed. It matters even more that they're executed at all. This means that lazy languages need a way to emulate side-effects in special types that ensure that they are executed and executed in the right order.

Since entirely side effect-free programs are useless (you need to be able to print to the screen at all), lazy languages actually do support side-effect. They just encapsulate them with the IO monad or uniqueness-types. As an example haskell does have mutable arrays, but they can be only used inside the IO monad.

sepp2k
To put it another way: it's not that lazy languages *can't* have mutation, it's that you wouldn't *want* it.
Jörg W Mittag
thanks for the answer
forellana
While interactive programs require side effects non-interactive programs can be useful even if they are completely side effect-free. They can just return a result to the caller.
Daniel Brückner
@DanielBrückner: I'm not sure that I would count a bunch of functions that are meant to be run from the REPL as a program. For me a program has a main function (or, well, main IO) and a main function can't just return the result to the caller, as the caller is the operating system. Also in haskell the type of main needs to be `IO ()` so you can't just do `main = 42`.
sepp2k