I have the following F# program:
open MyModule
printfn "%d" test
With MyModule being:
module MyModule
printfn "foo"
let test =
printfn "bar"
42
This produces the following output:
foo
bar
42
When I change MyModule to:
module MyModule
printfn "foo"
let test =
// printfn "bar" <-- note the comment!
42
... the result is:
42
Why doesn't "foo" get printed anymore?
I think section 12.5.1 of the spec, Execution of Static Initializers, has your answer. Quoting the relevant bits:
the static initializer for the file is executed on first access of a value that has observable initialization
and
All definitions have observable initialization except for the following definitions in modules:
The list that follows includes:
Non-mutable, non-thread-local values that are bound to a simple constant expression
After commenting out the first line of test
, it becomes a constant expression. So therefore, it no longer triggers static initialization.
EDIT
The spec doesn't provide the rationale for this behavior, but it's similar to C#'s. For example, in this code static initialization never occurs:
class Program {
static void Main(string[] args) {
Console.WriteLine(T.Integer);
Console.WriteLine(T.Null);
Console.WriteLine(T.Enum);
Console.Read();
}
}
static class T {
static T() {
Console.WriteLine("You won't see this.");
}
public const int Integer = 1;
public const string Null = null;
public const ConsoleKey Enum = ConsoleKey.Escape;
}
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