
"Design Patterns are the disease, Clojure is the cure..." - swannodette
http://blog.thinkrelevance.com/2009/10/19/the-case-for-clojure
======
alrex021
Design Patterns may be the "disease", but Clojure has nothing really to do
with this, "the cure". Lisp has been the cure before the term Design Patterns
even came into the CS vocabulary.

~~~
gord
The move from mainstream OO, cast in a mediocre language like C++ or Java, to
having some way to talk about higher level combinations [which the language
cannot express] is quite an improvement.

After a positive experience with GoF patterns its hard to convince people that
these patterns are just a natural part of working in lisp [or clojure] : Not
only can you talk in patterns, but your code can be written in patterns in a
direct way.

The same of UML and other formal diagramming systems - you get more expressive
power much more directly via a 'domain specific language' in lisp. All the big
fads are subsumed with a wave of the hand.

Unfortunately some universities take what they think is a pragmatic path of
least resistance and teach popular languages such as Java in place of a much
more subtle and powerful language.

I wonder at the sheer human waste in leagues of emasculated coders churning
out verbose Java/XML/SQL 'business' apps in cubicles, forced by convention to
work in an ugly way - those businesses would be much better served in terms of
efficiency, quality and innovation by using a good language, and their staff
much happier.

Thank Gods and the lords of Kobol for giving us Python, Ruby and Clojure that
they might seep through the cracks and weaken the stranglehold of obfuscation
and verbosity!

~~~
Confusion
_Not only can you talk in patterns, but your code can be written in patterns
in a direct way._

I have never bought this argument. What does it even mean? In every language,
an implementation of a design pattern can be clearly distinguished as such.
This is a good thing: it allows you to easily describe parts of of your
application. This part produces objects, that part provides an interface to a
bunch of other code, the other part determines which algorithm should
currently be used, etc.

~~~
gord
Sure, it is a matter of degree - we could ask, how much extra crud is needed?
I think lisp like languages have less crud, and so the idea is clearer.

This is partly because lisps can act on their own expressions, transform them.
This follows from extremely uniform or consistent grammar.

Now you could say C++ can do that, but look at the amount of machinery needed
in Boost to add something like a lambda or an accumulator 'pattern' to the
language.

Its a matter of degree - sure you can write a DSL in C++ [recursive descent,
lex/yac, boost, macros etc] but in lisp this really is just a natural part of
the language - syntactic sugar can be manufactured.

Lets take the idea of a callback - this is an excellent design pattern that
gives you a great deal of power. You could implement using function pointers
in C, or say functor objects with operator() in C++... either way, I contend
there is a lot more crud and boilerplate than there is in lisp where a lambda
is a fundamental construct of the language.

The more surrounding crud or machinery, the less clear the concept.

In other words, patterns in lisp can be _more_ clearly distinguished as such,
because there is less cruft.

Often the name of the concept or pattern actually occurs in the code as a
function name, for example.

~~~
axod
>> "I think lisp like languages have less crud, and so the idea is clearer."

Part of being a good programmer is being able to see through crud. Personally,
I don't really care about crud. It doesn't bother me. I think it's a good
skill to learn to be able to recognize and understand code that's within a
bowl of crud.

~~~
asciilifeform
> I don't really care about crud. It doesn't bother me.

Then you won't mind when a garbage truck unloads its multi-ton cargo into your
home.

~~~
axod
I don't equate crud with garbage. Crud is stuff you ignore after a while.

------
vsync
Posted this on the article's comments:

I have been following Clojure with some interest lately. I'm still a Common
Lisp guy though because Clojure is still in flux and evolving rapidly from
what I see.

I also see the fact that all Clojure programs are Java programs as a plus and
a minus: a plus because you get access to all the Java libraries and JITs and
whatnot out there, but a minus because there can't be any independent Clojure
port. In the real world to make an interesting port of Clojure you will also
have to port all of Java so applications work. It's like if no one wrote
Unix/Linux applications but only Windows and counted on Wine always being
there.

With regard to state -- and Paul Barry already touched on this -- I recently
started implementing a small app which needs some persistent state. I thought
to try doing it in Clojure but found out that while Common Lisp has tools like
Rucksack and Elephant and CLSQL, if I wanted it in Clojure I would need first
to create all my data structures as Java objects (albeit with (. blahblah)
wrappers if I wanted) then run them through some clumsy Java ORM, or deal with
raw JDBC or Java Berkeley DB.

If I missed something that's already out there and available I would love to
be pointed to it, but it seems to me Clojure could benefit from a native
persistence mechanism or library that takes advantage of its concurrency
strengths, or at least a native API for something like Berkeley DB that can
deal well with it.

~~~
ericlavigne
There is a Berkeley DB wrapper for Clojure. I haven't tried it yet, but it
looks like the nicest Clojure persistence library I've seen so far.

<http://github.com/gcv/cupboard>

------
crucini
Like most language advocacy, this piece implicitly compares the beloved
language to one other. In this case, Java.

"Java sucks, so use language X!". Problem is, this argument works for many
values of X.

