Hacker News new | past | comments | ask | show | jobs | submit login
Thoughts on Clojure (programmingzen.com)
93 points by fogus on July 9, 2010 | hide | past | favorite | 40 comments



For the inevitable "Where do I start" questions, read this previous comment:

http://news.ycombinator.com/item?id=1033503


... and an example of web development in Clojure:

http://mmcgrana.github.com/2010/03/clojure-web-development-r...

Just install leiningen, whip out your favorite text editor, and you don't have to worry about downloading/installing clojure, libraries and deps.


... provided you have java installed.


... which is likely if you use an Apple laptop and trivial if you don't


When I first started out with Clojure on Ubuntu I honestly had no idea which packages to start out with. It's not a huge deal and I was able to get it right through trial and error but it's one more step where a potential user could get lost.

I wouldn't mind contributing to some official getting started documentation if that was possible. Seeing an HN comment as the go-to source for getting started upthread disappointed me.


Sorry to disappoint.

What you're asking wasn't the intended scope of my comment, but it is covered by the 4th item: http://en.wikibooks.org/wiki/Clojure_Programming, specifically: http://en.wikibooks.org/wiki/Clojure_Programming/Getting_Sta...

To a great extent the previous items are intended to convince you to give Clojure a try/orient you before you start typing in a REPL.

Learning a functional language is not necessarily hard but many people say it's harder than programmers who are experienced in imperative programming expect. The latter are used to picking up new imperative languages and the change to the functional paradigm is not as easy. On the other hand, the more scars they have from side effect induced bugs the more they appreciate it.


The Apress book (VanderHart, Sierra ) is out, it's pretty well done:

http://www.amazon.com/Practical-Clojure-Experts-Voice-Source...

and Manning has 2 MEAP books in the pipeline

http://manning.com/fogus

http://manning.com/rathore


Since it's not covered in the link you posted I can't recommend labrepl enough as a way to get started.

http://github.com/relevance/labrepl


I really want to get into Clojure, but everything I've read suggests that I'll have to learn Emacs to do it. Does anyone think giving up Vim for a few months is worth it?


I still use exclusively Vim for all my clojure coding. I have Vim in one window (with VimClojure for syntax highlighting and some other features), a REPL in another (for quick experimenting), and my ant script in another for compiling and testing the whole thing. It's not as integrated as SLIME and emacs, but I don't feel like my tools are slowing me down significantly.


With Emacs(w/paredit)+SLIME you would be doing "interactive development" which is really a fundamentally different and better way of using Lisp. I cannot recommend it enough.


This is exactly how I work with Clojure. Emacs is not required to develop in Clojure.


I've been using clojure for a while now (nothing huge LOC-wise, but it's a pretty significant part a large system). I use vim, and haven't had any troubles. The clojure REPL doesn't seem to have readline support, but it works fine with the rlwrap program. I've been meaning to learn emacs to try out the niftier select and execute functionality that it has, but vim does work for me.



I'm a huge Emacs fan, but I'd recommend against learning Emacs and Clojure at the same time. While the tight REPL integration can be difficult to set up in vim, you can use a separate REPL/editor environment to get going, and then ease yourself into a more integrated environment once you get a little more familiar with things.


This is a great place to look for several IDE's and guides to getting started with VIM.

http://www.assembla.com/wiki/show/clojure/Getting_Started


You can modify Emacs to mimic Vim, which might be help you bridge the gap:

http://www.sanityinc.com/articles/vim-vs-emacs


You can even try it online: http://ideone.com/l7Nqw


In the middle of the article, the author talks about three advantages that clojure has over ruby. Simply put, speed, easy concurrence and functional.

I don't find these to be really good advantages.. First, "functional" isn't an advantage.. I mean, the advantage of functional code might be easier maintenance, concise code, easier to concurrence etc.. but "functional" isn't an advantage. It's like saying C++ is better than ruby because it is imperative or OO.. "Why is imperative or OO better?", that's the interesting part.

In my opinion, the advantage of clojure by comparing it with Ruby are:

