I just started to learn F#. The book uses the following notation:
let name() = 3
name()
what that differs from this:
let name = 3
name
?
I just started to learn F#. The book uses the following notation:
let name() = 3
name()
what that differs from this:
let name = 3
name
?
Using ()
creates a function which takes a paramter of type unit
, rather than the second case which is just a simple integer.
This is particularly important when you want to control execution of the function.
The main difference is when you have
let name() =
printfn "hello"
1
vs
let name =
printfn "hello"
1
then
let t = name + name
will print "hello" once. But
let t = (name()) + (name())
will print "hello" twice.
You have to be careful with this when considering the order in which functions are evaluated.
Consider the following program:
let intversion =
printfn "creating integer constant"
1
printfn "integer created"
let funcversion() =
printfn "executing function"
1
printfn "function created"
let a = intversion + intversion
printfn "integer calculation done"
let b = (funcversion()) + (funcveriosn())
printfn "function calculation done"
This will print the following in order
In
let name() = 3
name()
name
is a function, of type unit -> int
.
In
let name = 3
name
name
is an integer, of type int
.
In F#, every function has an input type and an output type. The input type of let name() = 3
is unit
, which has only one value ()
. Its output type is int
, which has values from –2,147,483,648
to 2,147,483,647
. As another example type bool
has only two values, true
and false
.
So back to you question what's the usage of ()
. If you don't specify the input value of a function, it cannot get executed. So you have to specify an input value to your function let name()=3
to get it executed and because of its input type is unit
, the only value you can use is ()
.
Here is another way to define the name function:
let name : (unit -> int) = (fun _ -> 3);;
and compare this to:
let name : int = 3
Definitely do NOT think of ()
as some syntax for a function call or anything like that. It's just a value, like 3, 5, 'q', false, or "blah". It happens to be a value of type Unit
, and in fact it's the only value of type unit, but really that's beside the point. ()
here is just a value. I can't stress that enough.
First consider
let name x = 3
What's this? This just defines a function on x, where x can be any type. In C# that would be:
int Name<T>(T x)
{
return 3;
}
Now if we look at let name () = 3
(and I somewhat recommend putting that extra space there, so it makes ()
look more a value than some syntactic structure) then in C# you can think of it as something like (pseudocode)
int Name<T>(T x) where T == Unit //since "()" is the only possible value of Unit
{
return 3;
}
or, more simply
int Name(Unit x)
{
return 3;
}
So we see that all let name () = 3
is, the definition of a function that takes a Unit
argument, and returns 3, just like the C# version above.
However if we look at let name = 3
then that's just a variable definition, just like var name = 3
in C#.
Before answering what
()
is lets get some basics defined and some examples done.In F# a let statement has a name, zero or more arguments, and an expression.
To keep this simple we will go with:
If there are no arguments then the let statement is a value.
If there are arguments then the let statement is a function.
For a value, the result of the expression is evaluated only once and bound to the identifier; it is immutable.
For a function, the expression is evaluated each time the function is called.
So this value
will always have the time when it is first evaluated or later invoked, i.e.
and this function
will always have a new time each time it is evaluated, i.e.
Now to explain what
()
means. Notice thatSystem.DateTime.Now
needs no arguments to work.Every argument has to have a type, so F# has the unit type for functions that need no arguments and the only value for the unit type is
()
.So this is a function with one argument
x
of typeint
and this is a function with one argument
()
of typeunit