17 ms·
I used to love F# before .NET Core, but then it was broken for two years for any sane design time experience on Core. I even wrote some rant about it with speci
by buybackoff 8y ago
I used to love F# before .NET Core, but then it was broken for two years for any sane design time experience on Core. I even wrote some rant about it with specific concerns I had (http://hotforknowledge.com/2016/10/19/4-functional-for-thought-imperative-for-hacking/ http://hotforknowledge.com/2016/10/19/4-functional-for-thoug...).
Two years later.. and very recently the .NET Core story started to work well, tooling improved to quite workable state, and in combination with C# it's very strong mix of practicality/performance + complex flexible abstractions and correctness.
Over that time F# has added quite a lot of low-level performance features (on par with C# - Span/Memory<T>, ref structs, struct tuples/unions, voidPtr, etc) and they just work. Build time is probably the main concern now, I have to disable building F# projects when they are in a solution but not touched because even on i7-8700/16GB it's very noticeable.
Two weeks ago I needed text parser and picked familiar FParsec. It's one of the fastest one in .NET (including C# ones) and is a mix of C# for low-level stuff and F# for powerful abstractions. I refactored it quite substantially and tooling was finally nice. But my attempts to micro-optimize it yielded only in substantially reduced GC due to the support of value structs and Span<T>, throughput was already quite optimal from .NET perspective (only c.<5% gain probably due to GC), so if used with care F# could be as fast as C# (which BTW is native-like fast when also used with care).
I believe such mix is the winning combination: C# is best for low-level high performance stuff, F# is best for complex things such as recursive data structures, analytics and so one.
My big concern is that F# community is great but often F#-only focused, e.g. reinventing existing C# libraries just because it's not F#. This isolationism from .NET as a uniform platform led for example to things such as F#'s `async` is better than Task Parallel Library (C#'s async/await machinery) in theory/design, but TPL is so much superior is usability, performance and deep platform integration but F# cannot use it directly. Without native TPL `task{}` F# is not a fully-featured .NET Core citizen but a niche language for specific tasks where it shines, e.g. to write a AST parser for a new query language. Sad that MSFT invests so little in F#, but the language is definitely is alive, is improving and is worth using.
- verinus 8y agoAs I understand it, F#'s async funktionality was there first, and C# TPL was modeled after it, but I might be mistaken... Anyhow I am with you that this is one of the problems I have with F#. Interop from F# to C# is generally pretty bad.
- buybackoff 8y agoYes, F# was the first with async. Interop with C# is native, all code is compiled to IL and JIT-ed together. Problem with TPL is that it is supported by Roslyn at the language level. The C# compiler rewrites async/await into very efficient state machine. F# cannot natively integrate into that state machine and a long async call chain is always broken on C#/F# boundary, while in C# async-only code could be compiled in a big state machine and with ValueTask (and even better IValueTaskSource that is used in Streams and Sockets in dotnet core 2.1+) a long running while(true) {await... } loop could be allications-free. Add to this upcoming in C# 8 AsyncStreams and importance of this increases. F# allocates a lot on every boundary and basically cannot be a part of a high preformance async data processing pipeline where GC latency pauses are important. Throughput is also lower. There is a way to hook into the state machine manually, but it's still less efficient, cumbersome and unmaintainable. Been there - done that.
- verinus 8y agoOfc everythink is IL but working with Options in C# is not fun at all... same with F# async and C#...not belding well into each other- some things I meant when saying that interop is not good imho. I am with you in thinking, that there should be only one mechanism and that C#s async is superior...
- pjmlp 8y agoTPL also got feedback from the Midori experience with System C#. http://joeduffyblog.com/2015/11/19/asynchronous-everything/ http://joeduffyblog.com/2015/11/19/asynchronous-everything/