It's the same with mutable vs immutable - we're finding that the defaults are wrong
- mutable vs immutable by default
- nullable vs unnullable by default
- imperative vs declarative by default
really, all these choices steer you toward the functional paradigm but not necessarily without object-orientation (Scala, and less so, F#)
but it's actually not too late to reverse the situation in C# - consider this
val x = 3; // immutable by default - type-inferred; doesn't imply out-lawing "var" but does begin a movement towards a saner default (well, actually, within a single method, if side-effects are constrained to it, supposedly it doesn't matter for purity;
still, val would be nice; and this doesn't mean transitively immutable - each type would still need to be implemented as immutable)
immutable unnullable class Person ... // self-evident, if bloated - but bloat at definition site is better than bloat at use site
invariant class Person ... // as above
immutable class Person! ... // as above
Strip away some paths of expression (implicit nullability, implicit mutability, implicit side-effects) and you give the compiler greater (or at least easier access to) freedom to do radical program transformation. I'd like to think that's where we're going...
One thing is reversing the present. Another is reversing the (sins of the) past - also known as the .Net Framework... But that reversal probably begins with a more principled C#.
Is there any actual compilers against functional language that can do analytical optimizations?