
Rich Hickey: "Simple Made Easy" from Strange Loop 2011 [video] - puredanger
http://www.infoq.com/presentations/Simple-Made-Easy
======
jsmcgd
For me this was the best talk I've seen in a long while. It reminded me of how
I felt when I first read PG's essays, someone articulating your own suspicions
whilst going further and deeper and bringing you to a place of enlightenment
and clarity.

BTW for those of you who haven't watched it, this talk is not Clojure
specific.

~~~
jcromartie
However it's a great advertisement for Clojure, since the set of things he
highlights as _enabling_ simplicity is pretty much a subset of Clojure (or
included libraries, like core.logic).

I'd be interested in seeing someone present a different and convincing set of
concepts. At this point, I think Rich has put together a very good toolset.

~~~
brianm
Well, yes, IIRC he described one of his major goals with Clojure as enabling
simplicity, or something like that. That Clojure's design follows his views on
simplicity seems natural.

Non-Clojure examples would help make the point. He does bring up examples from
Haskell (such as type classes) in the talk in places, but doesn't dive deeply
into them.

~~~
loumf
SQL and Prolog were also cited, but yes, nothing very deep (which I think is
fine for this talk)

I would love to see the programs that are generated from this philosophy.

~~~
bitops
Your comment made me take heart if I understand it correctly. Sometimes I feel
I'm the only person out there who thinks SQL has a certain beauty and
elegance.

I find it a little funny sometimes to hear all these "web scale" folks put
down SQL, and then praise something like MongoDB because you can do
map/reduce.

I saw a presentation by the author of the Lift framework in Scala and he made
a bit of a joke saying "gosh...all this FP stuff...the folks who created SQL
heard about that a long time ago".

~~~
fogus

        the only person out there who thinks 
        SQL has a certain beauty and elegance
    

You're not alone. :-)

<http://news.ycombinator.com/item?id=1730320>

------
va_coder
Great presentation, but it got me thinking. Am I wasting my time trying to get
software just right? Is it worth my time to learn Clojure or Haskell, when I
don't even know what I'll use it for?

How many programmers do you know that are learning all kinds of languages and
technologies and methodologies and other things to improve the quality of the
software they write and yet will probably sit at a desk writing code for the
next 30 years? As opposed to starting a business, getting financial free, etc.

Take the guy from Duck Duck Go. He wrote all of that in Perl; talk about easy,
but not always so simple (to maintain). What if he spent his time learning
Lisp and Monads instead of writing an app that lots of people use?

~~~
jcromartie
To me, Clojure is about as productive as banging out a script in Ruby. It's
_way_ more productive than writing the same thing in any language where I
can't (easily, or at all) just fire up a REPL and start hacking.

I can actually just crank out code that I use. It can be quick and messy.
Clojure is not concerned with type theory and provable correctness.

But the end result of a quick hack, in Clojure, is often something (or is made
of of parts) that can be applied to other problems by pulling it out into a
library, or by abstracting one more argument to a function, etc..

I think someone like Gabriel Weinberg could get along just fine in Clojure,
with much the same spirit as hacking Perl, but maybe with better results.

~~~
swah
I kinda regret having chosen Clojure for my project. Its not that I can't
express ideas in very little code, its just that my workflow is different from
languages like Python.

