Hacker News new | past | comments | ask | show | jobs | submit login
Clojure & Python, Side by Side (tin.nu)
158 points by llambda on Nov 19, 2011 | hide | past | web | favorite | 61 comments

Side by side assumes that you would write the Clojure solution this way.

But that's not how I (nor, I imagine, any experienced Lisper) would do it. Lisp programmers are not afraid to write compilers in Lisp targeting Lisp. This is not something a Python programmer would consider doing.

I would implement Dan Friedman et al's Scheme constraint solver (cKanren) in Clojure (which can be done in a few hours) so I could solve all sorts of problems, not just Sudoku, in 80 lines of code instead of 200 with very good performance.

Great, I was wondering what would be an idiomatic way of solving this in Clojure.

Given the addition of core.logic into Clojure 1.3.0, one could even skip the implementation of cKanren. Although to be honest I'm not altogether sure how core.logic measures up to cKanren.

I'm the main developer of core.logic :) core.logic is simply missing cKanren constraint solving extensions at the moment, but again they won't be hard to add since core.logic is a fairly faithful interpretation of miniKanren (the system which cKanren extends).

I love this format. Can anyone point to more "Rosetta Stone" examples like this? (Aside from ever-prevalent "X in Coffeescript compiles to Y in Javascript")

Not using the side by side format, sorry.


SQL and MongoDB MapReduce side by side: http://dbpedias.com/w/images/9/90/MongoDB.JPG

This is pretty cool.

I know python well enough to hack my way around it. I'm probably missing something, but now I have to ask: what would be the point in me learning clojure?

Clojure has excellent concurrency support.

Clojure has a focus on functional programming, immutable data[1] and the sequence abstraction[2].

Clojure is a Lisp and has most[3] of the super-powerful metaprogramming facilities that you would expect from a Lisp. This means you can, with enough effort, mold the language to suit your needs, even turning it into a completely different language should you wish to do so.

Clojure is not object oriented, though it does allow you to instantiate and create Java objects for the purpose of interacting with Java libraries. Clojure does support OO-like code through its Records/Protocol system.

Clojure has out-of-the-box support for multimethods.

Clojure runs on the JVM and therefore has access to the many many libraries written in Java or other JVM languages.

Pure Clojure code is, as far as I can tell, higher performance than pure CPython code.

PS: Just for the record, I love Python and use it a lot (and have actually been out of touch with Clojure for almost nine months now, sadly). The above are reasons why you may want to learn Clojure - not reasons to drop Python.

[1] The benefits on pure-functional code and immutable data are that it makes concurrency easier and safer and that it makes code easier to reason about as you do not need to consider that 1) side-effects are happening behind your back and 2) the data is being changed elsewhere (which is also why it makes concurrency easier).

[2] Similar idea to Pythons iterables, except IMHO Clojure's sequences are much more a part of the core language than iterables in Python, in that in Clojure most things are sequences, while in Python this isn't the case (though a lot of things are iterables).

[3] I say most because Clojure does not have reader macros

"Pure Clojure code is, as far as I can tell, higher performance than pure CPython code."

Not so here; the author mentions that the Python version is faster (in his blog post).

Adding type hints to the relevant spots in the Clojure code might have helped him in terms of performance.

This post has been on Hacker News multiple times. It usually comes up on the weekend when people post a lot of Clojure stuff. If you read the article, it says that the Clojure implementation was meant to mirror Norvig's Python implementation. The clojure code could certainly be written more succinctly. I thing there was another article that did this. Would have to look it up though.

Clojure has no GIL and the concurrency API has few rivals

Good point. Thank you for this.

Lets you target the JVM without writing Java, among other things.

Unfortunately, Jython is at 2.5.2, 3.5 years behind cpython.

That is certainly a problem. But there are very few language constructs in Python >= 2.6 that are missing in Python 2.5, and the really missing features (e.g, multiprocessing module) have better alternatives in the JVM, or are redundant. You lose some portability, but Jython 2.5 doesn't seem to be that limited in capabilities.

Anyways, YMMV. All I got to do once was set my Django application to run on Jython, and that was relatively painless.

While I'd agree Python 2.5 to 2.7 doesn't bring a swath of language features with it... it's a good sign of Jython's slowing/sluggish growth/development.

Personally, I want to use a language implementation that will be around and (well!) supported for many years.

None of you three mentioned Python 3.0 to 3.2.

That's because they don't matter to anyone.

It seems common that people don't upgrade to a breaking version of a programming language based on name or distro channel alone. Hence the slow uptake of Python 3 and Perl 6.

This occurred to me after I finished writing that post.

Yea... I'm still confused as to the whole point of pure/near-pure functional programming if we're not getting better code density/more productivity against other languages which I (and some others) find easier to work with.

I guess all I'm saying is "convince me!" :) I'm all ears.

In short: FP makes programs easier to reason about and understand by using trustworthy abstractions. Here are some resources to check out, which explain better than I could:

Why Functional Programming Matters: http://www.cs.utexas.edu/~shmat/courses/cs345/whyfp.pdf

Out of the Tar Pit: http://web.mac.com/ben_moseley/frp/paper-v1_01.pdf

Simple Made Easy: http://www.infoq.com/presentations/Simple-Made-Easy

The big differences between Clojure and Python are probably twofold: it's a Lisp, and it focuses on getting concurrency right. We've had Lisps for a while, and Python only really lacks Lisp macros, so let's think about the concurrency stuff...

