F# also has first-class tuple types. But the better way to look at it is that you can have records and can put them in sum and products. Then for compat, there&#x27;s the types for .NET&#x27;s OO system. But sure, that&#x27;s an increase in complexity in F#.<p>Yet in C# you have hard-coded keywords for things like System.Threading.Monitor (the lock keyword). This doesn&#x27;t exist in F#-the-language, but is implemented via a simple function so it doesn&#x27;t count. (Just like you wouldn&#x27;t consider System.Math.Max part of C#-the-language).<p>In C#, you have hard-coded operators, whereas in F# they&#x27;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&#x27;t (just one general construct for computation expressions).<p>People cite stuff like F# pipelining, but that&#x27;s not a language feature, it&#x27;s just a function. C# and F# both have quotations, but F#&#x27;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.)<p>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.<p>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:<p><pre><code>  Foo(Bar = Baz) &#x2F;&#x2F; Calls Foo with argument Bar with value Baz 
  Foo((Bar = Baz)) &#x2F;&#x2F; Calls Foo(bool) with result of (=) Bar Baz
</code></pre>
My gut feeling is that once you subtract F#&#x27;s stdlib and add in C#&#x27;s plethora of edge cases, you&#x27;re not actually significantly less complex in a meaningful way using C#, and F#&#x27;s improved uniformity wins out.