5 ms·
Key takeaway point: "Dynamic Languages have fewer language limitations, less need for bookkeeping objects and classes, less need to get around class-restricted
by wwweston 7y ago
Key takeaway point: "Dynamic Languages have fewer language limitations, less need for bookkeeping objects and classes, less need to get around class-restricted design. Study of the Design Patterns book: 16 of 23 patterns have qualitatively simpler implementation."
Or as someone else once put it, "design patterns" might more accurately be called something like "palliative idioms for pain points in static manifestly typed class-oriented languages."
That's a little bit unfair, given Smalltalk's place in all this, but one of the wastes of time over the last 20 years has been the ways in which some dynamic languages cargo-culted practices from, say, the Java world because Design Patterns™ were The Mark of A Professional™.
The fact this happened in JavaScript with Angular is particularly atrocious.
- erokar 7y agoI agree. The creators of Angular came from the Java world, and it shows.
- mr_crankypants 7y agoIt's unfair, but also pretty decent. For my part I've often wondered if design patterns being such a big deal in OOP is really a failing of the object oriented paradigm itself, or if it's just a reflection of how, ironically enough, popular object-oriented languages tend to be really, really bad at polymorphism. You're right, Smalltalk looms large here.
- 6thaccount2 7y agoYep...there are dynamic languages (Ex: APL and Common Lisp) where you can use OO primitives, but it usually isn't as encouraged if at all. I don't recall hearing much about proper design patterns in those languages. I'm not saying they don't exist, but it isn't a big deal. Smalltalk on the other hand forces you to do OO and I just read most of a book on the proper design patterns to use in it. It certainly isn't as bad as when I started to learn Java (it's almost a minor miracle to me that as much stuff gets built in Java as it does with all the straight-jacket boilerplate it has) but it is definitely there. Especially in the scripting arena (shorter programs of maybe a page or two) I find that nearly all OO scripts I see would generally be shorter and clearer as a few global data structures and some functions to operate on it.
- kazinator 7y agoOn the contrary, Common Lisp codebases nowadays are almost annoyingly replete with OOP.
- 6thaccount2 7y agoPaul Graham save us all ;)
- mr_crankypants 7y agoFunny you should mention global data structures. Last winter, when doing Advent of Code, it took me an embarrassingly long time to realize that I didn't really need to be writing super well-factored Clean Code™ with no globals or anything like that to solve these problems. And, when I stopped worrying about that stuff, my code ended up getting cleaner and easier to understand and debug. New hypothesis: Some practices make all the sense in the world in huge enterprise projects, and no sense at all in small utility projects.
- 6thaccount2 7y agoAgreed. The way I code would need to flip-flop if I was more involved with the writing of large software projects. Funny enough though. Those that I work with still write a lot of what I would call scripts, but they're super over architected and a lot of time is wasted and it is hard to read them. Sometimes simplicity is best as you observed.
- thom 7y agoYour critique of design patterns is driven by the exact same thing that causes people to copy inappropriate implementations from one language to another: you both believe design patterns have something to do with the technical means instead of the design choice. The strategy pattern has nothing to do worth first class functions. It has to do with designs in which you delegate a decision to the consumer of an API. The moment I start seeing the majority of projects in dynamic languages do that instead of passing around a massive bag of options in every API call, I’ll believe that these languages have grown out of the need for specific named components of software design.
- bcoates 7y agoDynamic languages don't generally favor using a function/class over a plain-old-struct, so there's no conceptual advantage to calling class GetNoCacheDefaultCookieJarStrategy { ... } fetch('https://google.com', new GetNoCacheDefaultCookieJarStrategy()) over const my_usual_fetch_opts = {...} fetch('https://google.com/', my_usual_fetch_opts) There are almost no uses of the strategy pattern that aren't equivalent to a trivial first-class function like a filter predicate or equivalent to a trivial plain-old-key-value-options-object, so the non-pattern version is stylistically preferred in the 99% case where it's not actually necessary.
- mr_crankypants 7y agoI submit that a filter predicate is an instance of the strategy pattern. The biggest difference between the two approaches is that one makes for a much less interesting UML diagram, so nobody ever really bothered to declare it a Design Pattern® and stick it in a long-winded book that we force college students to read. http://wiki.c2.com/?ClosuresAndObjectsAreEquivalent http://wiki.c2.com/?ClosuresAndObjectsAreEquivalent
- thom 7y agoOnce again, this completely fails to capture what is useful about the design decision to allow user supplied strategies. Literally this week I wanted to change the retry logic in an HTTP library but I’m out of luck because it’s just a bag of options, none of which do what I want. Whether it’s a function or an object is irrelevant. We’re taking about design decisions, not code.
- neilv 7y agoFWIW, the gang-of-four patterns book was a good idea. And still would've been, even if people were using crazy-powerful dynamic languages like Lisps instead of C++ (though the examples would've been very different, and then some would seem odd to include). One way to look at the patterns book is that it communicated a bunch of software architectural patterns that a developer might learn over many years of reading code others had written, and writing their own code. Suddenly, a new programmer could recognize and use those patterns immediately. Of course, at the time, it wasn't lost on the people who knew a bunch of OO analysis and design methodologies and programming languages, that there was heavy C++ bias to the exact patterns included. And we started to make comments like Norvig did here. But design patterns and the book were a good idea. Also, I was just a kid developer at the time, but, when the book first came out, I recall one of the principal engineers was looking into how patterns might be used for documenting large, well-engineered OO systems.
- erokar 7y agoThe point Norvig makes is that these patterns have emerged to mitigate shortcomings/lack of expressiveness in languages like e.g. C++ and Java. Expressive, dynamic languages lack these limitations and thus there simply is no need for most of these patterns.
- neilv 7y agoBut some of them (we won't speak of Singleton) are patterns that are helpful in conceiving of and understanding architectures or how the implementation language is used, even if an instance of the pattern looks like a very simple expression in the implementation language?
- senderista 7y agoThe GoF book is full of Smalltalk examples (in addition to C++). People who claim design patterns are irrelevant to dynamic languages have clearly never read the book. It would be more accurate to say that the patterns demonstrate the limitations of OO languages than static languages.
- xtracto 7y agoI kind of disagree. A kind of hidden point I loved about Norvig's presentation is that there are design patterns useful and proper for Dynamic languages. The main problem is trying to use design patterns created for static languages, in dynamic languages. I remember reading the Ruby book about design patterns. It was painful and the general motto of the book was "you don't need this and that static design pattern". However, I think as a community we should be defining a collection of design patterns that are useful in dynamic languages. At the end of the day, the main idea behind Design Patterns was the definition of higher-level logic constructs that could be used to solve a problem when developing software. It is like in the construction industry where bricks are the "code" and the 'best practices' (design patterns) of how to built houses with bricks do not apply when you are building a house using wood. Sure, brick design patterns do not work for wood, but that does not mean that wood building doesn't have their own patterns.
- AnimalMuppet 7y ago> Or as someone else once put it, "design patterns" might more accurately be called something like "palliative idioms for pain points in static manifestly typed class-oriented languages." But then one could claim that monads are a palliative idiom for pain points in function-oriented languages, with at least as much justification. Or one could think that we're bumping into some flavor of the expression problem: There is no language style that makes all things easy to write.
- msla 7y ago> But then one could claim that monads are a palliative idiom for pain points in function-oriented languages, with at least as much justification. Arrays are a monad. I think some monads can be described that way, but monads as a whole run into the "tensor trouble" of being so damned general that nothing can really be said about them... except for useless generalities.
- sampo 7y agoDesign Patterns could be general too, but usually we mean the common patterns. So you could equally talk about the commonly used monadic patterns.
- foobar_ 7y agoOOP is ideology masquerading as a paradigm. You can always pinpoint an ideology when people defend it blindly.