hubFS: THE place for F#

. . . are you on The Hub?
Welcome to hubFS: THE place for F# Sign in | Join | Help
in Search

Passing parameters "by reference"

Last post 05-20-2008, 3:58 by dsyme. 3 replies.
Sort Posts: Previous Next
  •  05-16-2008, 3:03 5921

    Passing parameters "by reference"

    I have this C# base class I want to derive from in F#, which has a helper method to set property values. This helper method does some additional work automatically, like change notification, so I would like to use it. Problem is, it's implemented using a "ref" parameter in C#.

    As far as I'm aware, the only way to call methods with C# ref parameters is by using a ref cell in F#, like so:

    C#:
            public void DoSomething(ref string foo) { ... }

    F#:
            let var = ref "Hi there"
            testclass.DoSomething(var)


    Now, in my real use case I have classes with lots of mutable members and properties that use said helper method. I'm currently using "mutable" for all the members. I could make them all ref cells instead and that would allow me to call the helper method without any fuss. But it doesn't feel like the right solution, because (a) using ref cells instead of variables everywhere introduces quite a bit of syntactical overhead and (b) I'm guessing that ref cells are quite a bit less performant if you have them everywhere - I'm happy to be corrected about this.

    Assuming I keep my "mutable" fields, I have found this way to implement my property setter code:

        let temp = ref x.var
        x.csharpclass.DoSomething(temp)
        x.var <- !temp

    Obvously this introduces overhead as well, albeit in a different place. And I don't know how easy it would be to abstract this away, so I wouldn't have to repeat that code in all my property setters - haven't looked into it.

    Anyway, (thanks if you're still reading!) here's my question: is there some other way of handling these calls in F#? In C#, passing a parameter by reference or not is a choice I can make at the point of the call. In F#, it seems to influence the whole way I declare my members. Is there something I'm missing?

    Thanks
    Oliver
  •  05-16-2008, 12:11 5927 in reply to 5921

    Re: Passing parameters "by reference"

    So, I spent some more time with this and analyzed the results of various syntactic variants in IL to see what F# is doing. As a result, I can see that as long as my fields are "just" mutables and not ref cells, they'll always get wrapped in a ref cell instance before being passed by reference.

    Since using a ref cell is the only way I'm aware of to force the F# compiler to pass the variable by reference (IOW - generate the "Type&" IL instead of simply "Type"), the solution that uses ref cells for all my fields seems the best one because I avoid creating and dropping them all the time.

    The difference in IL is this - passing by value:

    call instance void [ClassLibrary1]ClassLibrary1.Class1::TakeString(string)

    Passing by reference:

    call instance void [ClassLibrary1]ClassLibrary1.Class1::DoSomething(string&)

    It seems kind of weird that the ref cells should be the only way to do this. If I have a mutable variable, why is there no way to say "pass it to this function by reference", IOW tell the compiler to generate "Type&" IL? I'm sure there's something I'm not seeing, but creating a load of ref cells in this use case seems like a great waste of time and resources.

    Thanks
    Oliver

  •  05-17-2008, 4:37 5942 in reply to 5927

    Re: Passing parameters "by reference"

    This problem was solved with help from Brian McNamara - he pointed me to the important other, apparently secret <g>, way of passing parameters by reference, which I suspected to be around the whole time. Please see my blog post for the solution: http://www.sturmnet.org/blog/archives/2008/05/16/oddities-in-fc-interaction/
  •  05-20-2008, 3:58 5967 in reply to 5942

    Re: Passing parameters "by reference"

    Hi Oliver

    Thanks again for taking the time to report the resolution for the issue!

    Kind regards

    don

     

View as RSS news feed in XML
Powered by Community Server, by Telligent Systems