F# - On the parameters passed to C# methods - are they tuples or what?

c#, f#, parameters, tuples

Solution

When passing arguments to functions from other .NET libraries, you use a syntax like ".MethodName(parm1, parm2)", that is, the parameters are passed as a Tuple.

It's more hideous than that. See the description of method overload resolution strait from the language spec.

What it says, basically, is that argument in a method invocation isn't really a tuple. It's a syntactic tuple, meaning a comma-separated list of something, but the parentheses are part of the method call syntax, and so are the commas. It's why, for example, `o.M(a=1, b=2)` isn't a method call with a tuple of two booleans, but rather two named arguments.

So, normally, every comma-separated component just maps to a distinct argument. Hence why `Add(1, 2)` calls `Add(int, int)` overload, and `Add((1, 2))` calls `Add(Tuple<int, int>)`. There is no ambiguity here.

However, a special case that kicks in for your particular case is this:

If there are no named actual arguments, and there is only one candidate method in `M`, accepting only one non-optional argument, then the decomposition of `arg` to tuple form is ignored and there is one named actual `arg` which is `arg` itself.

So when you removed all overloads except for the tuple one, suddenly the entire thing inside the parentheses is effectively treated as a tuple constructor in a call. But if you'd e.g. have two overloads, `Add(int)` and `Add(Tuple<int,int>)`, then a call of the form `Add(1,2)` wouldn't resolve at all.

Problem

I've read many times that Assemblies generated from F# or any other .NET language are (almost) indistinguishable. I was then experimenting with F# and C# interop on .NET 4 (beta 2). I created a new solution, and a C# project, with the following class: ``` public class MyClass { public static int Add(int a, int b) { return a + b; } } ``` Then, on a F# project, after referencing the C# project, I tried: ``` MyClsas.Add(4, 5) |> printfn "%d" // prints 9 (no kidding!) ``` So far so good. Then another sentence I've read many times (perhaps on different books) came to my mind: When passing arguments to functions from other .NET libraries, you use a syntax like ".MethodName(parm1, parm2)", that is, the parameters are passed as a Tuple. Add that to something that I've once read here on SO (but wasn't able find it to link to), on a question where the OP was trying to create a using like `[ 4, 5, 6 ]` (when he meant `[4; 5; 6]`): "Comma is the 'tuple creating operator', for everything else use semi-colon." Then I modified my class to the following: ``` public class MyClass { public static int Add(int a, int b) { return a + b; } public static int Add(Tuple<int, int> a) { return a.Item1; } } ``` Now I tried to use it on F#: ``` MyClass.Add(4, 5) |> printf "%d" // prints ... (keep reading!) ``` So, adding up the three quotations above, one can conclude that: - F# will create a Tuple when it sees `(4, 5)` - Then it will call the overload `Add(Tuple<int, int>)` - So it will print 4 To my surprise, it printed 9. Isn't it interesting? What is really happening here? The above quotations and this practical observations seems to be in contradiction. Can you justify F#'s "reasoning", and maybe pointing to some MSDN docs if possible? Thanks! EDIT (to add more information (from Blindy's answer)) If you do: ``` MyClass.Add((4, 5)) |> printfn "%d" // prints 9 ``` F# calls the `Add(Tuple<int, int>)` overload. However, if you create another F# project (so a different assembly) with this: ``` namespace MyFSharpNamespace type MyFShapClass = class static member Add x y = x + y end ``` You can use it on C# like this ``` public static void Main(string[] args) { MyFSharpNamespace.MyFSharpClass.Add(4, 5); } ``` So far so good. Now, when you try to use it from F# (from another project, another assembly), you have to do: ``` MyFSharpNamespace.MyFSharpClass.Add 4 5 |> printfn "%d" ``` If you pass the arguments as `(4, 5)` F# will not compile because `Add` is `int -> int -> int`, and not `(int * int) -> int`. What is happening?!?

Original source