
Why I am excited about Clojure - txus
http://blog.txus.io/2014/05/why-i-am-excited-about-clojure/
======
undershirt
I'm more excited about ClojureScript because it runs in the browser as JS, of
course. My mind is kind of blown that Go-routines were added to the language
as a library (core.async). And so was logic programming (core.logic), optional
typing (core.typed), and pattern matching (core.match).

~~~
astine
That's the neat thing about Lisp-style macros. You have to sacrifice a little
bit of the syntactical sugar that you are used to in most languages, but in
return you have the ability to add almost any possible construct to the
language natively. It makes it much easier to extend the language as you don't
need to hack an interpreter written in C or Java. Half of the core language is
already written in macros.

~~~
seacious
Not having to memorize an operator precedence table makes me more than willing
to give up syntactic sugar. This is one of the things that I dislike most
about haskell. I wish liskell or one of the other projects trying to bring
S-expressions to haskell had taken off.

~~~
dominotw
>Not having to memorize an operator precedence table makes me more than
willing to give up syntactic sugar.

Really? This is such a big problem that you have to choose a completely
different language.

~~~
seacious
Knowing what the AST looks like without having to sit an think about it is
huge. Maybe you're smarter than me and can instantly intuit it, but I think
most people can't. I think that this is one of the reasons that macros are so
widely adopted in LISPs but not in other languages that support them. Having
an immediately evident AST makes it much easier to reason about, and hence to
manipulate either through code or manually.

Edit: Improve clarity.

------
lectrick
I am a Ruby guy torn between diving into Haskell or Clojure. Help! Every time
I get excited about one feature of one (ClojureScript) I learn the other has
something equivalent or potentially better (Haste).

One thing that has put me off on Clojure is 1) the ugly as hell JVM
stacktraces, 2) hitting the wall of the number system results in nasty JVM
errors if you are used to Ruby's trivial (to the developer at least) handling
of numbers of any size, 3) the time it takes to fire up the JVM itself (I like
really fast really instant unit tests)

On the other hand, what has put me off on Haskell is that 1) all its users
seem like mathematics professors, 2) a lot of its libraries will fail to
compile when combined with each other without a lot of hand-holding and
carefulness

~~~
scott_s
General advice: don't let the desire to learn the "right" thing prevent you
from learning, period. Eventually, it's better to just make a choice and dive
in, then to spend more time trying to figure out which one is "better".

~~~
JackMorgan
Absolutely learn both! Make sure you learn macros well (I suggest Let Over
Lambda) and Haskell's powerful type system. I know Clojure and macros pretty
well, but learning Haskell the last couple months has been incredible. And
then learn Forth, J, Prolog, do SICP in Scheme, etc. ;)

------
john2x
I'm a Python user and I _love_ Clojure. I guess I missed the Go bus. But
there's 2 things about it I'm not too fond of.

One is due to it's declarative nature (which I love), it's quite difficult to
get up to speed with unfamiliar code.

The 2nd is due to it's JVM roots. Those stacktraces, man. And when it happens
on an anonymous funtion in a not so documented library, ugh. It's like hitting
a brick wall.

The first, I can deal with enough practice and Schema/core.typed. Is there any
hope for the stacktraces to improve? How do other JVM based languages fare in
this regard?

