4 ms·
I've recently been using Clojure more and more, including introducing it for a few nascent projects at work. I haven't been this excited about a new language si
by jballanc 14y ago
I've recently been using Clojure more and more, including introducing it for a few nascent projects at work. I haven't been this excited about a new language since Ruby in 2005.
Plenty has been written on its technical merits, but there is one aspect of Clojure that I don't think enough people pay attention to: the community! 4Clojure is just one example. The #clojure IRC channel is another. The Clojure community today feels like the Ruby community did back in 2005: hackers having fun and getting work done at the same time.
You owe it to yourself to give it a chance...
- jonathansizz 14y ago4Clojure looks great .. what are some of the other stand-out community sites for learning and working with Clojure?
- ludicast 14y agoThis is awesome too, if a lot shorter: clojurekoans.herokuapp.com
- evilduck 14y agoI'm pretty much totally ignorant about Clojure in practice. One part I love about Ruby is being able to drop into an irb/pry session nearly instantly or run the Rails console and test out code and ideas interactively and being able to quickly restart the dev server if configs change. JRuby has always been appealing to me but it's kind of annoying to use for development due to the JVM startup time. I used to do Java development full time and had the same annoyance with needing the compilation/restart step to see changes. Does Clojure address this problem or are there workarounds (like Guard/Spork for testing in Rails)? Is there anything fundamentally different from JRuby that would alleviate the slow restarts, or am I simply thinking about the problem wrong?
- jballanc 14y agoThe Clojure community just recently put its full weight behind nREPL. You can run nREPL from Leiningen outside of a project directory, much like IRB. To be honest, I've never noticed the JVM startup time... But there is another way! Clojure inherits the concepts of SLIME/SWANK from the world of LISP. Essentially, since functions (not objects) are the top-level constructs in Clojure, you can redefine functions at any time while your program is running, and everything will "magically" start using the new definition. So, the typical way one develops in Clojure is to start a SWANK or nREPL server, then load their program files into this server. At that point, you can run any single function or if you're writing a web app, for example, you can run the function that starts the web server, hit a URL, edit a function, re-evaluate, reload the web site and immediately see the results. ClojureScript One is one example of how this can be taken advantage of. You can see a demo of it here: http://vimeo.com/35153207 http://vimeo.com/35153207
- habitue 14y ago"Essentially, since functions (not objects) are the top-level constructs in Clojure, you can redefine functions at any time while your program is running, and everything will "magically" start using the new definition. " This isn't exactly correct. It's not because clojure has first class functions that you get this behavior, but because clojure has late binding: http://en.wikipedia.org/wiki/Late_binding http://en.wikipedia.org/wiki/Late_binding
- jballanc 14y agoTrue, but Ruby also has late binding. Ruby also has open classes, so you could (in theory) do something very close to SLIME with Ruby. The problem is, Ruby also has singleton classes and singleton methods, so there's no guarantee that a change made in code and evaluated in the runtime will have the desired effect. Actually, Clojure has a similar problem with defonce, but in practice I've found that Clojure works much better with the SLIME development model than Ruby does.
- banister 14y agoJust curious but why does singleton classes/singleton methods in Ruby make it "so there's no guarantee that a change made in code and evaluated in the runtime will have the desired effect" ?
- jballanc 14y agoWell, a trivial example: class Foo def bar puts "Hello from Foo" end end a = Foo.new def a.bar puts "Hello from a special Foo" end Now, even if you change the definition of "bar" in Foo's class definition, "a" will still have it's own version. This might not seem like a big deal, but as you do more metaprogramming with Ruby, more examples like this pop up.
- wreckimnaked 14y agoI use Nailgun[1] with vimclojure[2] and lein-tarsier[3] to avoid the JVM startup pain. You'll end up with a JVM instance (server) running all time and the possibility to evaluate code from many different clients like REPLs and the editor itself. Changes to the code just need to be evaluated again to override the previous function definitions. It ends up being a really fast workflow. 1: http://www.martiansoftware.com/nailgun/ http://www.martiansoftware.com/nailgun/ 2: http://www.vim.org/scripts/script.php?script_id=2501 http://www.vim.org/scripts/script.php?script_id=2501 3: https://github.com/sattvik/lein-tarsier https://github.com/sattvik/lein-tarsier
- vdm 14y agoDrip[1] takes a new approach to solving the same problem as Nailgun. 1. https://github.com/flatland/drip https://github.com/flatland/drip
- wreckimnaked 14y agoSeems nice. The only problem of using it instead of Nailgun for the Clojure development workflow is that starting a new instance of the JVM would mean to re-evaluate all the code, and not only the modified definitions.
- Dn_Ab 14y agoI have two questions about Clojure. (1) How fast is it compared to Java and is the method for speed based on rules or tricks? (2) Compared to other lists how natural is metaprogramming? I've recently started playing with Scheme and the feeling I get is not quite just functional programming. It feels closer to Symbolic Programming, the same feeling I get with the languages in Maxima or Axiom. There is an intersection with functional programming but the feeling I get doesn't cluster as close with Haskell, Ocaml or F#. And even if the occasion should rarely occur where the full extent of this power is needed, just knowing that code and execution and data and algorithms are basically indistinguishable results in an incredible mindshift in style. I haven't seen anything comparable till I started to wrap my mind around genetics + DNA. So my question around all that rambling is, in clojure is the symbolic style on the counter, shelf or pantry?
- lkrubner 14y agoRegarding speed, you really need to read this essay that John Lawrence Aspden wrote, "Clojure Faster than Machine Code?" He walks through several experiments in which he figures out how to optimize Clojure for the JVM. Finally, he writes a macro that expands his code into code that adds type hints to all of the vars, and with the help of the type hints the JVM goes blazing fast. He concludes: " And so I wonder: This technique strikes me as very general, and very useful. All sorts of things can be represented as lookups in tables. This whole program took me one short day to write, and the whole time I was doing things that I've never done before, just going by intuition. Once you've got the hang of it, it's easy. I think that the program should be as fast as the equivalent java program would be, although I haven't got around to actually testing that, so I may have dropped the ball somewhere. In any case, it's probably possible to generate code like this that does run as fast as whatever the fastest Java implementation actually is. The JVM is widely thought to be around the same speed as native machine code or optimized C. I'm absolutely sure that I'm not able to write the equivalent program in Java, C, or assembler without code-generation. The code generation would be very very very much harder in Java, C or assembler. And so I wonder, is Clojure the fastest computer language in the world?" http://www.learningclojure.com/2010/09/clojure-faster-than-machine-code.html http://www.learningclojure.com/2010/09/clojure-faster-than-m...