I'm learning F# and I cannot figure out what the difference between let, fun and function is, and my text book doesn't really explain that either. As an example:
let s sym = function
| V x -> Map.containsKey x sym
| A(f, es) -> Map.containsKey f sym && List.forall (s sym) es;;
Couldn't I have written this without the function
keyword? Or could I have written that with fun
instead of function
? And why do I have to write let
when I've seen some examples where you write
fun s x =
...
What's the difference really?
The let keyword is used in binding expressions to define values or function values for one or more names. The simplest form of the let expression binds a name to a simple value, as follows. F# Copy. let i = 1.
The fun keyword is used to define a lambda expression, that is, an anonymous function.
Similarly, OCaml functions do not have to have names; they may be anonymous. For example, here is an anonymous function that increments its input: fun x -> x + 1 . Here, fun is a keyword indicating an anonymous function, x is the argument, and -> separates the argument from the body.
These things are sort of shortcuts to each other.
The most fundamental thing is let
. This keyword gives names to stuff:
let name = "stuff"
Speaking more technically, the let
keyword defines an identifier and binds it to a value:
let identifier = "value"
After this, you can use words name
and identifier
in your program, and the compiler will know what they mean. Without the let
, there wouldn't be a way to name stuff, and you'd have to always write all your stuff inline, instead of referring to chunks of it by name.
Now, values come in different flavors. There are strings "some string"
, there are integer numbers 42
, floating point numbers 5.3
, Boolean values true
, and so on. One special kind of value is function. Functions are also values, in most respects similar to strings and numbers. But how do you write a function? To write a string, you use double quotes, but what about function?
Well, to write a function, you use the special word fun
:
let squareFn = fun x -> x*x
Here, I used the let
keyword to define an identifier squareFn
, and bind that identifier to a value of the function kind. Now I can use the word squareFn
in my program, and the compiler will know that whenever I use it I mean a function fun x -> x*x
.
This syntax is technically sufficient, but not always convenient to write. So in order to make it shorter, the let
binding takes an extra responsibility upon itself and provides a shorter way to write the above:
let squareFn x = x*x
That should do it for let
vs fun
.
Now, the function
keyword is just a short form for fun
+ match
. Writing function
is equivalent to writing fun x -> match x with
, period.
For example, the following three definitions are equivalent:
let f = fun x ->
match x with
| 0 -> "Zero"
| _ -> "Not zero"
let f x = // Using the extra convenient form of "let", as discussed above
match x with
| 0 -> "Zero"
| _ -> "Not zero"
let f = function // Using "function" instead of "fun" + "match"
| 0 -> "Zero"
| _ -> "Not zero"
I guess you should really ask MSDN, but in a nutshell:
let
binds a value with a symbol. The value can be a plain type like an int
or a string
, but it can also be a function. In FP functions are values and can be treated in the same way as those types.
fun
is a keyword that introduces an anonymous function - think lambda expression if you're familiar with C#.
Those are the two important ones, in the sense that all the others usages you've seen can be thought as syntax sugar for those two. So to define a function, you can say something like this:
let myFunction =
fun firstArg secondArg ->
someOperation firstArg secondArg
And that's very clear way of saying it. You declare that you have a function and then bind it to the myFunction
symbol.
But you can save yourself some typing by just conflating anonymous function declaration and binding it to a symbol with let
:
let myFunction firstArg secondArg =
someOperation firstArg secondArg
What function
does is a bit trickier - you combine an anonymous single-argument function declaration with a match
expression, by matching on an implicit argument. So these two are equivalent:
let myFunction firstArg secondArg =
match secondArg with
| "foo" -> firstArg
| x -> x
let myFunction firstArg = function
| "foo" -> firstArg
| x -> x
If you're just starting on F#, I'd steer clear of that one. It has its uses (mainly for providing succinct higher order functions for maps/filters etc.), but results in code less readable at a glance.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With