Il semble que lorsque vous utilisez "let .. in" vous pouvez outrepasser le paramètre par défaut de "#light" qui est que les espaces blancs sont significatifs, donc je suppose que c'est ce qui se passe dans ce cas et pourquoi vous n'obtenez pas d'avertissement/erreur dans le second cas (vous avez ajouté 'in', donc le compilateur pense que vous voulez spécifier la portée explicitement). Cela semble un peu bizarre et il s'agit peut-être d'un bogue. Je suis sûr que Brian de l'équipe F# répondra bientôt à ce doute :-).
Quoi qu'il en soit, je pense que le compilateur traite votre deuxième exemple de la même manière (en utilisant un exemple plus facile à compiler) :
open System
let ar = new ResizeArray<_>() in
let rnd = new Random();
ar.Add(rnd.Next())
printfn "%A" (rnd.Next())
Vous pouvez le forcer à le traiter comme vous le souhaitez en ajoutant des parenthèses et en écrivant quelque chose comme ceci :
let ar = new ResizeArray<_>() in
(let rnd = new Random()
ar.Add(rnd.Next()))
printfn "%A" (rnd.Next())
En général, vous pouvez utiliser des parenthèses pour spécifier des scopes à n'importe quel endroit du programme F#. Par exemple, vous pouvez écrire :
let a = 1
(let a = a + 10
printfn "%d" a)
printfn "%d" a
Cet exemple imprime "10" puis "1". Bien sûr, cela ne semble pas très pratique, mais c'est utile lorsque l'on utilise la fonction use
qui se comporte comme un mot-clé let
mais fonctionne pour IDisposable
et s'assure que l'objet est éliminé lorsqu'il quitte le champ d'application (c'est comme pour les objets using
en C#) :
let some = new Some()
(use file = new StreamReader(...)
let txt = file.ReadToEnd()
printfn "%s" txt)
doSomething() // continue, 'file' is now closed!
EDITAR : J'ai complètement oublié de mentionner le point important - la première façon d'écrire le code me semble plus naturelle (et elle utilise pleinement les avantages de la syntaxe #light "simple" qu'offre F#), donc je la préférerais :-).