It's very common for people to repeat that claim that Peter Norvig gave in that presentation that design patterns are work arounds for language shortcoming. This is only true for some patterns. MVC, Facade, Composite and others are obviously applicable in most paradigms. Moreover, some patterns are obviated by library improvements, such as Singleton.<p>The truth is that modern OOP (even in Java) doesn't many of the patterns in the GoF book any longer. That's not much of a surprise though: GoF is 18 years old. Approaches to problems have changed and the patterns used are a bit different.<p>Idiomatic Haskell is full of design patterns. Here's a few of the popular ones: monads, composition (of functions, not objects), maybe. When I stopped use Haskell actively, they were just getting a handle on the overuse of monads. Pattern overuse had occurred, just as in Java. It seems that pattern popularity follows the Hype Cycle (<a href="http://en.wikipedia.org/wiki/Hype_cycle" rel="nofollow">http://en.wikipedia.org/wiki/Hype_cycle</a>)
GOF patterns are indeed language agnostic, as long as you work within the OO paradigm.<p>You can indeed apply the same pattern (fe visitor) in Python, Java, C++, Go. This is also the reason why it isn't that difficult to move from one OO language to another.<p>Functional programming languages fall within another paradigm. You do have patterns like 'fold', 'map', or 'nexus' but in general, they tend to be very small. This is because functions allow both more strict and more flexible composition than objects. Again, once you know Lisp, or Scheme or ML you can jump from one language to another, although from Scheme to Haskell will be a larger jump (purity & laziness) than from Scheme to Erlang.<p>Two final remarks:
<i>) The declarative paradigm (Prolog, Mercury, ...) seems to be out of flavour these days.<p></i>) Every self respecting developer should have mastered at least 1 language in every paradigm.
I have some objections.<p>If monads are design patterns, then why not rings (Num typeclass), which allow to use addition and multiplication in different contexts? If function composition is a design pattern, then why not function application? If chaining with '>>=' is a design pattern, then is using a semicolon a pattern too? If 'fold', 'map' are patterns, then why not 'sin' and 'cos' are? What is the difference? There's a "pattern" that after sine you put a number; there is also a "pattern" that after a fold you put a function. Thinking that higher-order functions are special is contrary to the spirit of functional programming. Functions and numbers are the same class of citizens, and a function taking a function should not be treated differently from one that takes a number.<p>Bare names of often-used library functions or language constructs should not be considered patterns, unless they occur as parts of repeating snippets. In this case, you should refactor or encapulate. If you cannot, this is a language flaw. It sucks if you have to type "x = new T(); try { ... } finally { delete x; }" each time. If your language allows to write "using (x = new T()) { ... }" then the pattern is eliminated.<p>Perhaps there are some "design patterns" in FP, but examples I find often are very weak. One thing that I would count as a pattern is "lift . lift . lift" used in Haskell in monad transformers.
<a href="http://norvig.com/design-patterns/" rel="nofollow">http://norvig.com/design-patterns/</a><p>The short answer is - no Java - no problem.)<p>The longer answer is:<p><i>Any sufficiently complicated C or Fortran program contains an ad-hoc, informally-specified, bug-ridden, slow implementation of half of CommonLisp.</i><p><a href="http://c2.com/cgi/wiki?GreenspunsTenthRuleOfProgramming" rel="nofollow">http://c2.com/cgi/wiki?GreenspunsTenthRuleOfProgramming</a>
There's definitely a few design patterns that aren't applicable in functional languages.<p>For example, the Visitor pattern can be naturally replaced with map and fmap in Haskell, which are far more powerful.
As John Carmack said on twitter the other day:<p>"Finally reading Design Patterns. The cross platform WYSIWYG editor used as an example doesn't "smell" like something actually implemented."<p><a href="https://twitter.com/ID_AA_Carmack/status/257683318907215873" rel="nofollow">https://twitter.com/ID_AA_Carmack/status/257683318907215873</a><p>I had the same impression. How to trust the authors with such unbelievable example.
For a hot minute this post was right above this post.<p><a href="http://doctrina.org/Javascript-Function-Invocation-Patterns.html" rel="nofollow">http://doctrina.org/Javascript-Function-Invocation-Patterns....</a><p>Had to giggle a little over this silly discussion of FP and are there design patterns or not. A strategy is the same intent whether you use a enclosed function or an anonymous object as the strategy. Remember the old computer programmer adage. Objects are the poor man's closure, and closures are the poor man objects.
<i>But you may have run across monads. What are they, if not a design pattern for "dealing with global state"?</i><p>This to me belies that the author doesn't actually do much programming with monads. They're more like the core abstraction of an interpreter or a sequencing algebra than a design pattern for global state.<p>Considering functions s -> (a, s) as "global state" is closer to a "design pattern", though.
I pretty often find myself "functionalizing" design patterns in in Java to split out the verbose part from the part that is interesting.<p>For instance, say you have a Log object that has 15 or so Log methods for different severity levels and signatures and you just want to write something that prepends something to anything that gets logged.<p>If you split this to "something that applies a function to any message passed to the log" and "a function that transforms a message" you get something that's certainly better if you implement more than one transform and probably better in the case of just one because the repetitive boilerplate is physically separated from the "business end".