Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Better performance in App Engine with new Lisp language Clojure (googlecode.blogspot.com)
173 points by mattyb on May 11, 2010 | hide | past | favorite | 85 comments


Posts like this really make me want to move to Clojure.

Python is now my go-to language, especially because of Scipy, NetworkX and bridges like RPy.

I would definitely put in the time if someone with mathematical modelling experience can support the idea that I'll be more productive in Clojure. Anyone?

I really would love to see a list of testimonials and anti-testimonials of people from various fields that switched to Clojure and either got much more done or got burned.

Sorry, I realise that this is a wee bit off the main topic.


FWIW, we're doing lots of math with Clojure in a startup. Mostly using Incanter and Clojuratica as a bridge to Mathematica.

So far the experience has been great. Apart from the language being really well designed, there is the wealth of java libraries accessible just by adding a single line to your project.clj. And there is Clojure support for parallel programming — there is nothing like spending all of 5 seconds on making one of your hotspots use 16 cores just by adding a 'p' in front of 'map'.

All in all, so far it has been a great experience. There were amazingly few bugs and problems.


You should spend a little time playing with Clojure. I don't know if you'll be more productive in it or not; people seem to either prefer lisps strongly or dislike them strongly. If you like lisp then you'll have no problems being tremendously productive, especially with libraries like Incanter available.


Do note, python has much better support for a huge variety of modelling techniques. I looked at incanter and it's obvious that it's in it's infancy c.f. R or numpy/scipy and associated libraries.

At the moment my vote would be for python or clojure + r.


Have you taken a look at rincanter? It claims to be a Clojure+R wrapper that should help you out:

http://github.com/jolby/rincanter


I very much like the elegance of lisp code, but I'm still a 'reader', not a 'writer'. I hope to change that one of these days, but as long as that magic 'click' hasn't happened I'm not confident enough to jump in and start some major project.

Maybe that's what I should lose, the paralysis of starting out down the wrong track and simply do stuff wrong until I find a better way.


One of the charms of lisp is that it makes it easy to change your mind. It is really well suited to iterative development; even if part of your iteration process consists of getting things wrong.


Practice


So I was in an App Engine workshop at PyCon and asked an engineer about running Clojure on App Engine, which resulted in a confusing exchange. Then I realized they thought I was talking about Google's Closure Library. Argh! I guess this wasn't on the radar.

This shows a lot of promise, and it would be great if App Engine could become (in a way) Clojure's Heroku.


I've looked off and on into using App Engine's Java interface. But even the "hello world" app looked much more bureaucratic than the Python equivalent (it's due to Google trying to do things the Java way).

Do you still have to deal with Java's baggage even if you run Clojure on App Engine? How much can you abstract away? Any libs?


Occasional you do have to deal with Java's baggage in Clojure. The best example I can think of right now is the build process. The consensus is to use Maven or the Clojure tool Leiningen.

The good news is that you also get Java's "Deployment for Dummies" solutions (just copy the JAR/WAR and you're good to go), though.