In Clojure, it seems that I can't apply the method of spike solution
(<http://c2.com/cgi/wiki?SpikeSolution>) and then refactor it into working
code like I do with languages like Python or C.

~~~
seancorfield
I'm curious why you feel you can't create spike solutions in Clojure?

~~~
swah
Probably because pseudocode in my head is imperative.

~~~
mnemonicsloth
I think that's normal. Part of learning Clojure is learning to think in
another kind of pseudocode.

What does this imply about the languages you already know?

------
gregwebs
A good talk. Leave it to a lisper though to call testing and type-checking
"guardrail programming". Hickey says instead you should reason about your
programming without acknowledging that testing and type-checking are ways to
have executable documentation of your reasoning about your program. Testing
does in fact feedback into complexity - if something is hard to test it may be
due to complexity that you realize you should get rid of.

~~~
stuarthalloway
Difficulty of writing a test can certainly be a complexity indicator, but in
my experience the evidence is against testing having served this purpose very
well to date, at least for the kinds of complexity addressed in this talk.

If you look at around 31:27 in the talk, you will see ten complex things, with
proposed simple alternatives. If testing helped people feel the pain of
complexity and discover simple things, we would see projects where people had
problems writing tests, and switched strategies as a result.

Do you see people moving from the complexity column to the simplicity column
in any of these ten areas as a result of writing good tests? I don't. What I
see is people cheerfully enhancing testing tools to wrestle with the
complexity. Consider the cottage industry around testing tools: fixtures,
factories, testing lifecycle methods, mocks, stubs, matchers, code generators,
monkey patching, special test environments, natural language DSLs, etc. These
testing tools are valuable, but they would be a lot more valuable if they were
being applied against the essential complexity of problems, rather than the
incidental complexity of familiar tools.

~~~
amouat
Why do you consider code generators, monkey patching & DSLs to be "testing
tools"?

~~~
stuarthalloway
I don't. I refer here only to their use in that context.

~~~
amouat
I'm sorry; I think I'm being dense - what is their use in that context?

(I don't disagree with your main point, but I don't quite see where those
techniques fit in).

~~~
fogus
Some examples off the top of my head that use these techniques:

* code generators: Visual Studio, Eclipse

* monkey patching: RSpec

* natural language DSL: Cucumber

~~~
amouat
Thanks! Very good examples.

I can see how monkey patching could be useful in mocking or something similar.
I've never really used a language that supports it though.

I'm not entirely sure what Eclipse's code generation has to do with testing,
but given the other examples I'll assume I'm being stupid again ;) I'm
actually working with a lot of EMF generation stuff at the minute which can be
quite painful.

------
falava
You may also want to look at this other great video:

Stuart Halloway: "Simplicity Ain't Easy"

