tags:

views:

272

answers:

4

Recently I asked a question here about using F# extensions in C#. Brian quoted:

Per the language spec, section 10.7 "Type extensions":

Optional extension members are syntactic sugar for static members. Uses of optional extension members elaborate to calls to static members with encoded names where the object is passed as the first argument. The encoding of names is not specified in this release of F# and is not compatible with C# encodings of C# extension members.

I am wondering if there are any other interoperability issues in .NET that restricts the usage of some functionality to some languages but not others?

+6  A: 

I expect there are lots of things, but mostly in corner cases if you're talking about the major managed languages (C#, VB, and soon F#). Other cases where F# currently interacts poorly with C# is when there method overloads that take both Action and Func (the C# overload resolution works differently than F#, so F# calls to such an API may be more verbose); 'params' argument arrays (especially when trying to tak advantage of 'array covariance', which is a feature of C# but not F#); there are some issues regarding subclassing or implementing interfaces, combined with accessibility (e.g. public versus internal), where sometimes you cannot derive an F# class from a C# one...

Many of these issues are simply either 'bugs' in the F# CTP compiler or 'design issues' with the F# language spec that may be changed before the final release of F#.

I don't know the dusty corners of the CLR well enough, but I bet that there are places where C# and VB fails to mesh. And there are features of the CLR that none of the major languages use, so I expect there's ways to create valid IL that may cause problems with some interop.

Overall I think all this stuff is minor, and in the case of F#, a bit of it will be 'fixed' before the final release. But I will be curious to see what other things people call out, as it could be useful feedback for the managed language teams at MS.

Brian
Here's one: Optional parameters in C# versus VB.
MichaelGG
@MichaelGG that's resolved in 4.0 at least
ShuggyCoUk
+2  A: 

There's a set of guidelines released by Microsoft for dealing with this kind of thing. Basically it's for class designers, and includes suggestions such as not including methods which differ only by case (for case-insensitive languages like VB), providing alternate methods for for operators when operator overloading might not be available, etc.

Turnor
Oops, the link disappeared.http://msdn.microsoft.com/en-us/library/ms229042.aspx
Turnor
Thanks, I put the link for you.
Joan Venge
+1  A: 

Consuming f# classes from c# code can be tricky or annoying at times.

Events in f# are not 'normal' events by default

Adding the [<CLIEvent>] Attribute solves this but unless you use DelegateEvent rather than Event the c# code must reference FSharpCore.

First Class function's differences

Making a delegate out of a FastFunc (the back bone of f#'s functions) in f# is easy. Making a FastFunc from a delegate in c# is rather more annoying and is touched on here. In particular the Unit concept maps very badly back into c# and the Func/Action delegate world.

Operators

Operators defined in f# are poorly, and inconsistently, handled in other CLR languages. That is an inevitable result of the CLR not defining the sort of complex type meta data that would be required.
Operators should be considered language features and not expected to translate well between different languages. Any useful operator should have an equivalent static method that allows a consistent and portable means of accessing the functionality.

Type inference

In f# this is pervasive and as a result you may find some very complex types being constructed. Once used in c# this may become cumbersome since type inference on functions is not as powerful but worse it is entirely absent from constructors which can result in painfully verbose c# code.

ShuggyCoUk
+1  A: 

C++/CLI has "pass by value" semantics for CLR objects (not references, but objects themselves), complete with copy constructors, temporaries and their destruction, etc. You can write:

ref class Foo {
public:
  Foo() { ... }
  Foo(Foo% other) { ... }
};

and then:

Foo^ getFooRef() { ... } // returns a reference to Foo
Foo getFoo() { ... } // returns a copy of Foo

Of course, on CLR level it's all references - C++/CLI simulates copy semantics by calling constructors, operator=, and destructors at moments where you expect them to be called. In case of "return by value", it means that the caller will have to correctly destruct the object, reference to which it receives. Neither C#, nor VB, nor any other CLI language apart from C++/CLI know how to do it, so such methods aren't callable from them.

Another interesting bit is that CLR allows to define methods with ref return types. No CLR language supports them (not even C++/CLI), but you can hand-code one in MSIL, and it won't be callable from any other language.

In general, this sort of thing is precisely why Common Language Specification (CLS) was created. If you stick to its rules, you shouldn't have interoperability problem with any language.

Pavel Minaev