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)