[http://blip.tv/clojure/stuart-halloway-simplicity-ain-t-
easy...](http://blip.tv/clojure/stuart-halloway-simplicity-ain-t-easy-4842694)

~~~
ExpiredLink
This kind of arrogance has no future.

------
spaznode
I can't add anything more to what @jsmcgd said but Rich's strange loop talk
really brightened my day and more importantly gave me the tools to express
what I sometimes try to share with other developers in the clearest way
possible. Thanks man, really awesome talk. Invaluable if more people could
start thinking this way. (which it sounds like oracle/java 7,8,.. will also
help to do whether they like it or not and that's also awesome for that
general clump of dev brethren)

------
neopanz
I feel smarter having watched this talk: it gives you tools to think about
thinking as you come up with new designs. Also love how Rich manages to find
the right metaphors to illustrate abstractions, he's a great communicator.

------
plinkplonk
The interesting thing about this talk is how Hickey's (very valid) distinction
between "easy/familiar" and "simple/unentangled" can be applied to argue _for_
powerful type systems like Haskell's or OCaml's. Likewise with the "benefits
vs tradeoffs" argument.

~~~
shoover
Likewise, some points in the talk brought to mind the OO SOLID principles.
It's unfortunate that much of the discussion I saw on HN and twitter after
this talk was argument about the value and purpose of testing. More useful
would be examining the point of the talk and considering any common ground
between Rich's "Simplicity Toolkit" and where things stand now with languages
that aren't Clojure.

Take your language of choice. If you're not in a Lisp already, you can't do
much about syntax vs. data, but what about the rest? Is it easy to work
generically with data and values instead of making custom classes and mutable
objects for every piece of data? Is it possible? Can we make it better? Are
there persistent collections or managed refs available? Can we write them as
libraries? Within the language's polymorphism construct, can we extend a type
we don't control to our abstractions without creating adapters and more
complexity around value and identity? What about transactions?

------
ironchef
Ugh. Why don't they release the presos as opposed to having to deal with
synchronous video?

~~~
jhickner
If you mean just the slides, most of them are in this github repo:
<https://github.com/strangeloop/2011-slides>

~~~
abscondment
For some reason, these slides are only available in a flash widget that's
synchronized with the video. Here's a little script to grab the flash and
build a PDF for yourself.

ImageMagick and swftools required.

    
    
      #!/bin/bash
      for s in {1..39}; do wget http://www.infoq.com/resource/presentations/Simple-Made-Easy/en/slides/$s.swf; done
      for swf in *.swf; do swfrender $swf -o $swf.png && rm $swf; done
      convert `ls *.png -x1 | sort -n | xargs echo` slides.pdf
      rm -f *.swf.png
    

[Edit: required packages]

~~~
markokocic
I agree with "teach a man to fish ...", but you know, some people are far away
from the sea (linux) so just providing them with the fish (pdf) is also a good
option.

~~~
malkia
This is in no way Linux specific - most likely OSX can do it, and with enough
time cygwin too. Probably BSD's and others...

------
agentultra
Great talk.

Simplicity is, of course, key; but a few of his applications of these
principles are misguided IMO.

Ex: The "Parens are hard!!" slide. He suggests that parens are "overloaded" in
CL/Scheme because they are used to wrap functions, data, and structures all
the same. However he completely misses the fact that by representing
everything with parens, CL/Scheme remove a lot of complexity in software
written in those languages.

AFAIK, the only languages that do macros right are homoiconic. Anything else
is too complicated. Just look at Perl 6 and Haskell macros. They require
learning special syntax and really crazy semantics. Using them will probably
just make your program more difficult to understand.

He also "rails" against testing. He misses the virtues of a proper testing
infrastructure in producing reliable software: if you don't test it, how do
you know if it works? Because you reasoned about it? How do you know you're
reasoning is correct?

True, "guard rail" testing isn't a crutch that will automatically produce
reliable software. But I think Rich relies too much on this narrow view of
testing to make his point. Testing is good and necessary.

And the jab to the Unix philosophy? ( _"Let's write parsers!"_ ). Isn't that
what we do on the web anyway? AFAIK, HTTP is still a text-based protocol. Any
server that speaks the protocol has to parse a string at some point. So what
was he getting at there? The Unix philosophy is about simplicity and has a lot
to offer in terms of how one can design software to be simple.

Overall though, it's a great talk. I just think that if he wants to get
pedantic then he could be a little more thorough and less opinionated.
Everything he said about designing simple systems I pretty much agree with,
but I think he glosses over some finer points with his own bias of what
simplicity means.

~~~
chousuke
Clojure is homoiconic just as much as CL and Scheme are. It just happens to
use more than one datastructure to represent code.

The "oneness" in other lisps does not make things simpler, nor, in my opinion,
easier. The reason why parens (lists) in traditional lisps are not simple is
that they _complect_ several different purposes. In contrast Clojure uses list
forms (almost) exclusively for "active" expressions such as function and macro
calls. For grouping and binding, vectors (and sometimes maps) are used
instead.

In this manner Clojure manages to keep the roles of different data structures
in code mostly simple.

~~~
gruseom
_The reason why parens (lists) in traditional lisps are not simple is that
they complect several different purposes._

You've repeated what Hickey says in the talk, but I'm not sure I buy it.
[Deleted boring stuff about boring parens here.]

The trouble with the general argument is that you can add constructs that are
individually simpler but nevertheless make a system more complex. It's overall
complexity that we should seek to minimize.

~~~
chousuke
How does adding several independent simple things make systems more complex in
a way that is unavoidable (ie. incidental complexity, not problem complexity)?
The interaction between simple elements will be explicit, whereas complex
elements by definition interact in ways that you can't control.

Of course, sometimes the complex tool might be exactly what you need to solve
your problem, making things easier. But in cases where you need only a part of
the functionality of this tool, the complexity bites you as all the unneeded
functionality (along its cost) is forced on you.

What sort of "overall complexity" does having several data structures in code
introduce? As Rich Hickey says in his talk, complexity is not about
cardinality.

In Clojure's model, the elements are distinct, and as such there is more
simplicity in the system than in lisps where you have to understand the
difference ("untangle" the complexity) between several different uses of lists
to get anywhere.

I also think having several datastructures makes code easier to read due to
the visual differences, but that's a separate discussion. :)

~~~
gruseom
Adding things means more things, which means more complexity. Doing so is a
net win only if the new things subtract more complexity than they add. To
figure out whether they do, you have to consider the system as a whole. That
much is clear. Do we know how to do that? Not really. Empirical studies favor
the simplest measurement of program complexity: code size. So that part is
roughly taken care of. But I don't know of a good definition of "system". What
counts as a single system and what counts as separate interacting systems, or
subsystems? It's in the eye of the beholder. If I take 90% of a program and
call it a library, has my program become 1/10 as complex?

Rich says his definition of simplicity is objective, but it's not. What
determines whether a construct has a single purpose? It's whether or not, on
inspection, you think it does. S-expressions seem to me to have a single
purpose: to group things. How those groups of things are treated by the
evaluator is a separate concern. You, following Rich, say no, they have 3
purposes. Ok. Why not 4? A function call and a macro call have different
purposes; why conflate those? (I have no trouble reading function calls in
s-expressions, but sometimes run into trouble not knowing that they are really
macro calls, so this is not a made-up point.)

We have no objective basis for this type of discussion, only emotions and
beliefs. Concepts like "readability" are hopelessly relative, but appeals to
"ease of future change" are no better; to put it politely, they depend on
individual perspective and experience; to put it bluntly, we imagine them.

~~~
chousuke
I don't agree with your assessment that adding things necessarily increases
complexity. Assuming these things are simple (in the objective sense as
defined by Rich), actually suitable for the problem, and used correctly, then
any complexity arising from their use is _necessary_ to solve the problem, and
can't be avoided.

The definition of a system in this case is anything with one or more
components that accomplishes a particular purpose.

It still seems you're using a different definition of complexity than I am. To
me, complexity implies unnecessarily intertwined elements.

In your hypothetical library situation, the answer is likely no. Your program
still depends on the "library" code in ways that make the two not treatable as
standalone entities, so no complexity has been removed.

An inherently complex tool may solve the specific problem it's built for, but
it does not combine well with other tools. A simple tool tries to keep itself
standalone so that can be freely combined with other simple tools to provide
functionality that the original authors of either tool might not have
envisioned. Clojure has many examples of this idea in action, but it's not the
only language to exhibit simplicity.

I think Rich's definition of simple is straightforward and objective. For
example, Clojure protocols fit the definition. They give you freely extensible
polymorphism based on object types. Protocols don't even provide a direct way
to do inheritance. That can be done by using a map of functions that you
modify as needed, but requires no explicit support.

Your defense of s-expressions is rather puzzling. The evaluator defines what
s-expressions (lists) mean in CL, and depending on context, there are multiple
meanings that are completely separate. Certainly you can argue that Clojure
conflates macro and function calls too (it is justified to me though, since
they're all operators), but it has at least reduced complexity by not
conflating binding and grouping with those elements.

As an added benefit, with few exceptions, whenever you see a list form in
Clojure you can assume it's either a function call or a macro of some sort.

------
vseloved
Rich is a good philosopher. Although it's often hard to strictly follow your
own principles in your real-life work - and Clojure shows that often ;)

------
typicalrunt
Slightly OT: What's the name of the template used in his presentation? It's
beautiful and has a nice contrast of colours.

~~~
puredanger
That's a stock Keynote theme called Industrial.

------
nebaneba
At 55:20 he says, if you have A calling B all the time, you should "Stick a
queue in there."

What is an example of this?

~~~
chousuke
I suppose he means that instead of A calling B directly, A should put work in
a queue and B should consume from it, thus decoupling the two entities.

------
Sikul
Can anyone explain how pattern matching causes complexity?

~~~
mnicky
see
[http://www.reddit.com/r/programming/comments/lirke/simple_ma...](http://www.reddit.com/r/programming/comments/lirke/simple_made_easy_by_rich_hickey_video/c2t7a9f)

------
ShardPhoenix
Good talk - reminds me of Yegge's recent rant about the Service Oriented
Architecture, but coming from another angle (internal use vs. external).

------
malkia
I wonder what would Rich think of automake, autoconf and cousins? is it
simple, is it easy, or simply esoteric?

It confuses the hell out of me :)

