简体   繁体   中英

F# module effects upon loading

I suspect that this behavior may not be unique to F#, but I'll pick on it since that's what I'm using for work.

suppose I have a module

open System

module Bar =
    let bar =
        Console.WriteLine("BAR!")
        "bar"

and I have the following in an fsx:

// this is a standard library function (Operators.defaultArg or Option.defaultValue)
let getValueOr v = function
| Some x -> x
| None -> v

let opt = Some "foo"

Console.WriteLine( opt |> getValueOr Bar.bar )

When I run this, I see the following printed

BAR!
foo

which is expected, since arguments are usually evaluated before the function body so I expect the effects in Bar.bar to be happen before getValueOr partially applies it (or even when the module is read).

However, when I compile the Bar module into a DLL and #r it, I see just

foo

In other words, Bar.bar doesn't get evaluated... why? Is it because of #r ?

This behavior is actually desirable for something I'm trying to create, but it's a little counterintuitive and I'd like to understand it better.

This happens because of optimizations.

When you run in FSI, optimizations are turned off, so everything works the way you expect it to work.

But when you compile in Release (ie with optimizations), F# compiler is able to do a lot more because it knows the structure of your code. In this case, the function getValueOr gets inlined at call site, and your last line turns into roughly the following:

// C# syntax
Console.WriteLine( foo == null ? Bar.bar : foo.Value )

Here's another interesting experiment: if you move the definition of the Bar module to the same place where Bar.bar is referenced, the effect will (probably) reappear, because the definition of bar itself will be inlined, roughly like this:

// C# syntax:
Console.WriteLine( "BAR!" )
var bar = "bar"
var foo = new Some("foo")
Console.WriteLine( foo == null ? bar : foo.Value )

The bottom line is this: uncontrolled effects are bad. They make your program unpredictable. Try to avoid them.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM