Counterpoint: languages (and libraries, and frameworks, and platforms) so well-designed that they introduce a "pit of success"[1] such that bad programmers naturally write better code than they would have done otherwise.
For example, what if PHP could somehow detect string-concatenation in SQL queries and instantly `die()` with a beginner-friendly error message explaining to use query parameterisation from the very beginning: tens of billions of dollars of PHP SQL injection vulnerabilities simply never would have happened - and people who were already writing database queries with string-concatenation in VB and Java who gave PHP a try would then be forced to learn about the benefits of parameterisation and they'd then take that improved practice back to their VB and Java projects - a significant net worldwide improvement in code-quality!
I've been writing in TypeScript for about 5 years now - and I'm in-love with its algebraic type system and whenever I switch back to C#/.NET projects it's made me push the limits of what we can do with .NET's type system just so I can have (or at least emulate as closely as possible) the features of TypeScript's type system.
(As for generics - I've wondered "what if every method/function was "generic" insofar as any method's call-site could redefine that method's parameter types and return types? Of course then it comes down to the "structural vs. nominative typing" war... but I'd rather be fighting for a hybrid of the two rather than trying to work-around an poorly-expressive type system.
For example, what if PHP could somehow detect string-concatenation in SQL queries and instantly `die()` with a beginner-friendly error message explaining to use query parameterisation from the very beginning: tens of billions of dollars of PHP SQL injection vulnerabilities simply never would have happened - and people who were already writing database queries with string-concatenation in VB and Java who gave PHP a try would then be forced to learn about the benefits of parameterisation and they'd then take that improved practice back to their VB and Java projects - a significant net worldwide improvement in code-quality!
[1]: https://blog.codinghorror.com/falling-into-the-pit-of-succes...
I've been writing in TypeScript for about 5 years now - and I'm in-love with its algebraic type system and whenever I switch back to C#/.NET projects it's made me push the limits of what we can do with .NET's type system just so I can have (or at least emulate as closely as possible) the features of TypeScript's type system.
(As for generics - I've wondered "what if every method/function was "generic" insofar as any method's call-site could redefine that method's parameter types and return types? Of course then it comes down to the "structural vs. nominative typing" war... but I'd rather be fighting for a hybrid of the two rather than trying to work-around an poorly-expressive type system.