This article does little to relieve my suspicions. It sounds like the Clojure newb experience is still a superset of the Java newb experience and the Lisp newb experience.
This article does little to relieve my suspicions. It sounds like the Clojure newb experience is still a superset of the Java newb experience and the Lisp newb experience.
1. Java the language? It has abominable syntax and execrable semantics. Clojure fixes this; interop makes even strongly Java-flavored code tolerable. With Clojure, even Swing sucks less.
2. The JVM? Honestly, the JVM is rather nice. Except for the startup time, it's refreshingly fast. With Clojure, you don't really need to restart the JVM very often.
3. Learning about the classpath? It's no worse than PYTHONPATH or GEM_PATH, and far more self-contained by default. This makes deployment much easier. Yes, you have to understand it up-front, but what is difficult about it? It's a list of libraries your app depends on. Clojure is one of those libraries. Unless you need to compile your Clojure code into .class files, that's it.
4. Ant? It's a poorly-designed monstrosity with horrific XML syntax. Don't use it. You don't need it.
5. Maven? Yes, it's a beast, and unfortunately, you need it. Luckily, the latest version of Leiningen wraps it very nicely, so you don't need to learn the details. You also don't need to look at its XML. You just make a project.clj file, put in your dependencies, and run "lein repl".
I don't want "alternatives" to Ant and Maven and Swing. I do not want to have to know what Ant, Maven, or Swing are. If they are so terrible why are they still around? Can't we throw them away?
Well, no. We can't. Java is mature. You cannot throw anything away because existing libraries and codebases have dependencies on the old stuff. And you cannot throw away the existing libraries and codebases because they are why you are using Java in the first place; the language's maturity is its strength, perhaps its only remaining strength now that other languages are targeting the JVM. So you can only bolt more stuff on. Which just makes the whole edifice even larger.
If Clojure is forever tied to Java then I don't think it will ever be friendly for newbs, because I don't think Java is very friendly for newbs. ;) And if Clojure is nearly independent of Java -- and some of the comments here give me renewed hope that this is the case -- my advice would be to forget about advertising it to newbs for the time being. Get the Java out. Get it all out. Until you can write a book, akin to the Pickaxe book for Ruby, which teaches a newbie programmer all about Clojure and never mentions Java at all. Then sell me that book.
There is of course Clojure CLR http://wiki.github.com/richhickey/clojure-clr/ which is clojure but on the CLR. And there are fundamental differences due to the underlying types (but this should change with clojure-in-clojure) and you're dealing with .net interop instead of java.
But the fundamental issue you bring up is that you can't do a production-ready tour based purely on clojure, and some of that is most likely due to the pragmatic nature of clojure - why write a complete web server when you can just provide a wrapper for jetty? I do think these will come in time, but they haven't had the chance to be as battle-tested as the java equivalents...
In any event, there are things that could and should simply be scrapped. I dont' see why maven is an integral part of the Java platform for instance. Maven is actually a very depressing example because it shows that the complexity culture of Java isn't limited to the bureaucratic enterprise types who gave us J2EE.
Part of it is that Unix has a rather different philosophy. Part of it is that Unix seems to be better designed.
But I think the deeper answer is: I'm ready and waiting to develop an allergy to POSIX, if and when a pragmatic alternative appears. There is plenty of fuel for its funeral pyre: Where do you think I honed my own platform-griping skills? By reading The Unix Haters Handbook, which is really old by now.
But the difference between Java and Unix is that there are alternatives to Java. I'm sufficiently pragmatic that, if compelled to solve a problem with nothing but a roll of barbed wire, I'll learn all about barbed wire. And if I didn't have alternative means to solve my problems I'd probably try to love Java as well.
Which Java features and libraries do you need to learn how to use (even if you never need to use them) to get started in Clojure?
I ask this as someone who is completely unfamiliar with Clojure, not to be snarky. But from everything I've read, it has always sounded to me like you could get started in Clojure without knowing anything more about the Java environment other than the fact that your code is running of a JVM.
I want to learn clojure, I don't really grok Java, and I'm not sure where to start - I don't have a clear explanation of how my clojure project fits into the JVM and how to build everything.
I wish examples would start without the repl, and instead write a simple "Hello world", turn it into a jar, and then expand on that, and then introduce the concept of the repl for iterative programming.
A clear explanation of where Clojure libraries sit in relation to Java libraries would help too.....
Yes it is worse. ruby is far easier to start with.
$ gem install json
$ irb
ruby-1.9.1-p378 > require 'rubygems'
=> false
ruby-1.9.1-p378 > require 'json'
=> true
ruby-1.9.1-p378 > JSON.parse({'1' => '2'}.to_json)
=> {"1"=>"2"} $ lein new myproj
Created new project in: myproj
$ cd myproj
$ lein deps
[copy] Copying 2 files to myproj/lib
$ lein repl
Clojure 1.1.0
user=> (use 'clojure.contrib.json.read 'clojure.contrib.json.write)
nil
user=> (read-json (json-str {"1" "2"}))
{"1" "2"}
I admit I cheated a bit: clojure-contrib comes with a JSON parser, and lein automatically includes a dependency on clojure-contrib. If I needed a different library, I'd have edited project.clj to include the dependency.http://www.ruby-lang.org/en/libraries/
It's amazing that you get voted up when you are clearly avoiding my point. Show an example without cheating! What if I wanted to talk to mysql instead of using json. My ruby example would be the same. gem instal ...; irb; require; use it
It's amazing that you get voted up when you clearly did not read my post. I wrote: "If I needed a different library, I'd have edited project.clj to include the dependency." Let me explain that in detail:
lein generates the following default project.clj:
(defproject myproj "1.0.0-SNAPSHOT"
:dependencies [[org.clojure/clojure "1.1.0"]
[org.clojure/clojure-contrib "1.1.0"]])
Then you change it to: (defproject myproj "1.0.0-SNAPSHOT"
:dependencies [[org.clojure/clojure "1.1.0"]
[org.clojure/clojure-contrib "1.1.0"]
[mysql/mysql-connector-java "5.1.13"]])
To wit: you add a dependency by including it in the :dependencies vector. For example, Berkeley DB JE would be [com.sleepycat/je "4.0.92"]. Then you run "lein deps", which takes care of the rest.I hope you aren't arguing that editing a text file to include a dependency is too difficult, so I'll address your other point: the Clojure site does not mention Leiningen. There's actually a good reason for it: it is not a core necessity for using the language; you don't have to use Leiningen to use Clojure. If you understand the classpath, you don't really need it. Leiningen is a convenience, not a necessity of life.
I'll readily agree that an overview of available development aids would make for a nice addition to clojure.org. No definitive "Beginner's Guide to Programming in Clojure" exists. It would ideally explain how to get started at the REPL, how to use SLIME and swank-clojure to work with Emacs, and how to use VimClojure to work with vi, how to handle packaging, and how to deal with dependencies. It would also explain why and how someone might want to use Ant, Maven, Ivy, Leiningen, and the clojars.org repository. I'm sure that someone will write this guide some day soon.
You said that clojure is as easy as ruby for a noob. The simple fact is that it isn't, and you've essentially admitted as much.
It assumes the lib is in a maven rep
Gems assumes that the gem is available in a Gem repository. I see no practical difference.
it assumes use of lien [sic]
"rubygems" is a separate package from MRI in Ubuntu. Standard or not, you have to install it. You also have to install Leiningen. With time, Leiningen or a tool like it will become a de-facto standard. Your original post strongly implied that no good tools exist for Clojure package management. This is false, and I refuted this claim.
maven is a beast
Yes. I wrote that in my original post; I'm glad you at least read that part. Leiningen uses Maven repositories and dependency resolution under the hood, yes. My example, however, does not use Maven at all. Most projects which use Leiningen to manage dependencies do not need to worry about Maven's intricacies at all.
You said that clojure is as easy as ruby for a noob.
Nowhere in any post did I say that Clojure the language is as easy as Ruby. That would have been a meaningless statement.
I actually said that the Java classpath is no worse that PYTHONPATH or GEM_PATH. I meant exactly that. Dependency path management sucks in every environment I've ever seen. I said nothing at all about the Gem toolchain, or how well it helps mitigate the problem. It certainly has had several years to mature. That said, six month-old Leiningen is decently close to the simplicity that Gems provides.
Hm, I can't figure you out. Your statement is missing the point. I don't know if you see that point and are cherry picking on purpose or if you don't know both ecosystems. I've done a lot of ruby, a lot of java, and a fair amount of clojure. I frequently run into very common java libs that are not in a maven repo. It's a common occurrence. I can't think of any significant ruby lib that isn't in a gem repo. The two situations are not equivalent.
"Nowhere in any post did I say that Clojure the language is as easy as Ruby."
Again, this is literally correct, but I feel you've implied it. You're like the Karl Rove of comp sci. The original comment was complaining that the clojure noob experience appeared painful. You then said that the java classpath was no worse than gem_path.
This is both wrong (the need for class loaders is one example of why, and my highlighting of the ease of use of gems is another), but it's also clearly implying that using libs in clojure is as easy for a noob as it is in ruby land. You can claim that you weren't implying that, but if that's the case then your reply was meaningless. Again, this is Karl Rove style hair splitting on your part.
Let me be clear then. The noob experience in ruby is much better than in clojure. Do you disagree? I've taken your statements as implying that, but you claim to have never said it explicitly, so now I'm asking you outright.
After using both, the noob experience in Ruby is better than in Clojure. I've had cases where more "advanced" library/package management was easier in Clojure (really, Maven) due to system local vs. project local package lookup. It's entirely possible that says more about my knowledge on the subject than anything else.
Oddly you don't find him foolish for the FUD comment, just me for responding to it.
This is particularly ironic because it's a cultural norm in the Ruby community to launch lots and lots of short-lived ruby processes to run your tests, while in Lisp-land it's much more common to have very long-running repl sessions with uptimes often lasting in the days range.
A very simple example would be, let's say i want to open mp3 files and get their metadata, in python and in clojure, from a clean fresh ubuntu install : The python way of doing this would be:
$ apt-get install python-mutagen
$ python
>>> import mutagen
>>> (proceed)
For clojure, i developped a whole website http://www.radiozerozero.com with clojure, and i wouldn't even know exactly where to start. It's totally dependent on your installation, whether you use emacs + swank-clojure, if you integrate with leiningen or not, etc. Granted if you are already fluent with leiningen and you know which library you're looking for, it could be fast. But that's the point, you have to KNOW what to look for and to know how to use it. Every programmer knows how to use apt-get. And if ubuntu doesn't have it, there is easy-install, with every python library you could possibly think of.And honestly that's why i use linux for development. I don't have to care about those things.
Clojure is 10 times younger than python, and is very far from its level of stability, so it isn't a fair comparison. But when you start using clojure for real world projects, you'll have to do this comparison anyway.
I want to get started in a way that allows me to code and ship a hello world program in vim/notepad (ie in a n IDE independent fashion) from day zero. I can handle complexity and steep learning curves. I cannot handle not knowing and fully understanding whatever it is that the IDE is simplifying for me. And I don't want to be treated like a kid. Tell me how to get my hello world app into production the same way people shipping code in that language do as soon as possible. Is there any way for me to shed my java and lisp newbieness?
I do suggest picking a CL implementation with Readline support on the REPL and that usually means CLISP (http://www.clisp.org/) since it offers just that on the most platforms without a hassle. Then you can just edit "whatever.lisp" in your favourite editor and go through the command history for reloading, evalling, etc.
You can even skip the Readline support and pick other implementations and just start your script from the commandline. Just check the commandline options and CLISP even has #!/usr/bin/clisp (hashbang?) support.
So you can do a hello world in an IDE independent fashion. Hope that helps, mail me otherwise :-)
While Java code is generally not backwards compatible, it is typically forward-compatible. Most 1.4 programs run fine on JVM 6. In fact, I don't think I've ever seen one that doesn't — but I'll take your word that they exist. Personally, I've had more trouble with OS distributions shipping Python 2.3, 2.4, 2.5, 2.6, 2.7, and 3.0. I've also had trouble with Ruby 1.8.6, 1.8.7, and 1.9.x. JVM applications have generally just worked for me, regardless of platform version number.
In any case, applications being certified to run on a particular platform is hardly unique to Java. Any application whose vendor wants to reduce support load will be certified for a particular set of supported platforms. The situation is hardly better in C, with versioned .so objects and incompatible libc implementations.
Back on topic: I somehow doubt that these questions seriously turn off beginners thinking about learning Clojure.
I'm not a beginner programmer, but I avoid languages built on Java or .NET for these reasons, among others.
1. Clojure and Scala have nothing in common with regard to syntax or language semantics. Clojure is a parenthesized, fully-prefix notation dynamically-typed language from the Lisp family. Scala is an infix object-based language with a tremendously complex static type system.
2. Clojure stands on its own well enough. It has a maturing CLR implementation. In the future, it will be reimplemented in itself, which will permit simpler implementations on platforms such as, e.g., LLVM. Google for Clojure-in-Clojure.
3. You can write plenty of Clojure code without touching Java interoperability at all. It all depends on your problem domain. The code will not look anything like Java.
I've encountered several interesting languages over the years and they would all have been really nice and painless to use only if it wasn't for their lack of standard libraries that are just there.
Good set of standard tools and libraries are more important for a language's success than the language itself. The language has to be quite bad in order to drive programmers away from good libraries.
It's the Python problem: I know the shortcomings of Python quite well and I would happily use some other language instead except that Python has almost everything and despite the shortcomings of the language itself, Python is by far the fastest way to code a quick program to solve some random, particular problem.
I don't like Java but in the case of Clojure, the heavy machinery in JRE is a critical life-saver. Sure the Java side is ugly but at least it's there for Clojure.
The world is full of lisps that you can't do anything with. Clojure isn't one of them.
By the way, I completely agree with your main point here. When programming in Clojure, the availability of the Java libs is a very useful thing and that makes Clojure itself useable for me.
1) Scoping: there's no nested lexical scoping but only function and global scope. Makes many unnecessary workarounds necessary. 2) Read-only closures: you have to use the list hack, you can't just assign to any closed-over vars. 3) No do-while. Surprisingly often needed and thus irritating. 4) Some shortcomings aren't inherent in Python: while I would always like to prefer generators over lists and list comprehensions, and consider iterators elegant, I started considering iterators and itertools as cumbersome and old-fashioned right after I saw lazy sequences in action in Clojure. 5) Various function and method names that I just never, ever recall without first rethinking it again. Like dict.setdefault() which is actually dict.get() but with a default value. There's probably a dozen of these, and each time I just wonder: why is it so difficult to properly rename a few functions and gradually deprecate the old ones. 6) Last, the classical "there are no proper anonymous functions": lambda doesn't cut it and having to specifically name "anonymous" functions is cumbersome. Combined with scoping limitations, even using a generic name like "_" for local functions to be passed as arguments can cause trouble.
There used to be more but I have done less and less with Python recently and much more with Clojure, so the irks are fading.
Java libraries are so numerous and prevalent that I'm growing to prefer that kind of availability. Coming from Python, I'm not uncomfortable at all with Clojure's java library use.
It really doesn't feel like I'm interfacing with Java. It feels like I'm interfacing with a library designed with OOP. (No more verbose or unwieldy than necessary, given an object-oriented library.)
I don't know if this works on clojure, but Jruby and Groovy solved this partially, by making closures convert into such interfaces automatically. This however, does not solve the problem of the multiplication of classes.
import frog
frog.nibble()Comparing to other newcommer experiences (on linux os):
- Python: $ python (it is installed by default)
- Ruby: $ irb (it is installed by default with high probability, if not apt-get install ruby first)
- Java: download eclipse/netbeans/intellij, create new project, that's it.
Newcommers don't need build tools (let it be rake, rubygems, sbt, gradle, ant, maven, ivy, sake, leiningen, etc).
Of course, I agree that a getting started guide should pick one tool (possibly an open source one, but on this case all of them are open source), and guide you with it. Also, installing clojure with a repl client easy executable as irb/python's on linux package management systems (with the proper java dependencies) would help tremendously.