
SICP in Clojure - MattF
http://www.afronski.pl/sicp-in-clojure/2015/08/07/sicp-in-clojure-chapter-2.html
======
neoncontrails
I've been feeling the past few weeks the repeated impact of hitting a wall.
Programming was starting to feel like grinding. I felt wistful for SICP, when
programming was full of big ideas and elegant new approaches to problems my
unprincipled brain's first instinct was to clobber by brute force -- and
learned, quickly, in Scheme, it's _hard_ to be artless. It is, I think, harder
code gracelessly in Scheme than to code with grace: it has a way of bending
your ideas to a form. I think that's my main complaint with Python. In Python,
exactly the opposite is true: it doesn't force you to think overly hard about
the _way_ you solve problems, so you can solve more problems! Woohoo! You can
Code Like Coltrane, as Rich Hickey says.

For better or for worse. Here's an unfortunate side effect I've noticed: my
programs are vastly more complex and efficient than when I graduated from SICP
a year ago, which is good, and yet I can't remember the last time I wrote code
that was truly beautiful. Code I felt proud to call my code. Whose inner
workings I could explain to a child. To me, _efficient_ Python programs
conceal so much of how they work, that striving for craftsmanship can feel
alienating. It conceals so much. It's like a black box magic trick: in goes
the value... (pause) oh, and there's the answer! And the obvious what's
happening in between those two points, the less efficient my solution tends to
be. The prize winning solutions are often the most opaque, the most dense with
imported methods. And my programs look inevitably kind of haphazard and
provisional. Like doodles.

My Scheme programs, on the other hand, looked like Swiss clocks. They pleased
me. They wouldn't have worked any other way. They molded to the precise,
regimented form they had to be. I understood them. They were good.

I like functional programming. I think the wall I'm hitting might be Python.
The thought of a little Clojure or Haskell in my life right now sounds like a
beach vacation.

~~~
copsarebastards
I've been writing Python a lot coming from a Scheme/SICP background too, and
I've slowly come to a sort of solution to this problem that works for me.

Basically, what it comes down to is realizing that a lot of the libraries and
frameworks out there are smoke and mirrors: they provide an initial solution
to a common problem, but when you start getting into the details of _your_
problem, the problem _you_ are trying to solve, you end up working around
their crappy configuration points. In short, you stop coding and start
configuring existing code which is poorly designed to solve your problem.

So what I do is I stop using those libraries. I zealously guard my
dependencies, only letting in things that are solid, well-designed, mature,
and minimally invasive. I use minimalist frameworks, eschewing ORMs. Most of
the time I avoid classes, opting instead to use closures and namedtuples. The
result, my code is fast, flexible, easy to understand, easy to test. I
migrated around 30,000 lines of code from Python 2.7 to 3.4 in an afternoon--
my unit tests caught a few issues and once those were fixed I didn't see _any_
regressions in the following months.

I think the wall you're hitting isn't Python, it's the culture and libraries a
lot of people use for Python. But there are a lot of people who don't use
those things. Next time you think of reaching for pip or Django, stop
yourself: do you need that? Maybe it provides a short-term solution to your
problem, but in the long run it's neither a beautiful nor efficient way to
write code.

~~~
beatband
would love to see an example of your code style...github account?

