I am looking at the following F# line
for i = 0 to i=10 do
Console.WriteLine("Hello")
An I am wondering that isn't the above line a statement as opposed to an expression?
Shouldn't everything be an expression in F#?
As already said, every syntactical construct in F# is an expression. F# does not distinguish between statements and expressions (and so I'd say that the WikiPedia quote posted by Robert is a bit misleading - F# does not have statements).
Actually, the above is not fully true, because some constructs in F# computation expressions such as let!
are not expressions, but we can ignore that.
What does that mean? In C#, the syntax of for
and method calls is defined something like this:
statement := foreach(var v in <expression>) <statement>
| { <statement> ... <statement> }
| <expression>;
| (...)
expression := <expression>.<ident>(<expression>, ..., <expression>)
| <literal>
| <expression> + <expression>
| (...)
This is very simplified, but it should give you the idea - a statement is something that does not evaluate to a value. It can be foreach
loop (other loops), a statement block (with multiple statements) or an expression with semicolon (where the result of the expression is void
or is ignored). An expression is, for example, method call, primitive literal (string, int) or a binary operator.
This means that you cannot write certain things in C# - for example, the argument of method call cannot be a statement (because statements do not evaluate to a value!)
On the other hand, in F#, everything is an expression. This means there is just a single syntactic category:
expression := for v in <expression> do <expression>
| <expression>; <expression>
| <expression>.<ident>(<expression>, ..., <expression>)
| <literal>
| <expression> + <expression>
| (...)
This means that in F# all syntactic constructs are expressions, including for
and other loops. The body of for
is also an expression, but it would not make sense if the expression evaluated to some value (i.e. 42
), so the types require that the result of the body is unit
(which does not carry any information). Similarly, the first expression in sequencing (<expr>; <expr>
) should return unit
- the result of sequencing is the result of the second expression.
This makes the language simpler and more uniform, but you can write some odd things:
let x = (for i in 0 .. 10 do printfn "%d" i); 42
This will print numbers from 0
to 10
and then define a value x
to be 42
. The assignment is a sequencing of expressions (<expr>; <expr>
) where the first one is for
loop (that has a type unit
, because it does not evaluate to anything) and the second one is 42
, which evaluates to 42.
Every statement in F#, including if statements and loops, is a composable expression with a definite return type. Functions and expressions that do not return any value have a return type of unit.
http://en.wikipedia.org/wiki/F_Sharp_(programming_language)
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