The best explanation I heard of design patterns is, that they are not a template to slavishly follow when producing code, but a common language to talk about code. So you should be able to go and
identify, look, this is an iterator, this is a command pattern, this is a monad, and you have a clear and concise way to reason about your code and talk to other people.
The second best explanation is that patterns are often a sign of shortcomings in the language. OP gives the example of iterators. Another example is the visitor pattern. Or async/yield as a replacement for explicit state machines.
A thing I'd really like to see in a language would be language level support for the command pattern (being able to capture arbitrary blocks of code, lift the execution to an object, and undo/redo it). Or to be able to include the state of an object in the type system - not like Rust does it with typestates, but to be able to say `Child` is a `Person` where `age < 18`, and if the compiler can't prove that the condition always holds, then it will force you to write the precondition checks or check it at runtime.
The second best explanation is that patterns are often a sign of shortcomings in the language. OP gives the example of iterators. Another example is the visitor pattern. Or async/yield as a replacement for explicit state machines.
A thing I'd really like to see in a language would be language level support for the command pattern (being able to capture arbitrary blocks of code, lift the execution to an object, and undo/redo it). Or to be able to include the state of an object in the type system - not like Rust does it with typestates, but to be able to say `Child` is a `Person` where `age < 18`, and if the compiler can't prove that the condition always holds, then it will force you to write the precondition checks or check it at runtime.