I think the elevator pitch for Clojure is more like: "Java libraries without
Java verbosity". Or: "Lisp finally meets the real world".

(I've played with Clojure, and found a startling contrast in seeing Java
objects inside such a friendly, dynamic environment.)

~~~
jrockway
My elevator pitch is, "A slow lisp without a real object system."

~~~
swannodette
Slow compared to what? Most benchmarks I've seen show that it easily beats
most of the other popular dynamic languages if you care about that. In my own
experience with macro hackery you can often get very close to Java (2x-3x).

The lack of an object system is a downright feature since it forces you to
take a functional approach. Most of the things you would want from an object
system (polymorphism, multiple inheritance) are readily available via
multimethods/hierarchies.

If you really want something CLOS-like, there's a library for that,
<http://code.google.com/p/explorersguild/wiki/XGModelAndGF>.

~~~
jrockway
_forces you to take a functional approach_

I don't think Clojure is really a functional langauge, it's more of an
imperitive/OO mix with immutable objects. Immutable objects aren't "functional
programming", they're simply common sense.

Functional programming is about composing parts of programs ("functions") with
generic combinators. I have not seen anyone in Clojure doing this. Haskell is
a different story; combinators are very reusable, and there is no way to
combine functions (and other "categories") without them. (In Clojure, you
combine program fragments by typing a closing paren and then opening a new
one. Your program doesn't control its sequence of operations, a Magical
Runtime does that for you. Inflexible.)

The reusability in Haskell is quite interesting; for example, application in a
monad is defined as "liftM2 ($)", the usual function application operator
("($)", itself a function of two arguments) lifted into a monadic context for
functions of two arguments. Cool.

The reusability is everywhere; you use the same Arrow combinators to traverse
an XML document as you do to parse plain text. (See HXT and PArrows.) And of
course, you compose Arrows with (.) (the function composition function),
because (.) works on all Categories, not just functions.

That is functional programming; Clojure is just immutable data and parens.
(Both good ideas, mind you. But it's not doing anything that Pure Java can't.)

~~~
weavejester
Your definition of "functional programming" is unusual. Wikipedia defines it
as:

"A programming paradigm that treats computation as the evaluation of
mathematical functions and avoids state and mutable data"

Wikipedia goes on to consider Erlang and Scheme functional programming
languages, so it would seem your definition of what consists a functional
programming language is more narrow than the norm. Most people would consider
Clojure to be a functional programming language, just not a _pure_ functional
programming language.

I'm also not sure why you describe a language with macros as being
"Inflexible". I've used Clojure and Haskell extensively, and Clojure wins on
flexibility. It's a dynamically-typed Lisp, after all.

~~~
jrockway
I think I am agreeing with Wikipedia's definition. What function is evaluated
that makes "foo" execute before "bar" in "(foo) (bar)"?

 _Wikipedia goes on to consider Erlang and Scheme functional programming
languages_

Yeah, people have diluted the term to near meaninglessness.

~~~
weavejester
Generally, in Clojure you'd write (do (foo) (bar)). The do form tells Clojure
to evaluate its arguments in order. Some forms have an implicit do, e.g. (when
x y z) is (if x (do x y)), but in general the order in which forms are
evaluated depends on the form containing them.

------
xtho
A pointless self-promotion that lacks any arguments and explanations etc.
Catchy title though.

------
joe_the_user
It would have been nice if the link named "sample code" linked, to, uh, code
rather than a git hub node that one might extract some code from, in maybe
fifteen minutes.

All the other links seemed to be announcements for the guy speaking and
article itself had no real _meat_. Show me some code does something hard
easily and something easy, easily. And _don't make have it be factorial, I
know functional programming can do factorial_.

~~~
gord
I put my hand on my heart and tell you, after programming for 15 years in C
and C++ on windows and linux, I am happy to throw it away after seeing how
much better the same things can be done in 'lispy' languages [scheme, clojure,
ruby]

Have a look at PGs 'on-lisp', 'the little schemer', the SICP book + video
lectures, or 'practical common lisp' - they have example after example -
finding fixed points, data query language, numerical approximations, symbolic
algebra, pattern matching, logic languages, momoizing all expressed very
clearly.

An excellent article you might enjoy is 'Functional Programming for the Rest
of Us' : <http://www.defmacro.org/ramblings/fp.html> [by a YC alumni, Slava]

------
brown9-2
Can anyone link me to (or provide themselves) a comparison of Clojure to
Groovy?

I might regret admitting it but functional/dynamic programming is new to me,
but I'd love to learn more about it. Groovy and Clojure sound pretty similar
to me, minus the Lisp part, so I'm curious what some of the other major
differences are.

~~~
holygoat
[http://stackoverflow.com/questions/1314732/scala-vs-
groovy-v...](http://stackoverflow.com/questions/1314732/scala-vs-groovy-vs-
clojure)

From what I've read, Groovy is monstrously slow. That alone should rule it
out.

~~~
regularfry
You'd think it would rule Ruby out as well, but no...

------
jister
Everything has its place in software development, may it be closure or design
patterns.

