Live data from Hacker News

Design Patterns Are Temporary, Language Features Are Forever

ptrtojoel.dev

11–20 of 67 posts

Re: Design Patterns Are Temporary, Language Features Are Forever

#11
post #5

Earlier quoted context omitted.

An insightful comment, but to be fair many important GoF design patterns like Composite and Decorator are genuinely object oriented, leveraging polymorphism and interfaces to produce order and elegance.

Order and elegance? Some people say that GoF patterns are just a way to cover up for OOP-centric language shortcomings.

They absolutely are, and aren't strictly necessary in many functional or multiparadigm languages.

Re: Design Patterns Are Temporary, Language Features Are Forever

#12
post #5

Earlier quoted context omitted.

An insightful comment, but to be fair many important GoF design patterns like Composite and Decorator are genuinely object oriented, leveraging polymorphism and interfaces to produce order and elegance.

Order and elegance? Some people say that GoF patterns are just a way to cover up for OOP-centric language shortcomings.

Object-oriented order and elegance compared to an object-infested mess of special cases and complications. Remember that 25 years ago C++ wasn't a pleasant place and Design Patterns was an impressive step forward.

Re: Design Patterns Are Temporary, Language Features Are Forever

#13
post #9

You don’t come across visitors every day, and they aren’t something to reach for instead of a simple switch, but if you are writing a Webpack or ESLint plugin or something like that, you might encounter them for traversing an AST. It’s not just an OO thing, either. I learned the visitor pattern in pretty ideal circumstances: from a classmate, back in college, when we were writing a compiler together for a class proje…

The problem with the visitor pattern is that it hides the traversal which can be good for some things but then lead to weird bugs (e.g. imagine walking a tree with a buffer in the visitor, then the thing that runs your visitor runs the nodes more than you expect and so on) e.g. I've seen bad code slip past a compiler because the visitor didn't realize it was being run on every node in the tree so it never actually found the pattern it was trying to match.

Re: Design Patterns Are Temporary, Language Features Are Forever

#14
I've seen it said that Alexander working on this stuff just at the moment of peak OOP-timism is a great shame/tragedy. I'm inclined to agree.

Functional purists like to glibly say that their patterns are discovered rather than invented. I used to Pooh Pooh this a bit. Then I had to write a class just to have a function to call. They're right.

Re: Design Patterns Are Temporary, Language Features Are Forever

#15
I disagree with the main thrust of the article, that the Visitor pattern is primarily a primitive way to do pattern matching.

For one, the Visitor pattern (as written in the article) fails to fulfill a core feature of Rust pattern matching, which is having a compact language to describe when something matches based on values, as opposed to the concrete type.

For another, you could equally well say that if-else blocks or ternary statements are also primitive pattern matching, if you're willing to stretch things that far.

In my view, the core reason people reached for the Visitor pattern in the past is that old Java didn't have convenient lambdas (anonymous functions). Visitors let you create an interface that mimics functional map.

Newer versions of Java have made lambdas much more convenient, so there's less motivation to reach for the Visitor pattern. You also saw this development in C#, where delegates were a language feature that often obviated rolling your own Visitors.

Re: Design Patterns Are Temporary, Language Features Are Forever

#16
The visitor pattern is a way of getting multiple dispatch in a language with single dispatch.

It can also be seen as a way of encoding a functional solution to the expression problem in an OO language, which is useful when you have a set of objects and want to make it easy to add new operations to them, not create new types of objects.

Re: Design Patterns Are Temporary, Language Features Are Forever

#17
post #5

Earlier quoted context omitted.

Order and elegance? Some people say that GoF patterns are just a way to cover up for OOP-centric language shortcomings.

They absolutely are, and aren't strictly necessary in many functional or multiparadigm languages.

FP languages have their own patterns. Some of them can be plausibly cast as "fixing weaknesses" in them, too.

Multiparadigm languages end up with lots of patterns you need to learn, because while multiparadigm languages may support many approaches to a given problem, generally there are definitely better and worse approaches, specific to the language in question, and between the number of options, the subtly of their implementation details and how those interact with the problem, and the specific preferences of the language itself (because all multiparadigm languages still have preferences), it can take a multiparadigm language community a decade to work out the best pattern for a given task. The existence of many options inevitably expands the number of wrong options, or if you prefer, "distinctly suboptimal" options, as well.

Re: Design Patterns Are Temporary, Language Features Are Forever

#18
post #5

Earlier quoted context omitted.

Order and elegance? Some people say that GoF patterns are just a way to cover up for OOP-centric language shortcomings.

Object-oriented order and elegance compared to an object-infested mess of special cases and complications. Remember that 25 years ago C++ wasn't a pleasant place and Design Patterns was an impressive step forward.

> "Remember that 25 years ago C++ wasn't a pleasant place"

25 years later it still isn't (joking... kind of)

Re: Design Patterns Are Temporary, Language Features Are Forever

#19
I think the visitor mimics pattern matching, but it really behaves/feels different. I think the visitor is really closer to a bridge from OOP land into FP land.

In FP its difficult/impossible to add new types but simple to add new mappings/pipelines for those types.

In OOP its easy to add new types but difficult/impossible to add new mappings/pipelines for those types (try transforming a POJO without lombok @Builder and @Value).

The visitor pattern (an OOP concept) allows us to more easily add a new mapping/pipeline for a set of related types. Normally in OOP this would involve adding a new method to a base class, implementing these new "mappings" in each subclass. With the visitor instead you just implement the new visitor, this allows the logic for this particular "kind" of mapping (visitor) to be grouped together, rather than represented by a method on a base class.

Post reply on HN