Hi, it seems that when you use "let .. in" you can override the default "#light" setting which is that whitespace is significant, so I guess that's what happens in this case and why you don't get any warning/error in the second case (you added 'in', so the compiler thinks that you want to specify the scope explicitly). It seems a bit weird so it may be a bug. I'm sure Brian from the F# team will answer this doubt soon :-).
Anyway, I think the compiler treats your second example just as (using an easier to compile example):
open System
let ar = new ResizeArray<_>() in
let rnd = new Random();
ar.Add(rnd.Next())
printfn "%A" (rnd.Next())
You can force it to treat it as you wanted if you add parentheses and write something like this:
let ar = new ResizeArray<_>() in
(let rnd = new Random()
ar.Add(rnd.Next()))
printfn "%A" (rnd.Next())
In general, you can use parentheses to specify scopes in any place of the F# program. For example you can write:
let a = 1
(let a = a + 10
printfn "%d" a)
printfn "%d" a
This example prints "10" and then "1". Of course, this doesn't seem to be very practical, but it is useful when using the use
keyword that behaves like let
, but works for IDisposable
objects and ensures that the object is disposed when it leaves the scope (this is just like using
in C#):
let some = new Some()
(use file = new StreamReader(...)
let txt = file.ReadToEnd()
printfn "%s" txt)
doSomething() // continue, 'file' is now closed!
EDIT:
I completely forgot to mention the important bit - the first way of writing the code seems more natural to me (and it fully uses the benefits of "simple" #light syntax that F# offers), so I would prefer it :-).