Reputation: 4505
In this example:
let generateStamp =
let mutable count = 0
(fun () -> count <- count + 1; count)
generateStamp ()
generateStamp ()
// prints 1 and 2
Isn't mutable count allocated for every generateStamp() call ? If that happens you would have to store the result of that call in order to be able to increment the counter, but that does not seem to be the correct assumption here.
Upvotes: 1
Views: 85
Reputation: 17153
No. You've defined generateStamp
to be a value, so it's only evaluated once, binding the name generateStamp
to a lambda of type (unit -> int)
. Every invocation of that lambda then shares the same count
variable.
If you had defined it as a plain function instead, every invocation would allocate its own count
, like this:
let generateStamp () =
let mutable count = 0
count <- count + 1; count
generateStamp () // 1
generateStamp () // also 1
Note that the output is only different because generateStamp
is impure. For pure functions (i.e. no side-effects), the output of the two versions would always be the same (although one might be faster than the other).
Also, note that the type signature is slightly different for the two versions. The first one is (unit -> int)
, while the second one is unit -> int
. (I'm not sure if this is anything more than a quirk of the F# compiler, but it's interesting to be aware of nonetheless.)
Upvotes: 3
Reputation: 3470
No. An amateur (in this regard) tries to explain:
You are not calling a function named generateStamp. generateStamp has a value which is a function, expressed as a lambda. generateStamp is calculated once before you call the function it has. Part of that calculation is to set count to zero. So that happens only once.
The expression generateStamp ()
means that you first retrieve a function with the expression generateStamp
, however which way that comes about - meaning it could be a declared function or a computed value as in this case. Then you supply an argument to make it execute.
The expression generateStamp ()
looks just like a normal function call, unlike in C# where you have to deal with this sort of thing in a much more cumbersome way. When we talk about functions being first-class members of the language, this is part of what it is about.
Upvotes: 1