So I’ve just about finished my first F# program, with my only functional background being a little bit of knowledge of Haskell (read: Haven’t really produced any programs in it).
After experiencing some boggling behavior, I came to realize that F# makes a differentiation between:
prepareDeck = allSuits |> List.collect generateCards |> shuffle
and
prepareDeck() = allSuits |> List.collect generateCards |> shuffle
I noticed that it “caches” the former, never recalculating it if it’s called again, whereas it treats the latter like a normal function. You can’t tell the difference if the function in question doesn’t have side effects, obviously, but my shuffle did!
Was this supposed to be common knowledge? I haven’t seen it mentioned on any tutorial materials yet. Is the reason just a weakness in the parser, kinda like how you have to declare a function before you use it?
Most F# material does explain that all top-level statements in a module are executed from top-down on declaration. In other words, what you’ve declared isn’t a function, but a value which is bound once when the program runs.
It really helps to see the reflected code. I have a simple file:
The compiled code looks something like this:
So one is a static property, the other is a function. This is a desirable property, because imagine if we had something like this:
We only want
xto be bound once, we don’t want it to invoke database function everytime we accessx.Additionally, we can write interesting code like this:
Since
isInNebraskais a value, its evaluated immediately. It just so happens that its datatype is(string -> bool), so it looks like a function. As a result, we only fill ourcitiesset once even if we invoke the function 1000 times.Let’s compare that code to this:
Oops, we’re creating a new cities set everytime we invoke the function.
So there is definitely a legitimate and real distinction between values and functions.