Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Different behaviour on F# module initialization

Tags:

f#

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?

like image 546
stmax Avatar asked Jul 10 '13 15:07

stmax


1 Answers

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;
}
like image 129
Daniel Avatar answered Oct 21 '22 05:10

Daniel