~~~
copsarebastards
A lot of my thoughts on this subject were inspired by this Tweet:
[https://twitter.com/garybernhardt/status/616327747435036672](https://twitter.com/garybernhardt/status/616327747435036672)

Maybe check out Gary Bernhardt's code?

------
markc
There's also
[http://ecmendenhall.github.io/sicpclojure/pages/contents.htm...](http://ecmendenhall.github.io/sicpclojure/pages/contents.html)
which is an actual translation of the book into Clojure, currently up to
chapter 2.1.4.

And the ill-fated sicpinclojure.com site, which looked beautiful and had such
great promise, but mysteriously stalled and died.

Looks like vqc below has done quite a few of the exercises. Nice.

Tommy Hall's SICP Distilled seems like the best shot at a complete book now.
It's running a bit behind schedule but appears to be in the home stretch.
We'll see!

------
rjberry
Clojure seems too high level for SICP. Scheme was a perfect fit because of how
simple it is and how few language features or data structures it contained.
You had to build everything yourself, which was kind of the point.

------
bogomipz
This is awesome! I would love to see this span the whole SICP book.

There was a kickstarter campaign for something called SICP Distilled, a while
back. However it requires your github login which seemed kind of sketchy and
also none of the content works anyway -
[http://www.sicpdistilled.com/](http://www.sicpdistilled.com/). Maybe someone
else knows more?

Anyway I look forward to seeing more chapters on your blog.

------
lrc
I've spent a lot of time with SICP and with Clojure. The book changed my life,
and I too considered working on "porting" the book, but there would be a
considerable amount of friction. Clojure can do everything necesssary, but
it's very unidiomatic to build data structures out of pairs in Clojure, and
SICP spends a _lot_ of time implementing data structures with pairs. A
reconsideration of SICP for the modern age would, I think, take vectors and
maps and sets as given, and see what _additional_ magic could be built from
there!

Just start with sequences. Lazy sequences, which are so helpful in the expert
system database that's built in SICP, are already right there in Clojure
without the complications of force and delay. My thought is you could do a lot
more with the higher level examples, but a lot of the first half of the book
would have to be rethought. (The functional implementation of Conway's Life in
O'Reilly's "Clojure Programming" is as good as anything in the first third of
SICP, for example; the example of accelerating series convergence from SICP
seems less exciting today than it used to, at least to me.)

------
sbensu
To the author: on the compound data structures example, it would be much
better to return an anonymous function with `fn` than to use `defn`. `defn` is
meant to add global definitions to the namespace, not to be used as a value.

~~~
edem
This was confusing to me as well since in the Scheme examples they embed
functions into each other with define. It may be useful to use _letfn_ to
achieve something similar.

~~~
brudgers
Implementing _define_ in a way that allowed it to be used was one of Scheme's
innovations relative to some of the other Lisps in the 1970's. It's idiomatic
in part because it is easier for new programmers to read and Scheme
historically and _SICP_ perpetually are targeted at newer programmers.

Clojure most definitely is not. It's not an accident that Clojure's _fn_ is
only two characters. It's design as a language encourages anonymous functions.
Along with _recur_ there are many fewer cases where the simpler ways to do
something require a name.

The fundamental problem of trying to port _SICP_ to other languages is that
_SICP_ is not a book about programming in Scheme. It's a book about software
engineering, and the points about software engineering are made in ways that
can be readily illustrated in Scheme. _Cons_ is used to illustrate engineering
ideas, and while those ideas could be illustrated in Clojure, there's an
impedance mismatch between _cons_ and the roughly analogous constructs in
Clojure. Part of the baby gets thrown out with the bathwater for little
advantage...understanding Scheme probably makes someone a better Clojure
programmer, while the force fit of _SICP_ into Clojure probably won't.

------
ninjakeyboard
“I personally don't think SICP will help you much with Clojure. YMMV.”

—Rich Hickey, author, Clojure programming language

~~~
erikcw
My guess is that this is being taken out of context.

I don't want to put words in Rick's mouth, but I imagine that he means that
SICP won't help you learn Clojure the language. Not that SICP won't make you a
better programmer in Clojure (and all other languages).

Personally I found it helpful to work through the book in scheme (the language
used in the book), porting some of the exercises to Clojure and other
languages I'm interested in as a supplement.

------
rachbowyer
For those people in London (England) interested in SICP in Clojure, we are
running a monthly study group. Our google groups group is
[https://groups.google.com/forum/#!forum/sicp-
mailonline](https://groups.google.com/forum/#!forum/sicp-mailonline) and the
code is at [https://github.com/MailOnline/sicp-
mailonline](https://github.com/MailOnline/sicp-mailonline) (each person has
their own branch).

We are just starting Chapter 3 and at the current rate of progress it will be
at least a year before we have completed the entire book!

Anyone interested is welcome to join us :-)

------
ericmo
There was another person doing SICP in Clojure too, but it's been frozen in
chapter 2 for a couple of years now.
[https://github.com/ecmendenhall/sicpclojure](https://github.com/ecmendenhall/sicpclojure)

Hope this one gets to cover the whole book.

~~~
ericmo
Also really interesting:
[http://xuanji.appspot.com/isicp/](http://xuanji.appspot.com/isicp/)

------
vqc
This is exciting; I've been looking forward to doing this exact thing myself.

Some more solutions can be found at [https://github.com/gregsexton/SICP-
Clojure](https://github.com/gregsexton/SICP-Clojure)

------
provemewrong
The link to previos charpter in the blog post 404's (but I could navigate to
it through the sidebar). Anyway, I'm looking forward to reading them when I
get home and hope to see the following charpters as well.

~~~
afronski
I've changed yesterday the structure and I've messed up previous links - it
should be fine now. ;)

