5

Background

In a language like F#, direct interoperability with most other .NET languages is possible. For example, it is possible to use classes written in C# directly in F#, and it is possible to call F# code directly from C#.

In F#, modules are compiled to CIL instructions corresponding to static classes, ADTs to a class hierarchy (abstract class + subclasses) and so on. This makes interoperability easy, but puts some limitations on language features.

For example, F# does not support higher-order modules like OCaml and SML does (or a 'similar' mechanism such as typeclasses or the like). Whether this is crucial or not is subjective, but it does limit the options to write polymorphic code (without using the OO parts of the language).

Interoperability through some interface

Of course, an alternative is not ignore the interoperability concerns in the main part of the language, and make some specific interoperability-interface. This could be one-way or two-way.

For example, in a language like F#, an alternative design could have been something like:

  • Let F# use C# classes directly, such as today. In this way, using .NET libraries is still easy.
  • Ignore C#'s ability to access functional F# code directly. This would remove some limitations that are currently imposed on the language design - we could in this way easily support a stronger type system, with higher-order modules or typeclasses, etc.
  • Let C# access the OO parts of F# directly. Hence, if you want to let our F# libraries be accessible from C#, we would have to put them in a thin'ish OO wrapper.

This would require a bit more work in some cases, but in my experience I would probably expect that most people would design an OO wrapper anyway, if an F# library is to be used in C#.

In case an F# library doesn't have an OO wrapper, it would still be possible to make one yourself (in F# obviously).

In the more extreme case, this interface could be two-way, such that F# could only access .NET classes through some interface as well - but there would probably be little reason to impose such restriction in this case. But for other languages, it might be an option - if for example, you wanted to write a pure language or something like that.

The actual question: Pros and cons

  • What are the pros and cons of each of these approaches?
  • Would it be technically unfeasible or impractical?
  • Would it be impossible for C# to interoperate with an assembly that is "misusing" the CLR or anything like that? (note, the question is not .NET specific, and you might as well base your answer on JVM langs like Scala, or whatever you know best)
  • Are there any languages which have used the inferfaced approach on? (on a higher level like .NET to .NET, and not just languages having an FFI to low-level code or the like)
  • 1
    SML.NET has SML's modules system and interprets namespaces and classes as modules but can interoperate with other .NET code provided the exported types aren't SML-specific – Doval Oct 10 '14 at 17:19
  • So you basically want for higher order types what type providers do for external data? – svick Oct 10 '14 at 22:23
  • @svick I am not completely sure what you mean. Type providers don't really provide the same functionality as higher-order modules or typeclasses. – nilu Oct 10 '14 at 22:58
  • @nilu I mean that a single type prover represents a set of types, that can't be expressed in the .Net type system. And a single higher-order type is also a set of types that can't expressed in the .Net type system. – svick Oct 11 '14 at 8:31
1

One of the issues is programming to a model. The other issue is programming to a machine. So you can program to a model and create an intermediate compilation that maintains any kind of special feature. The intermediate then needs to be something that programs a machine. There can be extra code given support libraries that provide compatibility for expanding the machines understanding or to downgrade what the code executes.

Ignoring functional code from C# does not improve F#. F# is currently modelling in a similar style as Ocaml (but for a .Net ecosystem) with enhancements and it is more a situation of F# working with the runtime and type system. If you expand what can be expressed by that runtime, every language can benefit.

Since delegates are designed like one method classes that are used to embody units of execution, things like lambda functions in C# are already thinly wrapped. F# does a similar thing with modules as classes with static methods. This is all for free.


It is not unfeasible to cut off one language from another. It is impractical to make languages harder to interoperate. The reasons are many goals are to extend and improve the runtime to allow more languages and to encourage cross library usage. Of particular with C#, it is not limited in what library it can call if it can consume an exposed and sensible values to its type system. The code can be unsafe and can be marked as such. It could (possibly by some future feature) mark code as advanced to allow it to do more that can be done in IL.

The problem managing the codebase for the checks to support the extra features in the compiler and the generators is to flesh out some useful code patterns found. So if you are generic in type, then the compiler would generate versions for every type of every kind that is a resolvable possibility or a lazy jitting generator base on use. Then you will think about what assures a kind is considered? Is it only a table lookup for usages or included scopes?

The easy out answer is time and desire. As outside influence voices its various opinions on matters and time allots itself to those issues, it comes to the attention of primary authors to consider the options. The usersvoice site helps. I myself have interest is in hygienic macros to expand beyond what and how I write code. Thank you. Good day.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.