- You get the best of Java (lots of library, OO) - You get the best of Lisp (macro, high level function)


> First, "functional" isn't an advantage.. I mean, the advantage of functional code might be easier maintenance, concise code, easier to concurrence etc..

Those are all good reasons why functional programming is an advantage. I guess you object to my grouping of all these under the "functional" umbrella term.

> In my opinion, the advantage of clojure by comparing it with Ruby are: - You get the best of Java (lots of library, OO)

I mention this as well, but that's not really an advantage over Ruby. JRuby gives you access to all the Java libraries you want.


What I meant is that functional in this situation is a bit vague.

Clojure Dude (talking to ruby dude): Hey, you should try clojure.

Ruby Dude: What is clojure ?

Clojure Dude: Oh, clojure is a lisp/functional language. You should really give it a try.

Ruby Dude: Why?

Clojure Dude: Its main advantage is that it's functional.

Ruby Dude: Wow, you convince me. I'm switching!


For a certain (large) class of programs, being "functional" is an advantage. Interestingly, you made the point that being functional means easier maintenance etc., but fail to attribute those advantages to being functional. If your argument is that there can be bad functional code which performs worse than non-functional (imperative or OO) code, I don't disagree. However, in the multicore future that our semiconductor overlords have in store for us, functional programming has a demonstrable advantage in helping build understandable and robust programs.


From an interview with the father of Haskell:

http://www.infoq.com/interviews/armstrong-peyton-jones-erlan...

But it turned out to be very hard to turn that into actual wall clock speedups on processes, leaving aside all issues of robustness or that kind of stuff, because if you do that style of concurrency you get lots of very tiny fine-grained processes and you get no locality and you get very difficult scheduling problems. The overheads overwhelm the benefits, in short.

It may be true that FP does make concurrency easier, but I don't think this has been demonstrated to be generally true yet and it's certainly not as simple as just eliminating side effects from your code.


While true, this is somewhat disingenuous. When people speak of concurrency in functional languages, they don't mean that each function executes in its own thread (even if it can, according to the semantics of the language). As this quote points out, the overhead of that is absurd, though maybe we'll get there someday with specialized hardware.

What functional programming does mean right now is that it's much easier to chop your program up into reasonable-sized chunks: big enough that it's worth the overhead, small enough that you can distribute as widely as possible.

In other words, if you think of a functional program as a tree and then expect to run each leaf in its own thread, the overhead will vastly outweigh the benefits. But the functional semantics also allow you to run each of the dozen main branches in separate threads with little effort.

I do this in Clojure all the time.


Sure but this is also what you generally do in an imperative threaded app. Break the work up into discrete jobs and use a producer/consumer model to parallelize it. This has to be done carefully and usually requires an intimate understanding of the flow of the computation. It might be easier to do this in a functional language but their advantages tend to be mostly at the micro level and the hard stuff tends to be at the macro level.

I honestly think that the advantages of FP for concurrency will turn out to be relatively minor and that FP is more interesting as a means of improving code reuse and reducing bug counts. I'm not convinced that the current crop of FP languages are a win in those respects either though, taken as a whole.


Well, yeah. There's no silver bullet. But it's much easier to start lopping off branches from the tree if there are no unmanaged side effects.

Programming languages of the future need to enforce thread safety and mutation semantics as well as they do type safety. Functional programming is a step in that direction.

Nobody's necessarily claiming that a concurrent Clojure/Erlang/Haskell app is faster than concurrent C++/Java one, but they're definitely safer and easier to write.


I wonder if the kind of concurrency people have been focused on in these kinds of conversations is really going to turn out to be that important. It seems to me like a lot of the really cpu-intensive problems people are trying to solve are way beyond the scale of a single machine - the kinds of problems you need a big hadoop-style farm to tackle. How many apps are there left that really need maximum throughput in a shared memory architecture?


"When people speak of concurrency in functional languages, they don't mean that each function executes in its own thread"

Erlang does do that, more or less, although Erlang processes are much lighter weight than what we usually think of as a "process" or "thread".