Leiningen is actually pretty cool. It uses Maven under the hood (but you don't have to know that).

The nice thing is that if you suddenly decide you need to use a Java library (say, one of the Apache Commons libs), you just add one line to your project.clj file, do "lein deps" and boom, you can use the library in your project.

Having written quite a bit of software in Common Lisp, this is a welcome change.


Leiningen only uses Maven's dependency resolution API. Everything else is written in Clojure.


Huh?, how's this easier than adding a package entry to the depends-on form in an asdf-file in CL?


You can add jars from any JVM language and use it directly with the great Clojure Java-interop.


For small crud apps you can avoid the java baggage.

Using ring and ring-servlet you can build the servlet app engine wants. Libraries like compojure build on top of ring.

The datastore can be accessed using http://github.com/r0man/appengine-clj or http://github.com/smartrevolution/clj-gae-datastore.

Accessing the blobstore has not been abstracted away yet and requires a bit of work to get uploads acting correctly with ring/compojure.

I've not touched task queues, xmpp, mail, or memcache and have not seen any abstractions for them.


I think the headache comes from accessing the datastore in an OO-like way. The GAE Python API makes this a lot simpler.


The Java Datastore API is much more straightforward as well. I strongly prefer to just use it directly over JDO/JPA, which suffers from a bit of an impedance mismatch.


This is correct - I was referring to using JDO.


This is a very readworthy slide from the CTO of freiheit and the project: http://www.slideshare.net/smartrevolution/how-a-clojure-pet-...

I'm curious about the "how to get rid of Eclipse"-part. How do you "Go to implementation" and "Find usages" in Clojure without a 7 key-combination in Emacs? I would love to take a Clojure-IDE for a spin.


NetBeans with Enclojure is probably the best option for those who do not already know Emacs (or Counterclockwise if you are already in the Eclipse ecosystem.) I use Emacs for Erlang and Python coding, but for some reason the swank-clojure setup never really clicked for me. I keep at it and I am sure at some point I will not think that my Clojure dev environment is not more of a hinderance than a help, but if you are not already using Emacs I would probably suggest you start off by looking at the list here: http://www.bestinclass.dk/index.php/2010/03/clojure-ides-the...


> How do you "Go to implementation" and "Find usages" in Clojure without a 7 key-combination in Emacs?

Go to implementation is M-. with SLIME in Emacs. It can even open up Clojure source in jar files on the classpath and let you edit (and save!) them from there.

Find usages is a little more complicated: C-c C-w c, but not too bad.


La Clojure for IntelliJ is getting pretty good, and is a nice option if you have multi-language application. I did a little work on some of the original code, some of which also survives as the "Clo-Jet" plugin, if you want something lighter-weight.


A question I've been meaning to ask but didn't want to make a completely new post about it:

If you could write a server (not a plain HTTP webapp necessarily) in Clojure, Python, or Node.JS, provided you know all three, which would you choose and why?


I'd go with Clojure if you need any of the following:

1. Concurrency 2. The most (largest qty of) available FOSS libs anywhere 3. Speed 4. The ability to extend the language 5. WORA 6. Text/string processing

Python will win in scripting/*NIX integration, though.

Don't really know enough about Node.JS


> 2. The most (largest qty of) available FOSS libs anywhere

Quick heads up. The ease of FFI (in Clojure's case with Java) is not unique to Clojure and it isn't necessarily a great thing. It's also an issue with Common Lisp: as FFI with C is easy, there's less incentive to develop idiomatic libraries for the language. E.g., Common Lisp lacks a standard modern way to network I/O, but it's largely been ignored as larger users of the language e.g., ITA could always build and standardize upon an internal C-based extension.

That being said, Clojure is great for reasons beyond running on the JVM: a unique approach to concurrency, incorporation of ML-family features, first order data structures beyond lists (maps, vectors) and the fact it's a Lisp-1 with a great macro facility. I'd love to see Clojure also go beyond the JVM and onto CLR, Parrot and LLVM.

Interestingly enough the other prominent "next generation Lisp", arc, is also a Lisp-1 with true macros (as opposed to Scheme's hygienic macros).


It's very common to write an idiomatic wrapper for a useful Java library. Your complaint seems to be that those wrappers won't survive the transition onto another platform. I don't really see why that's a problem.

Why target another platform if not for its libraries? If Clojure is exactly the same on the JVM as it is on LLVM, why should it ever leave the JVM?


Common Lisp lacks a standard modern way to network I/O

http://common-lisp.net/project/usocket/


Common Lisp has no standard way of doing Network I/O. usocket is one of several available socket libraries which don't exist in the ANSI spec.


It is a de facto standard. Everyone uses it; just like the Metaobject protocol.


If the usocket library suddenly disappeared, along with all the current Lisp implementations, there would be no guarantee that someone making a new CL implementation had to implement the library in a way similar to usocket, or even implement a socket library at all. It's the same as saying "everyone uses Emacs to edit Common Lisp, so it's the standard Common Lisp editor".


What is the standard way for network I/O in C, C++, Python, PHP and Ruby?

I am not in the business of conjuring up hypothetical situations about the demise of Lisp implementations and libraries; that doomsday scenario of having to recreate civilization from specs is simply not in my contingency plan :-)

Never underestimate the power of convention, de facto is the rule, rather than the exception.


I really have a hard time seeing Python losing to Clojure on (2), (5) and (6). What kind of software/library would you find on Clojure but not Python? How is Python not WORA? Where does Python lack in text processing?


Not Python specific but languages that regularly interface with C code are often troublesome on Windows because the library writer assumes Posix functionality is available or the library depends on Unix libraries that are at best badly ported to Windows.

Haskell is one language where i encountered that too often, whereas Clojure's Windows support does not feel second rate. The portability of the JVM and Java's libraries combined with a joyful functional language like Clojure is very attractive.


Java & the JVM give me 2 & 5. While Pythons text processing is great, I think functional composition & juxtaposition give Clojure and edge. Plus, strings are simply sequences, so the core language works well with them too.


Python has no parallelism story. Once you start using the Clojure parallel primitives, there is no going back: you will never want to deal with managing threads and mutexes again.

It's kind of similar to the feeling you get once you've programmed in a language with GC. You really don't want to go back, unless you have to.


All your repliers seem to forget that Jython exists and can be run on the app engine as well, putting Jython on par with Clojure in terms of available Java libraries.


Let's not forget JRuby. Java might be stalled but the JVM is really starting to show a lot more value.


Interestingly in the beginnings of java the JVM was just another abstraction layer.

Now that the JVM is really running just about anywhere it has become a viable platform to target, and java is just one more language that targets it.

Clojure, groovy and scala are built on top of the JVM, but there are also plenty of languages that are available on mutliple platforms.

Whoever came up with just-in-time compilation deserves a gold medal, without that none of this would have ever happened.


Whoever came up with just-in-time compilation deserves a gold medal, without that none of this would have ever happened.

My understanding is that JIT in Java is a variation on what the Smalltalk world called dynamic optimization. That was introduced into Smalltalk by Peter Deutsch and Allan Schiffman in the 1980s, but I don't know whether or not they invented it independently.


Yes, that's true. I'm not claiming that the just-in-time compilation technique was invented specifically for java, merely that it was a very useful addition to it and that whoever did invent it probably helped saving the platform.

That invention pre-dates java itself by quite a few years, but then again, java has a lot of elements in it that were considerably older, iirc there was UCSD pascal P-code, which was another virtual machine like environment with an abstracted machine, and the 'forth' language which has quite a bit in common with how the JVM operates on the lowest level.


I was giving you the information I had that would help you if you you wanted to track down who invented it.


Right, sorry, the endless downmods made it seem as though that comment was interpreted as though I made it seem as though the jit was invented after or because of java. Of course it wasn't. (see the other comment above).

I was just reading that 'early history of smalltalk' thing the other day, and it struck me as though really, since the 60's there hasn't been that much progress at all.

The 'mother of all demos' combined with the 'dynabook' (iPad?) really pretty much covered everything with the exception of the mobile phones.

Sure, we all have the equivalent of several Cray-1's in our houses now (or even in our pockets), but conceptually we are still were we were back then.

Everything looks great, we're burning billions of cycles on spiffy user interfaces and showing movies.

But under the hood it's old hat.

That's why I keep circling around and around trying to find my new 'home', the environment that I think will last me for the next 10 or 20 years.

I haven't found it yet. All I see is endless repetition, configuration files, minor tweaks. Rarely a bold move (fleet comes to mind, but I don't think it will ever be a commercial success). Programming seems to be mired in endless detail, fiddling the bits and tweaking things to get a link here or a widget there and to get them to talk to each other. User interfaces have become the main focal point, when they weren't (or at least when they weren't as pretty) we were happy if stuff just worked.

I feel like a homeless guy looking for a place to stay.

Clojure might be it, I don't know...

but I'll try it for sure. No point criticizing the soup before you've eaten it.

Thanks for digging up that jit reference.


Just-in-time compilation is not a new idea. According to the book "The Practice of Programming" (by Brian W. Kernighan and Rob Pike, Ch9, pg. 242):

"Generalizing the idea for the full set of operations, we can write an on-the-fly compiler that translates the current regular expression into special code optimized for that expression.

Ken Thompson did exactly this for an implementation of regular expressions on the IBM 7094 in 1967. His version generated little blocks of binary 7094 instructions for the various operations in the expressions, threaded them together, and then ran the resulting program by calling it, just like a regular function."


It seems you are confusing JIT and bytecode interpreters.

Why wouldn't Scala/Clojure/Groovy et al be possible without JIT? It's possible to run on the JVM anyway, whether said VM supports JIT or not.


They'd be possible, but they wouldn't be nearly as fast without it.

Java before JIT was added to the JVM was dead slow.


speaking of which. I'm testing a big multithreaded jruby app I wrote as I type this, and it's running very solidly. anytime I need parallel I'm going straight to jruby.


> What kind of software/library would you find on Clojure but not Python?

Java has a lot of great libraries for which there are not terrific examples in Python. Clojure gets all of them.

> Where does Python lack in text processing?

Clojure handles large strings better than Python (unless you start using substrings, in which case an underlying java bug hits you).

(oh, and Clojure is not a deliberately and comically crippled language).


How is Python deliberately and comically crippled? I'm honestly curious.


I think he may be refering to the GIL.


That and certain deficiencies spawned by a desire for “simplicity.”


Don't forget one-line lambdas.


It is true. I really, really, really do not like those. I dislike them to the point of irrationality.


Many python libraries have a C component which makes them a no go when it comes to app engine. Two big examples are image manipulation and numeric and scientific computation. The pure java libraries in these categories are much faster and more complete than the pure python libraries.


Node is pretty interesting and seems to have pretty good performance, but I wouldn't build anything critical on it until at least version 0.2.

As far as I know, there are semi-frequent breaking changes. Ryan Dahl has said that API stability should come with version 0.2.


"I wouldn't build anything critical on it until at least version 0.2"

Ha! It's a brave new world. It used to be you needed a whole version number under your belt before critical stuff could be built..


Been talking to people working with node.js and the general vibe is 'it rocks'. Although, there is a lot of breakage it's for the best.


Maybe they're taking the emacs approach to version numbers.


Agreed, node development is going at a breakneck pace, but you should count on your code not working 6 months down the line without at least as few tweaks.

BTW, the new Buffer objects are awesome, and provide massive speed increases with binary data.


The most (largest qty of) available FOSS libs anywhere

Do you literally mean anywhere or compared to other GAE languages?

If so do you have a rough estimate on how many Java/Clojure FOSS libraries/modules/packages there are?


I actually did this purely for fun. Could have done Python but I've been meaning to learn Clojure anyway. Check out http://github.com/mattc58/animate for the beginning of my web server in Clojure.


Super, thanks! I've asked if there was some kind of a reference web application in clojure that I could study before to show me 'how it's done', but got no takers, so I'll use your code as a study object if you're ok with that.


Mark McGranaghan's Ring library might be a good place to start. The Ring spec is the de facto base library for web applications in Clojure, much as Servlets are in Java, and Rack is in Ruby.


That's another helpful pointer, thanks again!

(found it here: http://github.com/mmcgrana/ring )


Sure absolutely. It's been a good learning experience. As soon as I finish the blogging features of it I'll start blogging about it. :)


This is something I've been noticing as long as I've been prorgramming. If you are programming a tool then the tool will be a requirement for building the tool.

For instance, you can't really build an assembler for a new architecture from scratch without some form of assembler and so on.

The bootstrapping sequence seems to be endless, you could be blogging about writing your blogging tool if you had it already. We always seem to need some scaffolding underneath it, just one more turtle on the stack.

No more hand calculating branches these days, /me is happy ;)


This is all for fun and for great justice, so I'm cool reinventing the wheel.


Keep in mind the loading request scenario for running GAE apps that are implemented on the JVM.

http://code.google.com/appengine/kb/java.html#What_Is_A_Load...


JVM apps on appengine start up slow. I encourage anyone looking into using a JVM app on appengine to put together a simple app, wait 10 minutes after deployment, and then hit the url and see how long it takes to load.

It bothers me that people don't mention this.


It's called "loading request" and Google mentions it in the docs. They claim that with the number of users rising, relatively few people will actually experience it. But the ~10 seconds it takes to load my clojure app surely is not pleasant.


Because if your server is getting hammered the JVM is going to be warmed up and really fast.


It doesn't really say much about performance...


It doesn't say anything about performance. I checked find-in-page in case I somehow missed it. :)


The blog referenced in this post has more details on their use of Clojure: http://www.hackers-with-attitude.com/search/label/Clojure


Where do the 30% and 50% numbers come from?


I took it to be an educated guess, not a statement based on hard data.


I am using Clojure a lot right now on a customer's project, a cool language for sure.

That said, I have doubts about Clojure + AppEngine because of the loading request times. I can get a Java + AppEngine app to do about a 1 to 2 second loading request time by not using JDO and minimizing dependencies.

Unfortunately, loading the Clojure JARs (or the JRuby JARs) increase the loading request time.

Sometimes when I go to TheDeadline, I see almost a 10 second delay on the first page load. Does not happen often, but it does happen.


On Google App Engine, Google's cloud computing platform, developers can officially choose between two languages -- Python and Java -- and both run on the Java Virtual Machine (JVM).

If they've got Python running on the JVM, why aren't they contributing back to Jython (or releasing their own Python->JVM bytecode compiler)?


This is rather unexpected. AFAIK, the Python they have there did not run on top of JVMs.


Where are you getting that quote from? They don't run Python on the JVM.


I think the article has been changed after andreyf quoted it.


article implication (GAE's python support is actually Jython) is incorrect http://jython.xhaus.com/jython-on-google-appengine-why-bothe...


Interesting, but I cringed when I read this:

"Writing less code requires less time."

Seriously? Then again, it /is/ a "to-do" app...


Seriously. Studies from a wide variety of languages over several decades have found that average lines of code/developer is reasonably close to constant independent of what language the developer is using. Therefore languages and libraries that result in less code to get your work done generally result in higher productivity.


I'd be interested in seeing similar studies with relatively modern languages, though. The only ones I've seen have been comparing things like C, Pascal, and Cobol.




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

Search: