Clojure's n00b attraction problem
gregslepak.posterous.com
gregslepak.posterous.com
> A true noob should probably install java, download clojure and clojure-contrib, run the repl, and stay there for couple 2-3 weeks. No IDE, no web app dev, just functional and concurrent programming with clojure in a REPL. They'll be much better off in the long run because they'll either give up (and save time) or learn something truly outside their comfort zone (and understand the benefit of getting setup for real development).
When teaching someone a programming language, your first goal should always be to get them to the point where they've made something real in a domain they understand. Then, they can bootstrap that domain knowledge, and its application within the new language, and use it to "grow into" the rest of the language.
The best thing for Clojure would be something that lets you write web-apps (or games, or visualizations like Processing...) in it two minutes after clicking "Download"—because those users would be able to say they've done something in Clojure, be able to say they're sure of their knowledge (because if they weren't, the program wouldn't have worked, would it?) and be able to proceed to learn more with confidence. The worst thing would be to download Clojure and be stuck at a REPL invoking (defproto) to overload String methods with no goal in sight—because that kind of knowledge doesn't stick, and won't get you anywhere.
Just telling, a lot of people got into python, because they wanted to solve a certain problem (I know of an RSS scraper and a state machine framework prototype), and these people just started with a book about python and NO knowledge and after around 3 days, they knew a large amount of python and were sold, because the problem was solved and the language 'felt very good'.
I think generally, programming language designers should stop assuming that their language is novel, or different or whatever and people will be clueless learning about the language.
If you know like Java, C#, Python or Ruby, NO object oriented language will present you with really large surprises (until you meet Javascript with prototypes, and things turn around a bit and common lisp with generic methods and things warp a bit, but still, the basic concepts behind the language are nothing surprisingly new, I still have my objects which receive objects and do things depending on the message receveid).
If you know something along ML, Haskell or some other functional language, it will be really, really hard to surprise you with a functional language. Cool, oCaml has references? Cool, Haskell has monads? That is true, those things might be a bit different, but the basic concepts of immutability, functions and recursion is all the same, no matter what happens.
So, tl;dr? You language is not novel, your language is not new, I have used a language which is similar to your language, I will just be bored if you throw me into Programming 101, because your language is new and I will probably just walk away.
Mastering the .NET class library took a lot longer, but that is a different issue, and I'm actually rather glad it's a separate issue (but that's a story for another day).
With Lisp and Python, I've tried to take a similar approach. Some of the PLT Scheme documentation -- excuse me, it's "Racket" now -- was very clean and concise. I also tried concurrently reading the R6RS spec, which was productive, though not quite as much as I wanted. Python, unfortunately, has full-programming-noob intros and a technical spec. The spec isn't bad, but it's difficult to parse down into the most important features. I scan through the tutorials, skipping most of the text evangelizing the language. That seems to work for now, but it's taken a lot more conscious effort on my behalf to stick to it.
For example, I started my journey into programmerdom with JavaScript. Going to C (strict C, not C++) was a major mind-f*, and I didn't make the transition well. When I went to Java, I became much more productive. Learning the finer details of how Java tracks references and performs parameter passing, I suddenly understood C a lot better. Once I knew C better, I realized a metric ton of flaws in my JavaScript. All because greater exposure to language informed my underlying assumptions about what language means. The jump from Java to C# enhanced my understanding of event-driven programming (merely because of how C# provides syntactical features for delegates separately from the class system). I then realized I understood WIN32 events in C a lot better. A similar experience followed my forays into F# (failed attempt into functional programming, but not unproductive), back into C#, into C++, back into Java (briefly), back into JavaScript (this time with the knowledge of first-class functions), and then into Scheme (finally a successful foray into functional programming).
A parallel can be drawn from almost any feature in one language to another feature or application of features in another. It's the essence of Turing completeness, we can emulate any system in any other system (yes, albeit not efficiently).
A summary of the problem is: the configurations people run are so diverse that it is hard to provide installation instructions that work for all, or even most, of them. As soon as someone wants something not covered by the simplest of tutorials, many of them will run into issues.
I think the only solution is documentation. The only thing that works is catalogueing all known problems people have encountered, so that others can easily find solutions to those problems. The largest problem of this solution is that n00bs need to understand their systems and they often don't.
Think of it like a school system: the required years of school (the problems that everyone has to deal with, starting off) should be streamlined and easily-digested, with a lot of thought and care put into the user experience. Secondary education (the problems that individuals have once they're doing something complicated and meaningful) is allowed to be more free-form, because the user now has a base of skills to fall back upon.
I picked up Ruby basics in a weekend of hacking around. I know there are still some things to figure out re: gems and big project management... but none feel insurmountable.
Python - same deal.
Clojure, on the other hand - has all this buzz on the net, but it's just that-much-more-complex to make even a seasoned language n00b a bit put-off. (if you don't have your head firmly around the java build process and basic librarires, it's hard to get past the repl in clojure)
BUT it is based on emacs, and unless you're familiar with emacs, its not going to be too friendly...
Then, if you want web-apps, you'll have to get your head around ring, compojure or some other library. If you want graphics, at this stage you are kind of limited to whatever java can provide, and there is no easy IDE inspector to show you what's available / defined at any given moment...
There are many ways to get around all of these, but they all seem to require a fair bit of digging around, google-fu and whatever else is needed to make it go.
Maybe what clojure needs is a simple executable wrapper that handles the java classpath requirements, provides a simple (but extendable) IDE, provides some common sample projects like a simple web app (blog), graphics (temp converter), maybe multi-threaded (the ants.clj example) all complete with good documentation.
I know that would have made my life a bit easier...
There are steps before that! The user's first concern is how to run the damn thing. If they can't get past this stage, they will give up and never return. The user should be able to download, install, and copy/paste/run "Hello, World!" with no bullshit. No IDEs, no configurations, no REPL. You have time later to sell all of that. A programmer who can't run from a file is tethered to your tutorial, even if they want to write more permanent code. Give them that freedom immediately, and give them a win immediately.
After they can actually run a program, then give an interesting example or two, and provide live links to up-to-date tutorials. It's irritating to see "official" links that are three versions out-of-date, and I see it too often. Examples should include a little bit of magic from the language, so the curious programmer thinks "Hm, that's not familiar. I wonder how that works!"
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.
That being said, I do believe the "noob experience" is improving, and the community Clojure fosters is inviting and welcoming to newbies, as far as I've seen.
I've begun work on a tutorial to get people up and running with Clojure, but I will be recommending Emacs in it. As someone in the comments on the blog noted, if someone's goal with Clojure is to crank out a web app in 24 hours, they've come to the wrong place. Emacs enriches the experience, and I truly don't think it is as daunting as it is often made out to be. Gaining basic productivity in Emacs, even if not excellent productivity, takes little time, and the benefits of using Emacs seem large to me.
Regardless, the sentiment expressed here is important to consider. There should be a sanctioned IDE for Clojure, and it shouldn't just be Emacs and clojure-mode.el + Lein, at least not to start. Along with clojure.jar, I'd like to see Leibke's clj script packaged and promoted. That way, like with python, irb and newlisp, you can download and immediately get started with a functional REPL to see if you like the language before investing the time in setting up the ultimate IDE.
And yes, documentation. Please, documentation. It's in the style of LISP to have little to none documentation in code, as the code should explain itself. And it certainly should, but a little exlanation here and there can only help to enlighten those not as familiar with the language and save the time of those in a hurry.
But now is an exciting tine for getting into Clojure. Don't let the initial challenge of getting into it deter you!
Nearly every Lisp data type and all special forms take docstrings; documentation that gets compiled into your code that can be queried at run time. Lisp was the model for online Unix manual pages; APROPOS and DOCUMENTATION and builtin Common Lisp functions. There is even a defacto commenting style for documenting code at various levels; file-wide, top-level form, and small inline documentation.
The typical "Lisp experience" is a fat abundant system that rivals its underlying OS and platform. It even has a function, ED, to invoke the builtin editor/IDE, and some Lisps even have that builtin.
I'd like to strongly encourage against that. Here's my story: take from it what you will.
2 years ago, I decided to get started with Lisp. I looked around, and the most "official" path seemed to be using "Lisp Box", which is Emacs based. I didn't have any experience with Emacs, but I did keep hearing about it, so I decided to jump in and learn it (I was, after all, in a learning mood).
Of course, learning Emacs isn't a one-day affair. Sure, I could learn enough to do some Lisp (and I did). But it feels like a waste. So I started to learn a bit more about Emacs. Then more. Eventually, I was spending so much energy learning Emacs, that I didn't have any time left to learn Lisp. To this day, I've never learned Lisp.
In contrast, with Python, I spent a day with the IDLE shell that comes packaged as part of Python. Then I moved on to working in files, with IDLE as an editor. Eventually, I moved on to looking for a good Python editor/IDE, a search I spent a lot of time on. But the point is, I didn't need to learn a completely new environment to use Python. Don't forget, a n00b only has so much time/energy to learn, you don't want them wasting it on the editor but on the language. The editor can always come later.
Oh no. I hope I do not come off as a troll but this is exactly why I never could get started with any of the lisps. I can't stand emacs or netbeans or eclipse. This a personal taste for me but a very strong one. They all just feel wrong to me. Associating a sanctioned ide with a language is a bad idea. It brings unnecessary baggage for a new user. By closely associating your language to an ide and by having every tutorial throw it in my face, your community is just creating an unnecessary entry barrier for me. Please consider making the tutorial ide independent.
This is the answer to so many of the concerns cited in this discussion, I'm shocked that it has not been more heavily cited in this thread.
I haven't used it yet, but from the documentation it looks brilliant. Dead simple package management and REPL tied together in a single command line tool. A noob should be able to go far with just this plus text editor of choice.
Indeed, if anyone complains about the noob experience in Clojure, it's probably a good sign that they don't use IRC. =)
The author complains that running Clojure per the simple instructions in the distribution is not a valid way to program, yet, then tears into the complexity of much more complex setups, which due to the fast-evolving nature of Clojure are often extremely fragile.
The command-line invocation of Clojure will work if you have a valid Java setup, and with the addition of jReadline, you have a decent, albeit bare-bones, environment for experimenting. Copy and pasting code and running it directly works, and once you figure out how to 'source' in a file, you can start building something modularized and significant.
I wrote about a 5000 line Clojure program, fairly early on, and ran development cross platform with just an SVN server at home on my mac, svn clients on mac and Windows, and notepad for Windows development, and TextMate on the mac. GUI design for Swing was done in NetBeans and could be loaded on the fly easily by Clojure.
Note the conspicuous absence of Vim, Emacs, Slime or any of the other fragile setups that people think they need.
Clojure has great facilities for modularization, and it's dead easy to use, but familiarity improves with practice in doing what actually happens instead of just pushing buttons in an IDE.
That's the really big "IF" that the article is trying to address, I think. If you already have your head firmly wrapped around java, then Clojure isn't a monster - but if you don't, you have to cover a lot of ground to actually produce production code with it.
My point is that I fail to see how adding Vim or Emacs or some other IDE or framework actually helps you get your head round Java.
It's only my opinion, but learning enough Java API to write serious Clojure programs involves hitting an O'Reilly reference, and having the Java class docs open in a web browser, with the absolute minimum of distractions from other sources.
It may be unique to me (hopefully not), but Clojure was a drop-in replacement for Perl in my sketching and prototyping workflow that I follow during planning and design. Clojure has access to all the Java APIs, and with pure Java goodies such as drivers for Oracle, SQLite, SQLServer, it's easy to write code that runs well across Mac, Windows and GNU/Linux. None of this stuff needs an IDE, since by and large, just dropping .class files into an appropriate folder is most of the battle in Java/Clojure.
Pity etherpad is gone now... so I can't retrieve my editing history, but there are a few clones there that do the same.
Seriously? Java comes with most modern operating systems and is easy to install on the remainders. The article is about getting a dev environment set up beyond the JDK.
It seems that the problems mentioned are common to all JVM languages (I was especially struck by similarities with JRuby, recently on HN).
Ideas: (1) look at other JVM languages. Copy their solutions. (2) someone develop a "JVM language support environment". It might include eg. a java server, so startup times disappear. (the JVM is damn fast, once it's going. And, kinda freaky to witness, it gets perceptibly faster, through JIT). Oracle might even include subsume it into Java, should it serve their business interest.
That being said, with a lot of the Clojure IDE plugins and build system reaching usable maturity, the n00b experience has gotten a lot better than when I started a year ago. So, keep up the good works, guys....
True fact: there aren't very many Windows users who are willing to help with portability issues. Of course there's a chicken and egg problem here to be sure, but if you'd like the situation to improve, you should volunteer.
(A great place to start would be by updating the .bat file that comes with Leiningen to work with version 1.2--hint, hint.)
I empathize with your pains, but you can't walk into a biker bar and ask for filet mignon.
Well, Windows users should switch, but failing that, they should be pleased...
Besides, most Windows devs are allergic to anything that doesn't come on an MSDN disc anyway.
It'd be wasted effort, and the communities are smart enough to know that.
(In some ways, the very expressiveness of LISP creates a this cacophony of ways to do things, but that's a post for another day....)
Clojure: 3 years old
PHP: 15
Java: 15
Ruby: 15
Python: 19
Objective-C: 24
I think the fact that there are so many coders that want to try Clojure despite its young age speaks to how compelling and powerful it is. The slick user experience will catch up soon.While the syntax and theory has been around for a long time, a language still needs its own libraries, build/package management software, editor integration, etc.
But Clojure already came with a lot of functionality because it could interface with Java, and therefore its vast collection of code.
But, Clojure and Java styles are very different from each other, so using Java libraries can be noticeably different from using Clojure libraries.
Your list suffers a little bit from selection bias. It doesn't include all the old languages that never caught on. There are of course many reasons why a language doesn't become popular and lack of good documentation and ease of getting started is probably not the most important one.
I mean, there's C++, the language that managed to become popular by doing everything wrong ;-)
In other words, since the very very first day of python, people could tell a new python user to grab that one very specific package from python.org and go ahead until he is able to judge the different implementations out there, which solves precisely the problem mentioned in the article.
Same goes to an extent for Java and PHP.
Most of the other points were, at best, just pointing out things you'd expect with a new language and new ecosystem. It takes time to polish things.
You can pry my preferred text editor from my cold dead hands, but not all developers think that way.
Someone like you goes "well, so what? I got trusty vi here. It might not be the ideal tool for the job, but it will work until I find something better". Others will go: Oh. I cannot use Y here. So, I need to finde another tool to develop Z. And since I have always used IDEs, this MUST be an IDE of course.
I'm unsure if I like this or not.
I'm all for making it as easy on the noob as possible but clojure will never be blub. It makes the hard problems easier but the price is that the easy problems are harder.
I don't think that Clojure isn't meant to be an easy language for newbies, like Java. Clojure is a master's tool, like Unix. Good tools require time to learn and for the user to develop a bond with them.
It's precisely the functional programming, multimethods, immutability, concurrency, macros, and sexprs that make up Clojure's value. There are enough blubs already.
- Edit code in plain Vim.
- Run Clojure from the command line.
I have a single directory where I download the appropriate jars. I ignore Ant, Maven, Leiningen and all that other fancy stuff.
Then I wanted to play with Compojure and think I got sucked into involving Leiningen (bleh). (Actually, I want to meet the person who named that project Leiningen and slap them with a small fish. What an annoying name to type and pronounce!)
Jokes just aren't as funny if you have to explain them: http://www.classicshorts.com/stories/lvta.html
That's where python, ruby and javascript clearly win over scheme and clojure. On the other side, C++ is weird. There exist a lot of "get started with C++" such as accelerated C++ but, in my experience, a true beginner won't understand it because the language is too complex.
And for first lines of code, you might try:
(map (fn [x] (+ 5 x)) [1 2 3])
which is equivalent to
(map #(+ 5 %1) [1 2 3])
Which oddly requires as much characters as Scala's:
List(1, 2, 3).map(_ +5)
Although I think Scala does some of this stuff better, there are still a lot of pain points for the newbie when it comes to different build systems, java toolchain, classpath, library dependencies, binary compatibility issues etc.
On the one hand it's great that tonnes of toolchain options already exist for Java which can be used with these languages. On the other hand, when coming from (say) the Ruby or Python world you just want and expect there to be one main widely-used/well-documented way to do basic things within a language's ecosystem, like installing libraries and so forth.
Rather than first having to figure out how the java world works, then make some arbitrary-seeming choices of java tools without much guidance, and then figure out how to work with the new JVM language on top of those.
It's about making sure this new crop of JVM languages feel like first-class citizens, rather than just add-ons for a java ecosystem which you're implicitly expected to know a lot about.
That said, however, when I moved from Maven to sbt, everything became a lot easier.
sbaz (their package management / repository system) was a bit of a disappointment, though, in that people aren't really using it (the last time I checked anyway).
And you end up having to learn maven anyway (or at least maven repositories?) in order to depend on other java or scala libraries that use it.
Minor nitpick, but there is a big difference between learning Maven vs learning how to use maven repositories.
http://github.com/relevance/labrepl
It's so good that I think the clojure website should be linking to it. Here's the summary from the above link:
Labrepl is an environment for exploring the Clojure language. It includes:
- a web application that presents a set of lab exercises with step-by-step instructions
- an interactive repl for working with the lab exercises
- solutions with passing tests
- up-to-date versions of Clojure, contrib, incanter, compojure and a bunch of other libraries to explore
See instructions below for getting started with NetBeans/Enclojure, Eclipse/Counterclockwise, Maven, Mac/Linux command line, Windows command line, IDEA/La Clojure, and Emacs.
A nice, compact hello world example would help. I didn't see any example on the parent (I'll admit I skimmed). A nice example of being able to something fairly complex in a clear, simple fashion would excite me.
The size of the Java hello world program made me nauseous every time I've looked at learning it.
There was a thread a while back about how much patience people doing BS activities. Not only do I have little patience with wasted, I tend to think that intelligence correlates with not wanting one's time wasted.
If you can show me a language which is clear and won't waste my time, I'll love. I love Ruby (though it's just too buggy to use for serious programming still).
Please provide an example of your case that Ruby is "just too buggy for serious programming".
thanks.
Maybe, "sloppy and ill-defined" - the only Ruby spec is the implementation of Ruby.
Maybe, "main implementation problematic" - the main Ruby VM never gives allocated memory back to the system - it garbage collects and keeps it for further allocation. That means that if you copy a 1 gig file, your Ruby instance allocates a gig and keeps it forever (one of the Twitter people described to me his horror at discovering this - two years ago!). That's why its standard to kill Ruby instances after a while in most large Rails installations.
Tell me those problems and problem like them are solved and I'll look at Ruby again. It's a beautiful language, the nicest syntax and approach I've seen.
#2 is an interesting issue. Is this true of all versions (jruby, rubinius included) or just the MRI?
I consider it best suited for people with extensive knowledge of the Java platform and at least good notions of FP, needing a way to write more powerful and concise code without throwing away a proven codebase or compromising performance.
Even if new to Clojure (or Lisp) I would not call these people n00bs.
The good thing about Clojure is that there are people who care about these things — see for example the leiningen and clj projects on github. Leiningen is already way beyond anything that was available for Common Lisp, for example.
There's hope.
And the number two best practice would be to get the novice to the point of writing and running their own "Hello World" program, in that language, as fast and as easily as possible.
Almost everything else is gravy.
But the problem is that clojure _strongly_ eschews object-oriented programming. But ActiveRecord and Django ORM are (or pretend to be) object-oriented. Therefore, there is a strong mismatch conceptually (e.g. http://stackoverflow.com/questions/3067261/how-does-one-mode...).
More than an IDE, there is a strong need to migrate _thinking_ from Rails/Django, etc. to Clojure.
His first complaint is that getting started with Clojure involves starting a REPL and that this is not how actual development is done. Well, no, it isn't. It is however, where you will spend most of your time. Not only that, but the most accessible documentation on both the Ruby and Python official sites mostly involve using a REPL. Clojure's only problem is that running the REPL is slightly more involved. Also, Clojure 1.1 is not already outdated and I'm not sure where the author got this idea. 1.2 will have some great features, but AFAIK will be completely backwards compatible. I'm not sure where a beginner would even learn about 1.2 without some serious internet trolling.
Next the author complains about how difficult obtaining Clojure is difficult. There is a "Download" link right on the clojure.org homepage that lists zip files for both 1.1 and 1.0, both of which include the source. This is less difficult than getting Python or Ruby, which involves downloading and installing a pre-compiled binary or compiling it from source. Also, the author complains about 1.2 not being available, even though 1.2 has not been publicized and is still in beta; true beginners probably don't know that 1.2 even exists.
The author complains about the fact that there are a whopping three choices for IDEs for Clojure, despite the fact that each of these IDEs also have plugins for Ruby, Python and PHP. There are no fewer IDE choices for these languages. If you ask most Rubyist which IDE you should use many of them will tell you TextMate, and editor that is neither free nor cross-platform. The author then brings up Xcode; well, of course every Objective-C developer uses Xcode, they don't have much choice. Clojure's myriad of IDEs is not a problem unique to Clojure.
Build systems, again, I don't think this problem is unique to Clojure. Where is the great documenation for Rake? Or Buildr? What build system do Pythonistas even use? Seriously, I've been using Python for a while now and I have no idea if there exists a canonical build tool. Comparing these platforms to the likes of Objective-C and .NET in terms of tool support is just unfair, in my opinion.
Like I said, I agree with the spirit of the post. Clojure is not an easy language to get into, but it has very little to do with the points the author made. Much of the cognitive load involved in getting started with Clojure has to do with the fact that it's a Lisp and most programmers are used to ALGOL syntax and Object Oriented semantics. Another thing to keep in mind is that Clojure is an incredibly young language. Much, much, much younger than Python, Ruby, PHP, Objective-C or even Scala. Taking into account Clojure's youth it's amazing that it's as far as it is.
The first hit on Google for setting up a Clojure dev environment on Ubuntu is incorrect.
[Edit: removed link]
Which parts did you find frustrating? Did you use ELPA? I ask because I've been using Clojure for so long now that I don't run into a lot of hurdles setting up new development environments.
http://stackoverflow.com/questions/1595418/emacs-behind-http...
Perhaps you were using Aquamacs? Aquamacs is a fork of Emacs that is not very well-supported since it's not cross-platform; it's impossible for people like me to test on. GNU Emacs is much more compatible: http://emacsformacosx.com
Getting started was, as I mentioned, frustrating though. Nearly all guides recommend the old way.
The #1 problem with people getting started with Clojure on Emacs is the huge number of blogs out there with "hey, I finally got Swank working; here's what worked for me" posts that are way out of date. The official documentation (http://github.com/technomancy/swank-clojure/blob/master/READ...) isn't stellar, but once people find it they generally get things figured out just fine.
$ script/repl
Clojure 1.2.0-master-SNAPSHOT
user=> '(println 1)
(println 1)
user=> (eval '(println 1))
1
nil
I don't understand what about this says "lisp code isn't a list itself"> and JVM isn't a Lisp machine in general
Well, neither's the x86, but we do what we can.
Btw, there was a link here to a blog-post from a jruby developer who argued that JVM is a crap for a dynamic languages (read: for anything except what it is) Why would you think it is perfect for a Lisp?
Do we need to start again about bad-by-design FFI, rudimentary and inefficient network and disk support, and so on?
Yes, it is well situated to some in-house development, but not for everything.
I know, some people believe it is good even for things like Cassandra, but I cannot imagine database system without things like efficient and low-level implementation of network layer (epoll/kuqueue support, tunable buffers, intellectual error handlers) and especially disk routines (O_DIRECT, proper caching and the like).
user=> (class '(println 1))
clojure.lang.PersistentList
A PersistentList is effectively a cons cell.> The pointers to functions and agruments, as is should be?
Effectively, yes. What would you expect to be able to do with this in a "real lisp" that you can't do in clojure?
> Btw, there was a link here to a blog-post from a jruby developer who argued that JVM is a crap for a dynamic languages (read: for anything except what it is) Why would you think it is perfect for a Lisp?
I don't. It is demonstrably good enough, though.
> <Further irrelevant JVM rantings>
Meh.
I can do it too - the widely used and popular implementation of an outdated, bureaucratic-designed concept which is situated well to simple and bureaucratic in-house application development and became bloated with badly-designed and poorly implemented so-called enterprise stuff which most people tent to reuse without thinking just because they heard (very good marketing) that everyone else did.
It have a fundamental problem being designed as an isolated from an OS blob (same as Flash, btw) which is proved to be dramatically inefficient for most of task other that very basic and general computation.
It was a complete failure as an in-browser technology, desktop-technology, and even server technology in the case of highly-loaded or low-latency systems. It is still in use because of almost parabolic increase in the x86 processors power and the same-curved decrease in the costs of CPUs and RAM. That is why projects like Cassandra are there - hardware is so fast and cheap that you can use even a bloated and crappy tools.
In the mobile segment - J2ME and Dalvik VM have no relations with JVM. ^_^