~~~
calibraxis
Oddly enough I never used this, but maybe named fns might help?
([http://clojure.org/special_forms#Special%20Forms--%28fn%20na...](http://clojure.org/special_forms#Special%20Forms--%28fn%20name?%20%28\[params*%20\]%20exprs*%29+%29))

    
    
        (fn my-name []
          (throw (Exception. "boom")))
    

(Sorry, I don't know Clojure internals well enough to have great answers to
your explicit questions.)

 _[Edited: thanks to jerf for pointing out the inconsistency in a term I
used.]_

~~~
jerf
Named... anonymous... functions? Wuzzah fuzzah?

~~~
weavejester
They allow you to use recursion without the need for a Y-combinator.

------
astine
That last feature is certainly one of my favorite parts about Clojure. It's
one of my favorite parts about Lisps in general actually, but Clojure has a
very good handle on it. Having to compile a program before seeing if the
changes you made work can be a nuisance. Interpreted programs are slightly
better, but being able to make micro-changes to a running instance of a
program and seeing in real-time how it affects the whole program is the best.
The feature that Clojure misses here is the ability to load new libraries (jar
files) on the fly, but that's not Clojure's fault, but rather the JVM's fault.

~~~
Zak
What I find really surprising is that other languages that have pretty decent
REPL support have not embraced it so fully as Lisps have. Connecting to the
live[0] instance a Rails or Django app, examining its internal state and
making updates that don't involve more or less restarting the app is unusual
at best.

Ruby and Python borrow a lot from Lisp, including the REPL, but some of the
most popular applications of those languages barely take advantage of it. Why?

[0] I'll stipulate that you might want to be very conservative about doing
this with a production system.

~~~
astine
_I 'll stipulate that you might want to be very conservative about doing this
with a production system._

No kidding. I knew at least one guy who hosed a product launch by doing that.
You even have to restart your development instance from time to time to make
sure that your application state remains consistent. I've been scared to try,
but I suspect that you could live-patch a server though if you were systematic
about it and tested the patch ahead of time.

~~~
Zak
_You even have to restart your development instance from time to time to make
sure that your application state remains consistent._

There are ways around that. Stuart Sierra uses a scheme wherein the entire
application is treated as a value, which can be re-generated on the fly. Of
course, that's not terribly different in practice from restarting the whole
environment, but it's faster and more convenient.

[http://thinkrelevance.com/blog/2013/06/04/clojure-
workflow-r...](http://thinkrelevance.com/blog/2013/06/04/clojure-workflow-
reloaded)

------
dopamean
What is it about Clojure that Rubyists love? I am a Rubyist who is new to
Clojure (I love it) and I cant explain it myself. Clojure was suggested to me
by several other Rubyists. I find myself suggesting it to other Rubyists as
well....

~~~
krat0sprakhar
I'll go out on a limb and say that everyone on HN loves Clojure! It seems to
be the least cribbed language here. Its features are hard to beat - that and
Rich Hickey's wonderful talks[0] make you all the more confident in Clojure as
a language!

[0] - [http://www.infoq.com/author/Rich-
Hickey](http://www.infoq.com/author/Rich-Hickey)

~~~
jacquesm
In a community of several 10's of thousands of people saying 'everyone' is
always wrong.

To love clojure you'd have to first become proficient in it and I highly doubt
even double digits of HN would claim to be proficient, much less to love the
language.

In general, you speak for yourself and yourself alone and my take from your
comment is that you love clojure.

I have played around with it but not enough to be able to say that I love it,
even though I would like to spend more time with it.

I'm sure that when the honeymoon phase is over clojure will be yet another
useful tool in the toolbox. I can't recall a single language that I truly
love, they all have their specific warts and I expect clojure to be no
different in that respect.

Just a different set of limitations to applicability.

~~~
astine
_To love clojure you 'd have to first become proficient in it..._

I do not think that the GP was using 'love' in that sense. You can 'geek out'
about news and information about something without actually being much
involved in that something at all. Witness the popularity of posts about space
launches on HN. I doubt that there are very many actual rocket scientists, but
we sure do have a lot of people interested in progress made in space.

~~~
jacquesm
Love for space travel and love for a programming language are two different
things entirely, the one is an adventure on an almost trans human scale the
other is a way to tell a computer what to do.

------
pk2200
I'd like to learn Clojure. Any suggestions on how to get started? It's my
first time using a Lisp dialect. I figured I'd tackle the Clojure Koans, and
mix in a few Project Euler problems.

I'd also like to do some code reading. I know the Clojure source code is on
GitHub, but maybe something smaller to start?

If anyone else is interested in getting started, here are a few links I
visited over the weekend:

[http://www.braveclojure.com/do-things/](http://www.braveclojure.com/do-
things/)

[http://aphyr.com/tags/Clojure-from-the-ground-
up](http://aphyr.com/tags/Clojure-from-the-ground-up)

[http://clojurekoans.com/](http://clojurekoans.com/)

[http://youtu.be/wASCH_gPnDw](http://youtu.be/wASCH_gPnDw)

The last link is an hour-long interview with Rich Hickey - a fantastic
introduction to the language and his design goals. It's probably the best
technical video I've ever watched on YouTube.

------
tieTYT
> When I start using a language, there are usually some situations where I
> can't understand why my code isn't doing what I expect it to do. When that
> happens to me in a language like JavaScript, for example, finding out what
> the problem was is generally a very frustrating experience

This is a very weird paragraph to me because I've experienced the exact
opposite. You can see my frustration in this stack overflow question I titled
"How do I get better feedback from Clojure errors?":
[http://stackoverflow.com/questions/16901836/how-do-i-get-
bet...](http://stackoverflow.com/questions/16901836/how-do-i-get-better-
feedback-from-clojure-errors)

While I agree that JavaScript has tons of "Wat" quirks that shouldn't be
there, I rarely run into them. And more importantly, when I get errors in
JavaScript, the cause is relatively easy to track down.

With Clojure on the other hand, it is really difficult for me to figure out
why I'm getting the error. Yes, I get the error because I "was doing it
wrong", but the errors don't help me figure out what I was doing wrong.

\-------------

> With Clojure your editor (be it Vim, Emacs, Light Table...) is permanently
> connected to a live REPL. You continually develop, test and modify functions
> with subsecond feedback. Continuously. All the cores in your brain are lit,
> as you have literally no time to think about anything else. That's not only
> deeply satisfying, but also leads you to certain thought paths that slow
> feedback and its inevitable lower focus would have simply blocked. That's
> one of my favorite parts of Clojure.

This is very useful when you're writing new code, but I found myself
scratching my head when I had to go back and modify already existing code to
add a feature. As a workflow, I don't "get" when/how you're supposed to add
automated tests when you're using REPL driven development. But, once I went
back to my code, I always wished they were there.

You see, I'd modify the code and break something and then the problem I
described above made fixing it very time consuming. Usually the cause of my
problem was my simple functions wouldn't integrate together the way I
expected. The REPL gave me the quick feedback to say that "increment-number"
worked, but I would accidentally pass in a String or a vector into the
function.

~~~
tall
I have been working in both clojure and javascript for a while. When I
encounter bugs in javascript assuming it does not crash, it can become
difficult to track down the source due to the lack of name-spacing, mutability
of variables that allow for race conditions, and unintended changes upstream
if you're not careful.

Where as in clojure, the scope of name spaces is generally smaller, while the
errors are more cryptic, I agree. The line number that it points you to and
use of the repl allows one to dissect the function in great detail and by
checking the incoming data and outgoing data, the bug becomes much clear. At
least in my experience.

~~~
tieTYT
_shrug_ Just different experiences I guess. I should note this isn't exactly
an apples to apples comparison. I am using a lot of discipline in my JS
project. I'm writing the code test-first most of the time, and I only have one
global variable in the whole project.

------
tomp
> With Clojure your editor (be it Vim, Emacs, Light Table...) is permanently
> connected to a live REPL. You continually develop, test and modify functions
> with subsecond feedback. Continuously.

Can anyone explain or point me in a direction where I can learn how the above
functionality is actually used and useful?

I keep hearing about live-editing/hot-reloading, and in theory I believe it
must be very useful, but I cannot concretely imagine how it would be used in
practice. What kind of programs can work like that? Continuously running
programs, like web servers/GUI programs? So what happens when you change a
function? Do you manually simulate a web-request? Rerun unit tests? Would it
work with command-based pipelined programs, such as compilers as well?

~~~
patrickmay
> What kind of programs can work like that? Continuously running programs,
> like web servers/GUI programs?

I use Common Lisp and Hunchentoot to build RESTful web applications. I can
connect to the Lisp image running on the server using Swank from Emacs on my
development box. If there is a bug, I can change the function, recompile it,
and test the change with curl, without rebooting the server or reloading the
app. The same techniques work for adding new functionality and APIs.

I suggest just giving it a try. It'll change the way you think about building
systems.

~~~
tomp
What do you do then, after successfully fixing the bug? Are the changes
automatically reflected in files, or do you need to manually perform the same
change locally and commit it, so that it's there when the server is next
redeployed?

------
krstck
I'm also mostly a Rails dev in my day job but have been exploring Clojure on
my own. I've found myself writing out functions in Clojure first before
porting them to Ruby. I'm very pleased with the quality of the Ruby code I've
produced after doing this.

------
the_watcher
> the language tries to drive me to the cleanest solution

This is really appealing to me. I've hacked a bit with Ruby (One Month Rails
and some other tutorials), but I'm not sophisticated enough to know
instinctively how to refactor towards "clean" or "elegant." Most of my code is
pretty ugly, and gets uglier the longer I work on it, since when I'm hacking
on something without guidance I spend a lot of time just trying not to break
things. Is there a good resource for a non-programmer to start learning
Clojure? The syntax is a bit scary to me, but I just think back to when I
first learned about programming and figure diving in will eventually make it
read more sensibly to me.

Also, being connected to a live REPL seems pretty valuable for learning.

~~~
nonrecursive
Clojure From the Ground Up [http://aphyr.com/tags/Clojure-from-the-ground-
up](http://aphyr.com/tags/Clojure-from-the-ground-up) is a good resource, and
there's also my own Clojure for the Brave and True
[http://www.braveclojure.com/](http://www.braveclojure.com/) . I actually
started by going through "Land of Lisp" first. Though it covers common lisp,
not Clojure, it's a very fun book.

edit: Realm of Racket is also a good lisp book, and a lot of people like "the
little schemer". It's hard for me to say how good these are for people
completely new to programming, though.

Finally, there's the ClojureBridge curriculum, which is targeted at new
programmers:
[https://github.com/ClojureBridge/curriculum](https://github.com/ClojureBridge/curriculum)

~~~
the_watcher
Thanks, I'll check them all out. I've been playing with languages for a few
years now and built some really tiny, throwaway stuff. I'd say I grasp the
basic concepts of programming pretty well (by basic I mean the very basic),
but I still very much feel new to programming. I started with Ruby because
it's accessible, but ever since I've learned about them, I've wanted to
eventually learn a Lisp.

------
Totient
Clojure feels like a 'compromise' Haskell, but I mean that in a good way.
Haskell _really_ wants to pretend that everything is a pure function. But I
think this is a case where the conceptually simpler thing (i.e. no state) is
just too hard to reason about.

Clojure backs off the 'referential transparency ONLY' philosophy, and merely
discourages mutability. In my (limited) experience, this gives almost all of
the advantages of Haskell, but an environment that's easier to program in.

So yeah, I'm excited about Clojure too. I just wish we could port it off the
JVM...

~~~
m0a0t0
You can still do state using the state monad.

> this gives almost all of the advantages of Haskell

except one of the biggest ones - the type system. Obviously this is subjective
though. Some people prefer dynamic typing :)

------
guiomie
I'm a C# guy at work, I also do some front-end in javascript (with angularjs
sometimes). For side-projects I like to use node.js. I want to learn another
language, and I've been wondering wether I should go with Clojure or C++ ? My
dilenma is "Do I want to learn more about programming style running on VMs
(functional) or do I want to dive into barebone high performance code ?"

I've done C and Java at university, but that was a while ago.

Anyone has a comment?

~~~
platz
I'm a C# guy at work too. I can't say I've touched much C++ outside of college
also a while ago, but I've been studying functional programming for a while
and really enjoying the new concepts it teaches. It can be a bit humbling at
times though.

I got some good perspective with
[https://www.coursera.org/course/proglang](https://www.coursera.org/course/proglang)
and you could do worse than taking grossman's excellent course. It helps to
have some structure and a schedule when starting imho.

I will admit at times I wish I had more chops (closer to the metal i.e. C or
C++), but I think I was eventually just more interested in new ways to think
about programming, and I'm not sure I'd get the same pleasure out of digging
back into C++.

Obviously, if you know something more about your intended use case (i.e. you
want to program games), you can make a more informed decision.

~~~
visarga
For some reason the Programming Languages class is offline now.

~~~
platz
That sucks, sometimes the just let you watch all the videos even if the course
isn't running. Wonder why different courses have different policies

------
m0skit0
> Plus, whenever some interface I've built feels awkward or there's some
> duplication, often times I find that, while thinking and trying to refactor
> it, the language tries to drive me to the cleanest solution

Yes, this is my exact feeling when I'm still learning it :)

------
nilved
I'd heard from other Ruby developers that learning Clojure is difficult but
ultimately rewarding. That was my experience as well. All of my side projects
are written in Clojure.

------
erokar
The reason I end up with Python, CoffeeScript or Ruby and not a Lisp is the
prefix notation and the parentheses.

The parentheses can decrease readability and the prefix math expressions can
make the order in which you think up a solution awkward.

[http://sourceforge.net/p/readable/wiki/Problem/](http://sourceforge.net/p/readable/wiki/Problem/)

[http://cs.brown.edu/~sk/Publications/Papers/Published/mfk-
va...](http://cs.brown.edu/~sk/Publications/Papers/Published/mfk-val-grow-
tree-expr-integ-fp/paper.pdf)

~~~
Expez
The benefits of lisp 'syntax' are legion, to the point that I've come to feel
that your position is unprofessional. Why wouldn't you try to get passed
something as superficial as syntax, in order to better _make_ stuff?

1) Easier to learn and remember syntax for polyglots. No more Googling, shit
like "what was the syntax for try-with-resources or the new multi-catch
feature in java"?

2) The language tooling is so much easier to get right. The parser for Ruby is
10k lines. What the actual fuck? How can you expect people to make good tools
if they can't get past the parse step?

3) Macros!

4) No fucking precedence rules. I don't want to memorize that the precedence
for 'and' and && is different in Ruby and how 'and' interacts with the
precedence of other operators like assignment.

5) Structural editing.

I might have forgotten a few, but 2) and 3) alone are killer features.

~~~
tomp
Julia [1] has 3 and 5, and almost 1 (it has very few built-in syntax sugars
and a uniform way of invoking macros). It's targeted at scientists, so 4 is
not an option, as infix syntax is a hard requirement for mathematics.

[1] [http://julialang.org/](http://julialang.org/)

Edit: Elixir [2] is homoiconic as well, with even more uniform syntax (though
it doesn't have special matrix syntax).

[2] [http://elixir-lang.org/](http://elixir-lang.org/)

~~~
technomancy
Elixir is not homoiconic. They used to claim that based on a very unusual
definition of homoiconicity, but they have removed those claims from their
materials.

~~~
tomp
But Julia is, or not? If yes, why? (The only difference, as far as I can see,
is that Julia AST is considerably simpler than Elixir's (a Julia struct with 3
fields, only two of which need to be present: head and args). Though
admittedly, that counts a lot.

------
badman_ting
Man. I know Lispers hate hearing about it, but I was _so on board_ with this
until the sample ClojureScript code and all the parens. I just… don't wanna
write code like that.

~~~
eccp
I felt the same way as you until I actually _tried_ Clojure. In a few hours
all my rejection of the parens dissapeared because I finally understood.

Try solving a small problem in Clojure (a code Kata, or a problem from Project
Euler) and you'll see those aprehensions against the parens will go away.

Nowadays I'm having trouble to accept the syntax of other languages, eg. Scala
:-)

