3 ms·
Calling F# Code in a C# Project
- mdip 9y agoGreat read, and I'm not just saying that because I used to work with this guy (sharp fella, but I digress) ... F# has always been one of those languages I have put on "the list" - that list of "gee, I should explore that a bit more" but could never find something that I really wanted to cut my teeth on with it. I was aware of some of the limitations around compatibility with other CLR languages but never quite got the "why" of it. For instance, C++/CLI has a handful of things that you can express in it[0] that cannot be expressed in C#, however, C# can consume these completely blocked features without issue. The breakdown between the two languages is interesting, particularly around "Cases with Types". I find it rather incredible that the exposed value in C# is so ... large? Several versions ago in F#, I wrote utility library that was mostly centered around string processing which I wanted to use with C#. I ended up scrapping it due to not being able to eek out the performance I needed. This bit of code makes me wonder how much magic is happening on the back-end with F# to make itself compatible with the CLR and if maybe some of that magic was responsible for the slowness[1]. Either way - great breakdown. I might crack a book on that language yet again. [0] The two that I know of are around generic constraints. In C++/CLR and CIL, itself, you can constrain a generic parameter to require that it be of type "enum" or "delegate". This allows one to write a number of very helpful utility classes that handle enums performantly and with high readability (I know this from personal experience having released a package that does just this). C# does not allow constraints of this nature, however, using a method that expresses this constraint works without issue. Consequently, the delegate conversions like the one from FSharpFunc to Func are one of the things I was aiming to address. [1] I want to say it was F# 2.x that I was dealing with and I haven't really given the language another try since then, so I can't speak to its current performance. I'm also broadly speculating about how well F# code matches up to CIL because I've never directly investigated it, so it could be that the F# representation is just dandy and ends up being plenty optimized ... obviously taking the C# representation of something that's represented in a different language is not a very good guide of what's really going on.
- akra 9y agoSaw a presentation on this was done awhile back. Most features are exposable to C# pretty easily - it's pretty easy to design libraries where consumers wouldn't know it was a F# type at first glance if you know how things compile down. If not directly you can always do simple things to make your types consumable in C# (e.g for my DU's I put a "match" member on them and have a Func argument for each case if exposed to C#). Or provide Func<> overloads for C# compatibility rather than the faster non-delegate FSharpFunc equivalents. One feature you can't use from C# is F#'s templated method support (SRTP) which I've used as a get-out-of-jail card when working with some pretty bad APIs due to static duck typing support. I think even the most basic features (e.g. deep structural equality) make it easier to write things especially libraries quicker in F# once you get the hang of it.
- JBReefer 9y agoThis is very well done, very understandable, and really drives home the "F# is laconic" thing. The amount of text in those generated classes is shocking, for the same functionality.
- platz 9y agodare you to open the network tab on this page..