Clojure's design goals combine some deep ideas about identity, state and time together and includes data structures and a concurrency API that supports these goals. It's going to be hard for anyone to just convince you in a comment like this, and even if they could, I'm not the one to do it as I'm a Clojure noob.

You should read this essay http://clojure.org/state and watch this talk http://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hic....

I think you will find that Clojure is pretty interesting, even if you don't start using it right away. I apologize for just throwing you links, but I can't do it justice, and Rich Hickey is a great lecturer, so you'll get more from his stuff.

I mean the answer is that the Python example is nearly purely functional to begin with. It uses list comprehensions heavily and I couldn't find any mutating assignments in a quick glance of the code. Which is not surprising, since it was written by Peter Norvig, who wrote a very popular Lisp book.

I think what Clojure can offer on top of that is macros, the advantages of which are really only evident on bigger or harder problems.

getting better code density/more productivity

Its not so much about brevity or productivity as it is about correctness. Functional programming and immutable data makes it easier to reason about code and to prevent bugs/errors, especially in the context of concurrent/multicore code.

You actually get better code density with Clojure, for large enough programs. And a WAY better code density when you try to do multithreading.

How does Clojure's Java interop compare to Jython's?

In some ways it's nicer (clojure fns are java Callables), in some ways it's less nice (harder to extend a class).

Follow up question.

How does it compare with Scala?

This is really neat. Although, one thing that makes it easier to map this program from Python to Clojure is that the original program was written in a pretty functional style. It would be interesting to see if a more imperative sample program, or one using more object-oriented features, would map similarly.

I agree. For some things, like more mathy things that only perform one function, it seems like functional programming is the way to go. However, for HUGE programs based on data and complex interactions between and extensions of objects, it seems like a more object-oriented style would be better... all about the right tool for the job, I guess.

I think you're absolutely right that functional programming is particularly suited for things like mathematics. But you can also enjoy many of the benefits of a functional approach by moving most of the complexity into purely functional, well, functions and leaving the state-modifying code fairly simple. For a good pragmatic example of this approach, check out the snake game in Programming Clojure v2 from Pragmatic Programmers.

Coming from Ruby this approach was a bit mind-boggling at first, but even with my fairly limited Clojure exposure (or should that be expojure?) I've come to appreciate how easy pure functions are to test and to reason about.

Python looks like a lot less typing.

And much more readable, without the parenthesis balancing dance.

Just like English is soooo much more readable than German, because well, I don't know German :)

I found the Python more readable even though I have written programs in Clojure and never written programs in Python. In fact I'd be willing to bet that Python-like syntax would be found to be more readable than Lisp-like syntax for programmers with N years of experience in that language, if such a study could be conducted. (ie, I'd bet that an average programmer with 5 years of Python experience and nothing else can correctly read programs faster than an average programmer with 5 years of Clojure experience and nothing else (not that the latter exists)).

True, but for instance I know neither Python nor Clojure, and yet Python looks more accessible on first glance - even though I have some experience with other LISPs.

I know Common Lisp well, thanks. Only dabbled with Clojure.

I've started using Clojure after many years of Ruby and I have to say the parentheses are a non-issue. Emacs and many IDEs automatically balance the parens for you (see e.g. paredit). Once your eyes learn to ignore the bracket soup, the code starts looking an awful lot like Python (cmp. Emacs Lisp indention with Python semantic indention).

Funny, I was thinking the opposite -- the Clojure code is far more readable.

In addition to performance metrics, this site has implementations of their benchmarks in all the languages they test.

It's not pretty and side-by-side, but it's fascinating.


See the previous discussion (about Justin's blog post): http://news.ycombinator.com/item?id=2386575

LISP is the coolest language ever and maybe forever, in theory. In practice, it also works phenomenal, but just for 1%.

Meh, I am an amateur when it comes to programming and still I am loving clojure over python. Truth is that when you are using lists all the time, lisp seems just more natural. All those for and if in object oriented languages feel pretty awkward when you manipulate lists and hashes.

Just an amateur opinion although.

Would love to see this in Ruby

Is there a site out there that has common implementations of problems using different languages? I would love to be able to compare.

Very much agreed. Although clojure might be faster, it is so so difficult to read, and from a rubyist's POV, looks like a disaster compared to python. Maybe that's just a result of being spoiled by super clean syntax and almost human readable methods... but that's gotta count for something

I'm a rubyist and now Clojure convert. The code does not look difficult to me, but i'm sure you can make it much more concise if you were to add some mutation in the Clojure code. As my career progressed i found that I don't care almost at all about syntax but semantics. Clojure offers far better semantics for almost everything including Data Structures, concurrency and meta-programming. That's were the true power of the language is on its semantics.

The parentheses -- my eyes -- pain

I can only admire the persistance (free time) of someone coding in Clojure. Everytime someone says to me "I hate Objective-C syntax" I show them Clojure...

If I want fast performance I code in C or other low level language. Sorry Clojure community, I'm not drinking the kool aid this time.

What's really unique about the Clojure community is that (as opposed to many other language communities) we don't respond to vague handwaving-type flamebaits such as this one.

Most of us just get stuff done using Clojure, quickly, getting concise and most importantly — correct code, even in massively multithreaded applications.

What makes you specifically mention fast performance? I wasn't aware that this was the most important selling point of Clojure. What kool aid is it that you won't drink this time?

For me, Clojure is great because it allows you to build powerful abstractions and has some interesting concurrency constructs, while running on the JVM and making it easy to interoperate with Java code. Of course, being a Lisp, it uses Lisp syntax.

Registration is open for Startup School 2019. Classes start July 22nd.

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact