none
Multiline Parameterlists

    Question

  • I have a member definition with a long parameterlist. For example:

    member MemberExample (parameterA:int, parameterB:double, parameterC:double, ... ) =
    ...

    Is it possible to define this member multiline? In C# it's just a line break. Using a line break in F# i received a warning:

    warning FS0058: Possible incorrect indentation: this token is offside of context started at position (51:39). Try indenting this token further or using standard formatting conventions.

    What's the right way in F#?

    Thursday, April 26, 2012 11:33 AM

Answers

  • You need the argument list to continue after the open parenthesis of the arguments, e.g.

    type SomeType() =

        static member SomeExample(a, b,

                                  (c:int), d) =

                a + b + c + d

        static member

         SomeExample2(a,

                      b,

                      (c:int),

                      d) =

                a + b + c + d


    Brian McNamara [MSFT]


    Monday, April 30, 2012 9:14 PM
    Moderator

All replies

  • You can have function parameters on different lines like this:

    let funcwithlongParamList p1 
        (p2: int) 
        p3 =
            p1 + p2 + p3 + 2
    
    funcwithlongParamList 1 1 1
    
    > 
    val it : int = 5

    However to improve code readability you may use:

    1. Compiler type inference which helps to get rid of type annotations in function parameters

    2. Function partial application if you have default values for some function parameters: http://msdn.microsoft.com/en-us/library/dd233229.aspx

    3. Create a simple record type with your parameters and pass it to a function as a parameter


    Petr


    • Edited by Plepilov Thursday, April 26, 2012 12:39 PM
    Thursday, April 26, 2012 12:39 PM
  • Hi Plepilov,

    thank you for your reply.

    What you've written works for me for "normal functions":

    You can have function parameters on different lines like this:

    let funcwithlongParamList p1 
        (p2: int) 
        p3 =
            p1 + p2 + p3 + 2
    
    funcwithlongParamList 1 1 1
    
    > 
    val it : int = 5

    In my case i want to implement a F# - library for a C# project. So i have to wrap my functional code into members - the methods for the C# project. If i define my member like you've written:

    member MemberExample(parameter1,
    	parameter2,
    	...) =
    	...

    i still get the warning. Do i something wrong?

    Thursday, April 26, 2012 1:41 PM
  • I think you still can use this declaration:

    type SomeType() = 
        member m.someFunc a
               (b: int) (c:int) 
               (d: int) = 
            a + b + c + d + 3;

    It will be compiled to method that could be consumed from C# (here is a snippet from ildasm output):

    .method public instance int32  someFunc(int32 a,
                                            int32 b,
                                            int32 c,
                                            int32 d) cil managed

    Also you could find this document useful:

    Draft F# component design guidelines.

    http://research.microsoft.com/en-us/um/cambridge/projects/fsharp/manual/fsharp-component-design-guidelines.pdf


    Petr

    Thursday, April 26, 2012 2:01 PM
  • Hi Plepilov,

    thank you, that works fine.

    But now i have the situation, that i have an overloaded static member.

    If i write:

    type SomeType() =
    	static member SomeExample a b 
    		(c:int) d =
    			a + b + c + d

    i got an error:

    The method 'SomeExample' has curried arguments but has the same name as another method in this type. Methods with curried arguments cannot be overloaded. Consider using a method taking tupled arguments.

    If i do not use curried arguments:

    type SomeType() =
    	static member SomeExample (a, b,
    		(c:int), d) =
    			a + b + c + d

    i got the previous error:

    Possible incorrect indentation: this token is offside of context started at position (24:41). Try indenting this token further or using standard formatting conventions.

    Do you have any ideas how to solve this situation? I've read the component design guidlines document, but i couldn't find any help for this special situation. In both situations i use a signature file.

    In the first case it looks like:

    static member SomeExample: float -> float -> int -> float -> float

    In the second:

    static member someExample: float * float * int * float -> float
    Friday, April 27, 2012 7:41 AM
  • It seems that in this case (overloaded method) you have to use tupled arguments. As stated here: http://msdn.microsoft.com/en-us/library/dd483468.aspx

    "However, overloaded methods are permitted in the language, provided that the arguments are in tuple form, not curried form."

    I don't think that you could put them on different lines in this case.


    Petr

    Friday, April 27, 2012 1:15 PM
  • You need the argument list to continue after the open parenthesis of the arguments, e.g.

    type SomeType() =

        static member SomeExample(a, b,

                                  (c:int), d) =

                a + b + c + d

        static member

         SomeExample2(a,

                      b,

                      (c:int),

                      d) =

                a + b + c + d


    Brian McNamara [MSFT]


    Monday, April 30, 2012 9:14 PM
    Moderator
  • Hi Brian McNamara,

    yes, that works. Thank you :)

    Wednesday, May 2, 2012 9:42 AM