If you’ve been programming in F# for any length of time then undoubtedly you’ve run into the term “call by value”. Another name for “call by value” is eager evaluation as opposed to lazy evaluation and the corresponding “call by name”. Let’s throw together a fun little program to demonstrate the difference between the two.
Call By Value
type MissileCommand =
| Launch
| Disable
let a1 = printfn “%A” “KABOOM!”
let a2 = printfn “%A” “WE LIVE!”
let run cmd a1 a2 =
match cmd with
| Launch -> a1
| Disable -> a2
run Disable a1 a2
So what do you think gets printed to the screen when we run our Disable command? You may be surprised to see the following written to the console.
“KABOOM!”
“WE LIVE!”
So how did the human race get obliterated when we sent the Disable command? In a “call by value” language functions arguments are evaluated eagerly, so both a1 and a2 are evaluated before the run function is applied to them. Scary!
Call By Name
To simulate “call by name” semantics in F# we are forced to explicitly wrap our functions in a lazy wrapper.
let lazy_a1 = lazy (printfn “%A” “KABOOM!”)
let lazy_a2 = lazy (printfn “%A” “WE LIVE!”)
let safe_run cmd (a1:Lazy<_>) (a2:Lazy<_>) =
match cmd with
| Launch -> a1.Force()
| Disable -> a2.Force()
safe_run Disable lazy_a1 lazy_a2
And now the human race is saved from nuclear annihilation as we get what we expect printed to the console.
“WE LIVE!”
The lazy wrapper acts as a thunk for the actual computation which only gets computed once we force it.
Call By Value With Side Effects
Now I hope you don’t lie await at night worrying about a computer bug accidently leading to Armageddon. I’m sure our nuclear missile system is written in a lazy language. But I do hope you get a feeling for what a noxious combination “call by value” and undocumented side effects are.
What if instead of printing to the console our action updated a global counter? Or deleted records from a database? Functional languages allow us to pass functions around as if they were data, but do we really want them evaluating them behind the scenes when they do?

Hello,
You can also use “unit -> unit” type functions as a sort of poor man’s lazy. For simple cases like this it probably more appropriate (although I do appreciate that it’s a simple example to illustrate the point). I’d probably have written:
type MissileCommand =
| Launch
| Disable
let a1() = printfn “KABOOM!”
let a2() = printfn “WE LIVE!”
let run cmd a1 a2 =
match cmd with
| Launch -> a1()
| Disable -> a2()
Cheers,
Rob
I think I missed your point. If I copy your ‘Call By Value’-example to say a F# Script File (.fsx) the signature of a1 is unit, the signature of a2 is unit and the signature of run is MissileCommand -> ‘a -> ‘a -> ‘a . What is supposed to be the link between the a1 and a2 values and the function run ?
If we want a1 and a2 to be treated like funktions and not (unit) values we should add parentheses. For readability I have renamed a1 and a2 to b1 and b2. The result is as one would expect; only b2 is evaluated.
#light
type MissileCommand =
| Launch
| Disable;;
let b1 () = printfn “%A” “Kaboom!”;;
let b2 () = printfn “%A” “We live!”;;
let run cmd b1 b2 =
match cmd with
| Launch -> b1
| Disable -> b2
run Disable b1 b2 ()
System.Console.ReadKey() //just so that the console is not closed right away
Best regards,
Robert Nielsen
Hello Mr Nielsen,
See Mr Pickering’s comment above for an answer to your question. Adding a () to your function creates a thunk to a function and not an actual function, you’re example is a simpler way to do lazy evaluation described above.
I would argue that lazy evaluation should be the default as opposed to the edge case. Do we really want programmers deciding whether to create functions or thunks to functions and then reasoning about how they will behave?
I wonder, I wonder…
Now what happens if we really really want to launch three missiles?
run Launch a1 a2
run Launch a1 a2
run Launch a1 a2
. How many “Kabooms” do we get?
A simple experiment shows that we get only one. So our potential enemy still has most of its nuclear weapons targeted at us. In this simple case the problem is simple to resolve, but what if we have those calls nested somewhere deep in our code?
After messing with Haskell for a while I’m pretty much convinced that lazy evaluation with side effects is evil.
In Haskell, the only way you could do IO inside a pure lazy function is making use of the function “unsafePerformIO”. And I believe it is called “unsafe” for a reason…
Hi Anonymous,
I guess it depends on your definition of an actual function. If I use .Net Reflector (freely available from http://reflector.red-gate.com/download.aspx) I see that b1 and b2 are indeed functions in the MS dotnet IL (Intermediate Language) sense.
I definitely agree with your comment “Do we really want programmers deciding whether to create functions or thunks to functions”; I am completely happy with the b1- and b2-functions the F#-compiler creates for me, even if they are thunks by your yardstick.
Yup, Rob’s comment is more concise than mine, but his comment wasn’t yet visible when I wrote my comment. :-)
From my perspective the connection between the original variables a1, a2 and the evaluation of printfn have only little to do with ‘Call By Value’. Even if you never call ‘run’ a1 and a2 will still be initialized (evaluated) early on in the program/script. Do you guys compile the program/script in some way so that a1 and a2 are allowed to be ‘optimized’ away? When I write a let-expression I expect the compiler to initialize my variable (and so it does).
In such a simple example I would probably have written:
#light
type MissileCommand =
| Launch
| Disable
let b1() = printfn “%A” “Kaboom!”
let b2()= printfn “%A” “We live!”
let run cmd =
match cmd with
| Launch -> b1()
| Disable -> b2()
run Disable
System.Console.ReadKey() //just so that the console is not closed right away
which emphasizes that it is the ‘cmd’ parameter that determines wheter to go “boom” or not.
Now also you get the obvious result (three times “Kaboom!”) if you want to launch three missiles:
run Launch
run Launch
run Launch
I appreciate we now have such a powerful language (F#) where we can express algorithms beautifully and yet relatively easily figure out how the compiler will interpret what we are writing. On a side note though, if I move the functions b1 and b2 inside of run like this:
let run cmd =
let b1() = printfn “%A” “Kaboom!”
let b2()= printfn “%A” “We live!”
match cmd with
| Launch -> b1()
| Disable -> b2()
then b1 and b2 are no longer static functions, but rather object methods. Do any of you have a good link to somewhere I can read about the reason behind that?
Thank you all for the examples and comments
Robert Nielsen
Robert Nielsen
There’s a good talk by Simon Peyton Jones introducing Haskell at OSCON. In the talk he mentions trying to write a conditional function in a “call by value” language. He says it can’t be done becuase “call by value” languages evaluate their parameters before applying the function to them.
The reason the functions are passed as parameters was to test whether this is really true. The example was a bit of a humorous attempt to test out the concept as opposed to a rather boring conditional function.
a1 and a2 are values of type unit and regarding their scope, they are assigned before the execution of the run function. Of course would they be initialized beforehand. They’re not functions, they just store the unit value.
I didn’t know F# so this puzzled me, but now I’m just disappointed.
sorry for that comment, you did show call by name evaluation and i was hindered by limited knowledge.