> pattern matching without the ability to check for exhaustiveness defeats the safety they provide
This holds for a lot of C# vs F# issues... There is a fundamental difference between "it's valid, but our tooling hides it from us" and "the execution environment guarantees that it can never happen".
The single pass compiler, functional foundation, currying syntax, and other features that provide guarantees simply can't be replaced with equally robust syntactical sugar. Much in the same way that writing imperative programs that follow OOP principles in possible, but will never give you the system level guarantees that a compiled class sytem will.
I'm guessing that's a reference to how, in an F# project, files have a specific order in which they're compiled, and you can only refer to things that are declared previously in the current file, or in a previous file.
It makes accidentally creating circular dependency graphs, which can be a source of technical debt, difficult to do. There is still a facility for introducing mutual recursion, but you have to do it explicitly.
This holds for a lot of C# vs F# issues... There is a fundamental difference between "it's valid, but our tooling hides it from us" and "the execution environment guarantees that it can never happen".
The single pass compiler, functional foundation, currying syntax, and other features that provide guarantees simply can't be replaced with equally robust syntactical sugar. Much in the same way that writing imperative programs that follow OOP principles in possible, but will never give you the system level guarantees that a compiled class sytem will.