As an added note, I'm not aware of anyone doing this yet, but it would be really cool to have a VM that did JIT-like analysis of purely functional code as it runs to determine optimal points for thread segregation.


Really? Can you post some profiling data?


It may be true that FP does make concurrency easier, but I don't think this has been demonstrated to be generally true yet

Perhaps not generally true, but I think MapReduce and LINQ are two prominent examples of how a "functional programming-like" model lends itself to easy parallelization and distribution.


And there are also enough 'prominent examples' for impure imperative languages. For instance, OpenMP makes parallelizing some loops in C/C++ a walk in the park, and I have parallelized some of my programs by adding only a few pragmas.

The 'FP makes concurrency easier' is a often-used selling point, but I think the jury is still out. First of all, many functional languages are impure, and do not have this advantage in the same manner that e.g. Haskell has. Second, purity can be an expensive trade-off due to the copying involved. For lots of things (e.g. fast linear algebra) you'll still want to work in an impure world.

I think a better selling point of some functional languages is clarity. For instance, some class of problems can be solved very elegantly in Haskell and ML using algebraic data types, pattern matching, etc. But then again, some other classes of problems can be solved elegantly in Prolog.


And there are also enough 'prominent examples' for impure imperative languages. For instance, OpenMP makes parallelizing some loops in C/C++ a walk in the park, and I have parallelized some of my programs by adding only a few pragmas.

I'm curious -- were the programs that were easily parallelized with OpenMP largely data parallel to begin with? I haven't used OpenMP extensively, but I'd suspect that the ease of parallelizing a program with OpenMP probably varies inversely with the amount of explicit coordination/synchronization/update of shared state that the program requires.


Mostly, yes. This particular program evaluates effectiveness of features given an existing log-linear model. So, you can evaluate the effectiveness of features in parallel. For each feature, you can also partition the training data, process the the data in parallel, and apply a reduction step[1].

But 'map' in MapReduce is also a typical data-parallel task.

[1] In practice, there is a trade-off: the vectors are usually so large for the average training set, that you do not really want to copy them for memory-efficiency, so the mapping and reduction are interleaved, requiring some locking.


I don't think you should claim "demonstrable" and "future" in the same sentence. "Theoretical" or even "promising", perhaps. The most performance intensive problems in the world, when they have competition, are very much still solved in C and C++.


You're quite right about the juxtaposition of "demonstrable" and "future". I should have said functional programming has "already" demonstrated an advantage in producing robust and understandable concurrent programs, which will continue to be relevant in our multicore future. Really, there's nothing "theoretical" about that fact.

To your second point, I made no claims that C and C++ are not used to solve performance intensive problems. I'm sure C and C++ (or Assembly, for that matter) can be applied to solve any number of problems, if that's one's calling.


Well, what's it worth if you are doing (real-world) number crunching, and your program turns out to be one or two orders of magnitude slower? For instance, after implementing some machine learning software in Scala, I ended up rewriting it in C++, because it was so slow (IIRC the Scala version was 50x slower). The only way you can get down to 'a couple of times' slower is by writing Scala as Java with a slightly different syntax. And since the program does many repeated matrix calculations in a loop, parallelizing the C++ version was done in half an hour (mostly testing where lock contention kills the advantage of parallelization).

Yes, I do realize that there are more applications of multicore processing than number crunching ;).


I should have said functional programming has "already" demonstrated an advantage in producing robust and understandable concurrent programs

Examples of this other than Erlang?


Functional programming eliminates mutable objects, and mutable objects are (at a certain scale and in certain scopes) the new spaghetti code. I have worked with too many projects where twiddling the attributes of distant (global/static/inherited/etc.) things was necessary to get anything done, and it's obnoxious. It's too many indirections.

With functional languages and "dumb" data you don't have to guess about what your data can do. You just do what you want with it.


If it gets added to SPOJ (https://www.spoj.pl/) I'll give it another shot. The JVM is just a frustrating platform when it comes to experimenting with new languages.




Join us for AI Startup School this June 16-17 in San Francisco!

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

Search: