|
|
|
|
|
by thomasz
3941 days ago
|
|
Case in point: You can define a type as an enum, a discriminated union, a record type, an interface, an abstract class, a class or a struct. You can have a primary constructor for a class or struct, or like a method with the new() keyword. You have namespaces and modules. |
|
Yet in C# you have hard-coded keywords for things like System.Threading.Monitor (the lock keyword). This doesn't exist in F#-the-language, but is implemented via a simple function so it doesn't count. (Just like you wouldn't consider System.Math.Max part of C#-the-language).
In C#, you have hard-coded operators, whereas in F# they're essentially just functions (compile-time type parameters work similar to _Generic in C11). In C# you have hard-coded LINQ and async syntax, whereas in F# you don't (just one general construct for computation expressions).
People cite stuff like F# pipelining, but that's not a language feature, it's just a function. C# and F# both have quotations, but F#'s are more complete, not a one-off to implement LINQ-to-SQL. That reduces complexity, or is at least a tie. (In the way that arithmetic over integers is less complex than arithmetic over int32.)
Type extensions are another case of this. C# has them, but only partially implemented (extension methods), whereas F# implements the feature in a less complex way that provides more coverage.
OTOH, F# does stuff like transforming Int32.TryParse to match as a tuple (nice, but a complication). And it also has really ugly things like this one: Explicit parameter names take higher binding than = operator. Example:
My gut feeling is that once you subtract F#'s stdlib and add in C#'s plethora of edge cases, you're not actually significantly less complex in a meaningful way using C#, and F#'s improved uniformity wins out.