Search code examples
f#functional-programmingpass-by-referenceoutref

F# pass by reference


I'm trying to pass by reference in F#. In C#, it is pretty easy using the ref and out keywords, but it seems in F#, it is not that simple. I just read this: http://davefancher.com/2014/03/24/passing-arguments-by-reference-in-f/, which suggests using a reference cell. (I suppose this means there is no analog to the out keyword in C# where you don't have to initialize a variable to pass it.)

But anyway, I'm wondering if this is the best/only way to pass by reference in F#, and if this is even a good idea in a functional language.

EDIT:

I am interested because I just realized that exceptions were slowing down my code. I'm on a crusade to eliminate them. Basically, my plan is this: say a function returns a double or throws an exception if there is an error. Instead, I'll pass in a double and an ErrorCode type by reference as a bit mask and then pass the values and the errors down. I'm guessing I'll just have to make all these variables mutable.


Solution

  • Your question has a number of parts which I will try to answer:

    • which suggests using a reference cell

      • Yes, Reference Cells (or ref cells) are the idiomatic way to pass mutable data into a function
    • I suppose this means there is no analog to the out keyword in C# where you don't have to initialize a variable to pass it.

      • C# usually uses out parameters to signify additional return values. The idomatic way to do that in F# is with tuples. For example the C# function int TryParse(string s, out bool succeeded) is simply TryParse(s : string) -> (int, bool)
    • if this is even a good idea in a functional language.

      • This is certainly not what I would consider to be normal, idiomatic F# code. The way I would represent this would be with a Discriminated Union representing the possible results:

    type MyFunctionResult = 
        | Success of double
        | ErrorCase1
        | ErrorCase2 of AddditionalDataType
    

    etc

    If you have a number of functions that use this style, it's very easy to compose them together with a bind function.