| Great projects <3 I agree, source-generation is particularly unfortunate. I don't think it's a deal-breaker per se however - most of the time a small bindings project in C# is more than enough - I just accept it as a matter of life and get on with it, luckily it has not been particularly troublesome. Perhaps it's a bigger issue for people who would like to keep their projects C#-free (which is unfortunate, because C# is an awesome and productive language too). The bigger issues for me personally is support for low-level primitives. Because F# has full HM type inference and of course gets to enjoy the same performance of struct generics as C# does - it is tempting to write HPC code for which C# can't infer the full generic signature the way F# and Rust can. Unfortunately, however, in this specific area F# is outmatched because it has surprisingly less flexible pattern matching - list and array patterns in F# are bound to lists and arrays and you can't as easily match opaque objects, abstract classes or interfaces to a specific type with specific state inside, something that C# lets you do easily, where you can match, deconstruct, inline slice and unbox on any type that simply has the necessary "shape" without being bound to specific core types or interface implementations. You can work around most limitations with active patterns, but there is nothing that you can do that would give you `span is [var x, ..var rest]`. Continuing the last point - C# has really pushed forward in making span-based and general performance-oriented code simple and idiomatic. In F#, the use of ref structs is much more restricted (please do not hold it against the team that works on it - it's a complex piece of functionality, just look at https://em-tg.github.io/csborrow/ as a start). As a result, F# is an extremely powerful and productive language that sits in an awkward spot where it is frustratingly close to being "the OCamlish Rust for .NET" thanks to its incredible type system, but at the same time if you do care about maximum performance with heavy data manipulation - you will be better served by C# still simply because it would take a lot of effort to make these specific areas in F# work just as well. Important - these issues are _luxury_. Java ecosystem simply does not provide any alternatives due to limitations of the type system offered by JVM. So while indeed things could have been better, they do not have a proper alternative in Kotlin/Clojure/Scala at all, disqualifying them from certain performance domains completely. On AOT - as long as you avoid printfn in F# and use string interpolation with Console.WriteLine and such you should be getting no AOT warnings. With library code it can be tricky, but it's usually caused by the abuse of un-analyzable reflection. You can always ping authors to perhaps take a look at it or use something better if available :) I'm enjoying AOC with F# and FSharpPacker too, but sadly don't have time to continue. |
I’m curious in what industry you’re utilizing those features. I imagine you must be using mostly your own code since much of nuget contains things that don’t take performance as a first priority. I imagine it would be similar to the trading companies using Java where they toss out most of the standard library and most things on maven and create their own faster versions (which is also not dissimilar to gamedevs tossing out STL and making their own low-allocation libraries).