Why is "do" allowed inside a function?

f#, language-specifications

Solution

From the documentation on MSDN:

A `do` binding is used to execute code without defining a function or value.

Even though the spec doesn't contain a comprehensive list of the places it is allowed, it is merely an expression asserted to be of type `unit`. Some examples:

if ((do ()); true) then ()
let x: unit = do ()

It is generally omitted. Each of the preceding examples are valid without `do`. Therefore, `do` serves only to assert that an expression is of type `unit`.

Problem

I noticed that the following code compiles and works in VS 2013: ``` let f() = do Console.WriteLine(41) 42 ``` But when looking at the F# 3.0 specification I can't find any mention of `do` being used this way. As far as I can tell, `do` can have the following uses: - As a part of loop (e.g. `while expr do expr done`), that's not the case here. Inside computation expressions, e.g.: ``` seq { for i in 1..2 do do Console.WriteLine(i) yield i * 2 } ``` That's not the case here either, `f` doesn't contain any computation expressions. Though what confuses me here is that according to the specification, `do` should be followed by `in`. That `in` should be optional due to lightweight syntax, but adding it here causes a compile error (“Unexpected token 'in' or incomplete expression”). Statement inside a module or class. This is also not the case here, the `do` is inside a function, not inside a module or a class. I also noticed that with `#light "off"`, the code doesn't compile (“Unexpected keyword 'do' in binding”), but I didn't find anything that would explain this in the section on lightweight syntax either. Based on all this, I would assume that using `do` inside a function this way should not compile, but it does. Did I miss something in the specification? Or is this actually a bug in the compiler or in the specification?

Original source