I can't agree more. Design pattern resources often omit the fact that "design patterns are missing features of programming languages". It's not a piece of common knowledge yet (at least outside HN), and I hope people could talk about this more.
Take the visitor pattern as an example: Say we have M types, and each type has N operations. OO languages like Java are good at extending M - you add another class. But it sucks at extending N because the obvious way is to add the operation as a method in every type. Visitor pattern helps you invert the problem, make it easier to extend N while suck at extending M. In fact, the visitor pattern feels more or less like it reinvented the plain, old "function" - just write a function and handle each type in it and you just achieved the same things.
I find it's always more readable when I just use a function. There's no exhaustive type checking so it makes sense to use the visitor pattern in Java, but I often people still use the pattern in, say, TypeScript without a second thought.
What if we want to extend M and N at the same time? There's a sophisticated design pattern called object algebra [0]. In this case, it's pretty clear that features like type class in Haskell and traits in Rust could solve the problem in straightforward ways without wrestling it with design patterns.
[0] https://en.wikipedia.org/wiki/Expression_problem#Problem_Sol...