I like Clojure quite a bit more than Java, but some of these are unfair if you are comparing against modern Java.<p>For instance, the sorting example can be simplified:<p><pre><code> Comparator<User> userOrdering = Comparator.comparing(User::isSubscription).thenComparing(User::getName);
// forward sort
Collections.sort(users, userOrdering);
// reverse sort
Collections.sort(users, userOrdering.reversed());
</code></pre>
A lot less verbose than it's made out to be.
Brilliant-- this is among the best design pattern writeups I've ever seen, and will greatly help developers who are coming to Clojure.<p>This would be excellent for expanding to book-length guide to help people learn functional programming along with the patterns. Thank you Misha for writing this!
Peter Norvig covered this two decades ago: <a href="http://norvig.com/design-patterns/design-patterns.pdf" rel="nofollow">http://norvig.com/design-patterns/design-patterns.pdf</a><p>Paul Graham mentioned Norvig's work in 2002: <a href="http://www.paulgraham.com/icad.html" rel="nofollow">http://www.paulgraham.com/icad.html</a>
I love the idea! A few examples are a bit strawmanish but really when you're comparing languages like that who can resist the strawman.<p>The Clojure solutions do sacrifice a lot of safety though, due to dynamic typing (e.g. the visitor pattern, which relies on basically strings to do its dispatching).
I'll just plug my own (not as comprehensive) contribution to this meme: <a href="http://www.colourcoding.net/blog/archive/2014/10/27/design-patterns-happy-birthday-and-goodbye.aspx" rel="nofollow">http://www.colourcoding.net/blog/archive/2014/10/27/design-p...</a>
Really nice writeup of patterns. What turned me off Clojure is that the dynamic typing makes it very hard to refactor. e.g. even renaming a function is really quite difficult, let alone adding function parameters. Forget extracting a function. The dynamic typing also means a typo can yield a nil that travels far from the mistake site making debugging difficult. There are hints towards better debugging in clojure, but last time I checked it was still very much a work in progress. Also lazy lists are easy to screw up, e.g. if you put a concat inside a reduce then stack go boom.<p>Still this is a great post because it teaches you both good Clojure and the design patterns. Since java has closures now you can take a lot of what you learn from Clojure and put it in your well typed and refactorable Java programs.
Whilst I agree in general with the sentiment, it really doesn't help if you start with a misunderstanding of the command pattern. The essential property of command is that it's data that can be executed. Implicitly, it's possible to do other things with them: log them, undo them and so on. A better model would be a record that implements IFn.
I think the Visitor example is a mistake. Couldn't you replicate the Clojure version in Java by having a "Formatter" singleton that has a function for each of the different item type/format type combinations?
Excellent, definitely going to read this. I would like to see this for Haskell, though. And some Lisp idioms (from On Lisp, for example) could be thrown in for a good measure, too.