10 ms·
Why Clojure?
- mattwilliams 16y agoBob's Railsconf 2010 talk, "Twenty-Five Zeros", is also worth a watch if you enjoyed this post of his. http://www.youtube.com/watch?v=mslMLp5bQD0 http://www.youtube.com/watch?v=mslMLp5bQD0
- bitsai 16y agoExcellent. Since picking up (and falling in love with) Clojure a few months ago, I've had multiple "Why Clojure?" discussions with friends and co-workers. This post is short, sweet, and hits all the points I've tried to make (poorly) to others. Saving it now as ammunition for the next "Why Clojure?" discussion :)
- edanm 16y agoNot sure I'll have time to check out Clojure any time soon, but this post convinced me I want to read SICP. Despite hearing great things about it, my impression was always that it was much better for beginners, and wouldn't teach me that much. Sounds like I was wrong.
- zsouthboy 16y agoThe entire book is available on their website: http://mitpress.mit.edu/sicp/ http://mitpress.mit.edu/sicp/ Wanted a deadtree version to read at my leisure, but at $70 I think I'll read the HTML version. EDIT: found a PDF version: http://www.scribd.com/doc/15556326/Structure-and-Interpretation-of-Computer-Programs-SICP http://www.scribd.com/doc/15556326/Structure-and-Interpretat...
- atuladhar 16y agoThere are used copies available on Amazon (and elsewhere too, I'm sure) for about $40. Recycle, guys!
- alf 16y agoepub version: http://github.com/downloads/ieure/sicp/sicp.epub http://github.com/downloads/ieure/sicp/sicp.epub
- zsouthboy 16y agoThank you very much, was looking for a version for ebook reading.
- herdrick 16y ago...any time a Clojure programmer want's to change the state of a variable, they must do so using the same kind of transaction management as they would use for a database. Not a good thing. The word 'must' is the glaring red flag.
- herdrick 16y agoIt's not totally true, either; there are other ways to do state in Clojure. But none of them simply let the programmer, you know, change the state of a variable.
- lukev 16y agoSure they do. Thread-local vars behave pretty much like regular variables. Atoms also get you uncoordinated state.
- herdrick 16y agoOK, thanks for the tip about atoms. I hadn't dug into the var/atom/ref/agent docs. I should have before commenting. What I was looking for can be done with atoms, and is made more like traditional lisp mutation by defining a "st!" (or maybe "zet!" is a better name). (defn st! [atm v] (swap! atm (fn [_] v))) Now making ordinary lisp clojures is reasonable: (def fns (let [c (atom 0)] {:add (fn [x] (st! c (+ @c x))) :mlt (fn [x] (st! c (* @c x)))})) > ((get fns :add) 3) 3 > ((get fns :add) 3) 6 > ((get fns :mlt) -5) -30 Though I sure could do without the calls to 'atom' and @. Referencing and dereferencing is for C programmers. Maybe using swap! directly is better after all. (def fns (let [c (atom 0)] {:add (fn [x] (swap! c #(+ % x))) :mlt (fn [x] (swap! c #(* % x)))}))
- prospero 16y agoThe function you're looking for is 'reset!'
- 16y ago
- Zak 16y agoGreat article overall, but it makes the same mistake as many other Clojure overviews: implying that STM is the only means of managing state. Clojure, in fact has four main ways to do state, one of which is a (thread-local) normal variable. Each is appropriate for a different sort of stateful operation; STM is the most complicated.
- Raphael_Amiard 16y agoIt is not a great article overall. It is well written, and conveys a lot of enthusiasm, but has no insightfull/new content in it. I've read every clojure news and article for six months, and this just basically rehashes every "I love clojure article" i ever read.
- Zak 16y agoIt's at least good for a short introduction - a "why you should be interested".
- bitsai 16y agoIf you've been devouring every bit of Clojure-related writing (which I've also been trying to do), then as swannodette said to you elsewhere on this page, you very well may not be the intended audience :)
- mitjak 16y agoWhat are some good articles on why X loves Clojure?
- jsmcgd 16y agoBecause it's so clean.
- limist 16y agoA more complete and detailed answer to this article's question is provided by the free Chapter 1 of Amit Rathore's book-in-progress, Clojure in Action: http://www.manning.com/rathore/ http://www.manning.com/rathore/ As Rathore puts it, Clojure's power is drawn from three mutually supportive design decisions: 1) it's a Lisp, 2) it's functional, and 3) it's on the JVM. Read Chapter 1, it's well written.
- mhd 16y agoI wish someone would take the compiler infrastructure of Go and would make native Clojure with it, with an easy access to C instead of Java. I need a good exit path from things like Java, not something to just ease the pain.
- bitdiddle 16y agoIf I recall correctly this was one of the goals of Guile, which is essentially Scheme, arguably cleaner than common lisp.
- mhd 16y agoI won't get into the CL vs. Scheme pissing contests, but if I remember correctly Guile was basically RMS' answer to Tcl, a language he didn't particularly like. And it was more intended to replace Emacs Lisp, while most of the infrastructure would still be written in C. Running on Hurd, of course.
- bitdiddle 16y agoThat sounds correct, but also embeddable and callable from C. It's unfortunate it didn't succeed in replacing elisp. Emacs would be even more awesome than it is today. I'd love to see the same thing done with Clojure and Go.
- mhd 16y agoI'd much rather have a proper, powerful Lisp than being forced to settle on alternate soft and hard layers. But the Common Lisp Emacs project never went anywhere.
- whyenot 16y agoFor anyone interest in Guile's history (and it is kind of interesting), it was born in the great Usenet Tcl War http://www.vanderburg.org/OldPages/Tcl/war/ http://www.vanderburg.org/OldPages/Tcl/war/ It was intended to be GNU's official extension language, but it has never really caught on. That's sort of a shame, because it's actually a pretty nifty scheme implementation.
- nkh 16y agoI agree with the article, and I have to admit I think Rich Hickey (creator of Clojure) is a brilliant man. If you check into his thoughts on programming you will find some very interesting arguments. His talk on state and identity: http://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hickey http://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hic... is awesome, and I can not recommend highly enough. If you want motivation for learning a lisp (Clojure is one) check out http://www.paulgraham.com/avg.html http://www.paulgraham.com/avg.html if you have not already done so. An awesome essay to re-read if you have not done so in a while. Edit: Fixed Link (thanks atuladhar)
- deleted 16y ago[deleted]
- jules 16y agoCan you explain the point he is making in "Are we there yet"? I have watched it but I didn't really get a different viewpoint on state and identity. That could be because I already had the same viewpoint, but I doubt that.
- nkh 16y agoThe text below is directly lifted from the Clojure site at: http://clojure.org/state http://clojure.org/state The article describes it more clearly and succinctly then I could. There is another way, and that is to separate identity and state (once again, indirection saves the day in programming). We need to move away from a notion of state as "the content of this memory block" to one of "the value currently associated with this identity". Thus an identity can be in different states at different times, but the state itself doesn't change. That is, an identity is not a state, an identity has a state. Exactly one state at any point in time. And that state is a true value, i.e. it never changes. If an identity appears to change, it is because it becomes associated with different state values over time. This is the Clojure model.
- jules 16y agoSo is he saying that you should not nest refs? i.e. you should not create a vector of refs and assign the vector to a ref. Because now the state itself can change.
- cageface 16y agoYou know, I really want to like Clojure, but so far I'm finding it a bit of a slog, for the following reasons: 1. stack traces are very hard to decipher 2. ubiquitous laziness can lead to some really subtle bugs 3. the syntax can be extremely obtuse, moreso than other lisps 4. the basic ADT is just a keyed map, which provides a lot of flexibility but also can make data modeling very opaque, even compared to other dynamic languages 5. immutable and recursive as a default takes a lot of getting used to. things I could dash out in minutes in ruby take me hours sometimes 6. other languages have caught up enough that Lisp macros are not as game changing as they might have been ten years ago I embarked on a project recently to explore machine learning algorithms, implementing them in both Scala and Clojure at the same time. I expected this to be an easy win for Clojure but, to my surprise, I'm much more productive in Scala, my code has fewer bugs, and I can refactor it much more aggressively. I realize that this isn't an either/or thing and it may be entirely my shortcomings at play here, but my instinct is that although Clojure is a superb lisp, it's still a lisp, and it's going to be a niche that most programmers won't choose to occupy.
- swannodette 16y ago1. Fair point 2. Mutable state can lead to really subtle bugs 3. Sure but no more than Haskell or any other terse FP lang, Scala included 4. defrecord works wonders. You get all the flexibility of a map with the context of an actual type 5. It takes me hours to do things in Ruby that I could dash out in Clojure. 6. Right. Quite a few people in the Clojure have come from Scala. So everyone is entitled to their own opinion.
- cageface 16y ago2. Mutable state can lead to really subtle bugs Absolutely, but these aren't ends of the same stick. You can have immutable but eager, which is simpler to model mentally a lot of the time, at least for me. Simon Peyton-Jones has said that perhaps Haskell should have made eager evaluation the default and I'm inclined to agree that lazy evaluation is very powerful but maybe not a good default. 3. Sure but no more than Haskell or any other terse FP lang, Scala included True, although the baseline for a lot of Clojure code is higher, IMO. 4. defrecord works wonders Maybe so. I haven't really gotten my head entirely around the options for datatypes in CLJ yet. 5. It takes me hours to do things in Ruby that I could dash out in Clojure. It's true. Clojure makes some things that are hard to do in other languages much easier. Programmers are different, so we shouldn't expect one set of tools to suit us all equally well.
- linuxhansl 16y agoI will be forever grateful, that my University taught Scheme/Lisp with this book (and others) as introduction to programming. While I have never used Lisp or Scheme in my professional life, that set of undergrad courses more or less defined my mindset when it comes to algorithms and their expression and has lasted to the present day (some 20 years later).
- dasil003 16y agoAgreed. I went to the University of Minnesota which modeled its curriculum after the MIT CS program. I was saddened to hear they were ditching Scheme for their intro class. I don't see why they felt the need to update to a more "modern" language. It's impossible for any language to ever more directly express the basic concepts of functions and recursion than lisp. Why muddy the waters with syntax?
- almost 16y agoAnyone have any recommendations for trying Clojure? I'm an Emacs user on Ubuntu and I'd like to try it out but there seems to be quite a lot of choice about how you do things I'm a bit lost. Any up to date blog posts on setting up Clojure and connecting Slime to it? The ones I've found are always slightly out of date (apparently starting swank from Emacs isn't the preferred way to do it anymore?)
- arete 16y agoYeah there are a bunch of different ways to start Clojure with a REPL and/or swank server running. Maven, Leiningen, and cake are all build tools that also do dependency management - great when you're working on a complex project but have some amount of setup overhead for their project descriptors. cljr is a different option that lets you start a REPL anywhere, with no project descriptor, and also takes care of setting up your JVM classpath with any dependencies you've installed via 'cljr install'. All of these tools encourage running the JVM outside of emacs, rather than as an inferior-lisp, and have some command line option that starts a swank server on a specified port. After that you can just do M-x slime-connect and get hacking as usual =)
- bitsai 16y agoSwank Clojure is a server that connects SLIME and Clojure projects. Its github page has instructions on installation and usage, hopefully that will serve as a good starting point: http://github.com/technomancy/swank-clojure http://github.com/technomancy/swank-clojure
- technomancy 16y agoI recommend the Clojure wiki: http://www.assembla.com/wiki/show/clojure/Getting_Started_with_Emacs http://www.assembla.com/wiki/show/clojure/Getting_Started_wi... If there is something that's not covered or linked to by that post, please submit a bug report to Swank-Clojure: http://github.com/technomancy/swank-clojure/issues http://github.com/technomancy/swank-clojure/issues There is a lot of bad out-of-date documentation out there, but I like to think the official docs are pretty serviceable; if they aren't please help point out how.
- dasil003 16y agoI've never more than dabbled in the functional programming world. I've been pretty happy professionally in Ruby for the last 5 years. However, if there's one thing that I learned, it's that unit testing is an invaluable sanity check but a poor substitute for mathematical rigor. I see my trajectory over the next 5 years to involve learning Haskell well enough to know the functional approach for a much wider set of problems, but then falling back to Clojure professionally because, you know, I gotta get shit done.
- jules 16y agoI'm eagerly awaiting the binary release of ClojureCLR.
- Raphael_Amiard 16y agoÎ really love clojure, but this article is not a good plaidoyer, for a lots of reasons, the first and most pregnant being the ability of the author to vastly traverse subject he is probably not an expert about. > Functional programming, of the kind shown in SICP, is a way to write code that does not manage the state of variables, and could therefore be partitioned to run in parallel on as many processors as you like This is kind of true, but totally misleading, because very few tasks are actually easily paralelizable this way. When you stumble on one, you know it, and replacing map with pmap certainly is a joyful exercise, but this kind of parallelization are easy to do in any languages. The hard parts are those when you need to access shared state across threads. The facilities that clojure provide in this respect, while innovative and enlightening , have benefits that largely remain to be proven. > languages like F# and Scala which have a complexity and "quirkiness" reminiscent of C++ Erm, sorry, what, F# reminiscent of C++, did you even try to read some code written in F# ? F# has one of the tersest syntax you're likely to find in any language. As an ML descendant it does already have a very clean syntax, and the addition of significant whitespace only adds to that. > You can write Clojure code that derives from Java classes and overrides Java methods. In short, if you can do it in Java, you can do it in Clojure. Yeah sure, but in practice, most people that says that didn't ever had to really handle a non trivial project with java interaction in it. I did. And frankly it can get ugly. It's good to have it, but ideally, all should be encapsulated in idiomatic clojure wrappers. While this is not that hard because java interaction is very well thought, it's a long and boring process, and when you're in the middle of a project and just needs some bit of functionnality that isn't in a clojure lib (and trust me there are still a lot of those), you tend to just use the java interop in place. And then you get back and read your code, and you cry. In short, this is just a rehashing of what you usually hear about clojure, but with no insight of real use. My (uninformed) guess, is that the author probably didn't use clojure a lot, and frankly, this kind of stereotyped talk gets old.
- swannodette 16y agoYour response is more misleading than the article: > but this kind of parallelization are easy to do in any languages. Not if you have a GIL. Even then the languages without that limitation do not make what pmap does ... easy. > [STM] have benefits that largely remain to be proven. I always find this statement to be misleading. STM has been shown to greatly benefit the correctness of concurrent programs, you're managing that less by hand. The only thing that seems to be unproven is whether the performance tradeoff is worth it. It'd be nice to see some numbers that show what you lose in X% of the performance vs removing X% the amount of locking code. > [Java interop] And frankly it can get ugly. It's good to have it, but ... Yet far less tedious and simpler than writing a C module, or a C library binding. If you're comparing against that, Clojure's Java interop story is damn heavenly. > In short, this is just a rehashing of what you usually hear about clojure, but with no insight of real use ... Perhaps for you and I. But there are a lot of people in this big wide world. Uncle Bob taps into a community that's quite different from the language enthusiast crowd of HN. Your viewpoint more myopic than the OP. Yet you get upvotes. Oh well.
- inodeman 16y agoHow does Clojure account for the JVM's lack or TCO? Does it do it in code and then compiles it? Does it add some special kind of goto before compiling it? Just curious.
- knodi 16y agoI don't think so I'll take erlang over clojure any way.
- c00p3r 16y agoonly when pg will use it.. =)
- c00p3r 16y agoHey, what's wrong? It is so cool and modern Lisp implementation which runs on even more cool and super-efficient JVM (who said Ernang?!), so, why not?! Let's port HN news app to Clojure and see how much users it can handle. Every one know that Jetty is so cool! ^_^
- kunley 16y agoI guess there's an established trend how one writes about switching to new language: it's usually a long blog post containing facts distilled by others, sometimes mixed with author's wishful thinking. All that because author probably feels a need to justify his decision. It's normal - we usually want to justify the reasons why we do stuff, esp. when the new way is time consuming. It's also great that the OP is willing to dive into new waters. But such article cannot be taken as an expertise, even for the reason that it's not from OP's experience (yet).
- sqrt17 16y ago> become enamored with a language that has roots that go back to 1957, i.e. Lisp? Duh. What does that punk think that the "60" in Algol 60 stands for? Y'know, the bondage and discipline languages also have an ancestry that goes pretty far back. And I'd choose C++ (or Java) over Algol just as I'd choose Clojure over Lisp1.5 any time.