Being on top of the JVM is also one of the really nice things about Rhino (Mozilla's JVM based JavaScript interpreter: http://www.mozilla.org/rhino/). You have access to a zillion Java libraries. Taking two of their examples:
MySQL:
var conn = java.sql.DriverManager.getConnection("jdbc:mysql://"+host+"/"+db+"?user="+user+"&password="+password),
statement = conn.createStatement(),
resultset = statement.executeQuery("SELECT * FROM test");
// do stuff!
Jetty also works from Rhino:
var server = new Packages.org.mortbay.jetty.Server(8080);
server.setHandler(new Packages.org.mortbay.jetty.handler.AbstractHandler({
handle: function(target, request, response, dispatch){
// do stuff!
request.setHandled(true);
}
}));
server.start();
Obviously these could be wrapped up in more JavaScripty libraries, but all the hard work is done for you.
for more javascripty DB/server stuff http://dev.helma.org/ is (though relatively unknown) the premier (kinda) server side javascript library/framework,
There's a lot of monolithic server side JavaScript packages like Helma, but I want something more modular. Also, Helma is written in mostly Java I believe, rather than JavaScript, which is ok if you don't want to hack on Helma itself (or if you know and like Java), but I'd rather have an all (or at least mostly) JavaScript solution.
If you don't know, Rack/Jack are like bridges between webservers and Ruby/JavaScript web apps/frameworks, so framework/app devs don't need to worry about what server they're using, they just write to the Rack API. It also includes "middleware" which lets you pre and post process requests, which allows for neat things like intercepting some requests and serving static files, or gzipping responses, etc (in a server agnostic way)
Right now it only works with Rhino+Jetty but ideally it will work with a number of JavaScript interpreters and webservers.
It also includes a Sinatra-like routing framework (called Roundabout), which lets you define routes like
GET("/user/{username}", function() {
var user = this.wildcards["username"];
// do stuff!
return resulting_html;
}
Jack and Roundabout, combined with your other frameworks of choice, like ActiveRecord.js (http://activerecordjs.org/) make a pretty good solution, I think.
This guy is just rambling about CL and writing about his inability. I never had problems with SBCL on any machine, runs on my VPS, with threading, like a charm. Also, noone forced him to learn and use Emacs. There are Vim modes or CUPS for Eclipse. Destructive functions are the language's feature. If not sure, just use non-destructive. It's also not CL's fault he doesn't understand macros and can't use CL-WHO.
I like Clojure, but I like CL better. One guy's incompetence learning CL doesn't mean Clojure wins.
This attitude ("It's good enough for me, I don't care anymore about the learning curve's steepness, and I'm indifferent/enthused that my language is only accessible to a tiny minority") captures the CL spirit quite well. It also explains why you have to do so much wheel reinvention when you code in CL: those lower lifeform coders, who you openly despise, produce working, ready-to-use libs for most common tasks on JVM, not for CL dialects. Up to you to reimplement your superior libs in your superior language for your superior self.
CL is the perfect language for those who consider that development is not a social activity, and luckily for you, there are a couple of niches where this remains a sustainable delusion. For now. Meanwhile, Clojure carries on the Lisp heritage in the branch of software development that's not going to get extinct soon.
I don't have that attitude and I'm sorry if you encountered it (it's true the Lisp community could be friendlier, warmer to newcomers). However, what can a I (or any other Lisp programmer for that matter) do about the steep learning cure you mention? You have to try for yourself to learn the language, noone's going to do it for you.
Create a simple working installer for the major OS's that includes a useful IDE, Database connectivity to least one major database and a fully functional web server. Once this is working get some people to write a standard library for date / time functions, file IO, formatting output etc.
Never underestimate how difficult it is for a new user to setup a working environment.
It's Aquamacs combined with SBCL, some documentation, and some should-be-standard CL libraries. Double click and it immediately takes you into a REPL. Aquamacs recognizes most of the usual Mac key bindings, making the Emacs curve not quite so steep.
Lispbox is a good idea. Target Windows if you can. Setting up Clojure with Emacs on Windows involved a lot of steps and arcane stuff, but now there's a Clojure Box which makes things a lot more pleasant.
I've tried SBCL with the Eclipse plugin and it's been a huge PITA. IIRC, I couldn't get libraries to install when I finally gave up. It may have improved since, but I'm not sure. Of course the fact that many cool-sounding CL libraries had defunct websites and inaccessible CVS repos didn't exactly encourage me...
"Create a simple working installer for the major OS's that includes a useful IDE, Database connectivity to least one major database and a fully functional web server..."
In the comments there are instructions to get ASDF working, that I haven't tried yet.
I've tried to avoid Emacs, but it seems impossible. Lisp in a Box has a lot of problems, ABLE has still too many bugs and Corman lacks GUI programming without which I can't justify the price. CUSP also has too many bugs. So I'm surrendering and looking at Emacs.
I think CL is suitable for projects which are fluid and have a very few people working on them. Speaking from personal experience 1 person can get an awful lot done in CL, very quickly. Compared to any other scripting language. I've worked with CL, Python and Ruby. There are certain things that I think are impossible to write in Python.
I started by writing a domain-specific crawler which extracted certain information from a bunch of sites. But the sites I was crawling changed their design mid way. So I then ended up writing a program in CL, to which I describe the data that the site has. E.g. Name-of-city is "Edinburgh", Address is '15 Market Place, ED12', First-Movie-name is 'Bend it like Beckham', First-showing-date is '15 Jan', First-showing-time is '14:20'. The program then produces a function which when give a page from this website extracts this information in the form of an alist so that it can be pushed into the database.
Funnily enough the my site which shows this data runs on django.
Reddit was initially built on CMUCL on FreeBSD. Here is what Steve Huffman said on why they switched to python one weekend.
"The biggest trouble that plagued us was that we could never quite get Lisp reddit stable enough to sleep at night. There were weird threading issues that would bring the site to its knees a couple times a day and required constant monitoring."
I used CMUCL a bit, and SBCL almost never. Does SBCL really deliver on what it set out to do? Is it better, faster, more portable? As far as I know, the Windows port never matured.
Which of the two do people recommend using?
SBCL set out to make a version of CMUCL that was easier to build and maintain. I'm pretty sure that was delivered.
But of course that's not of much interest to the average user. I think SBCL is in general faster, is developed more actively, has more features that are relevant in the modern world (eg. lose a Motif interface, gain native threads), and currently runs on more platforms than CMUCL does.
My impression is that most people using CMUCL are ones who started using it 10 years ago and are comfortable with it, new users would tend to go with SBCL. But I'm biased, so it's quite possible that there are real and substantial reasons to prefer CMUCL.
I was subscribed to SBCL list some months ago. I could see that Windows port was quickly progressing. "Never matured" suggest a project that was tried and later abandoned. It seems more of an ongoing effort. Versions are still being created regularly. I would try in a few months.
As did I. In my case, the problem was running it on a VPS that had no user-visible swap, no way to add swap space and possibly some other memory-related oddities that I don't remember. The workaround ended up being to limit SBCL's memory usage with --dynamic-space-size.
Noone's. The point is it's not a valid argument. The sameway the author had problems deploying SBCL on his machine, I could have problems deploying JVM on mine.
I'm going to have to disagree with you here. You rarely hear about people having issues getting the JVM set up on a random machine. On the other hand, deployment of SBCL is a complaint you hear somewhat regularly from people using shared hosting.
It's not necessarily a fault of SBCL, as much as it is a function of Java's popularity. But to say they equally share deployment problems seems a bit misguided to me.
Yeah, you are probably right. Because of Java's popularity and high demand, hosting providers have to be Java-ready and nowadays, it's not a problem.
However, it seems I've been living in a cave. Besides the Reddit case, I haven't heard (or at least can't remember) about problems running a CL environment. Can people who had this problem please reply - what disto, what implementation, what was the issue?
The use case was a final class project, where the instructor needed to be able to run the final version of the program just by executing a script in an unpacked tar file. Couldn't get SBCL to run with the limited time I spent on it. Got CMUCL to run, but not in a way that could be deployed in a self installing manner. Punted and used Java (was easier to work with team members that way, too).
I've had a lot of issues with JVM in a cheap hosting with Virtuozzo (a VPS). I assume people that are using Java choose a provider that gives it preinstalled.
This might be a good experiment, but the examples seem a bit flimsy to me.
For example - Whilst it may well be better from his experience, Timestamp has always been an anomaly in Java (it doesn't necessarily play nicely with Date)....
Equally I've never found browsing the filesystem that superb in Java - in fact the whole FileFilter, FilenameFilter thing can be quite clunky to use... It's one area where I've never felt more than a smidgen away from C (even moreso now with the NIO library).
So - maybe better, certainly not perfect - Either way they didn't on the weight of it seem killer arguments.
I'm going to make a different kind of statement here. Something that I've learnt from my CL experience.
When I think about solving a problem by writing new software, I ask myself, is a run of a mill problem like a website which serves data, or making use of a bunch of libraries to do something. Then use rails/django, I use django/python.
If I don't know what the solution will look like and I don't think I'm going to need existing libraries. I'll use CL everytime.
It is common to have Apache as your static web server to serve images/css/js files and use modules such as mod_rewrite or mod_jk to route to your dynamic context. It seems like his dynamic content server is down (could be the jetty server he was referring to), hence the 503 error code.
Clojure is a Lisp, so you get all the usual things like first class functions and macros. Clojure leans toward FP philosophically, so all the built in data structures are immutable. Concurrency support is generally very good, and it has some useful syntax sugar for vectors and maps.
I prefer Clojure over all the other Lisps I've tried, but YMMV.
Good. Only thing missing in Clojure seems OOP. But I can live without that.
Hope Clojure doesn't push the FP thing too far. Pure functional languages are evil. In broad sense, pure anything in evil. Look what Java turned into trying to be a pure (or too much of an) object oriented language.
It’s multi paradigm that wins. Giving programmers freedom on how he wants to code any specific set of problem.
It's pretty realist, it even has a doseq especially for side-effects iterations. It's not that it forces you to be FP (it can't, you can always run java methods), it's that it makes the advantages obvious and lets you decide.
It is my first contact with FP, but what I find incredibly cool is the way the data structures are transparently persistent. If it's true this is a rarity in functional languages, I can't imagine using another one.
I'm curious, what do you mean by "transparently persistent"? Do you mean that you can serialize anything (and so persist it as a file or what have you)?
Let's say you have a map, and you change a value in it. Being a functional programming language, and the map being an immutable structure, you end up with two maps: the old and the new. Now, the cool part is every data-structure in clojure is designed _not_ to do this by copying the whole thing. You'll have two maps who share everything except the changed value. Same with collections, sets, trees etc. The work under the hood must be impressive...
Another nice thing (for me at least, coming from imperative programming) is there is a better difference between a variable and a value. A variable is a placeholder, and a value is ... well, a value. In clojure you treat them separately. A better explanation: http://clojure.org/state
Persistent in this case means that if FOO has value '((2 3) 4) and someone does (CONS 1 FOO) => '(1 (2 3) 4); the value of FOO does not change, but the new list shares its structure.
I'm just surprised that (it seems) you can do statement-based code in lisp. I thought it all had to be expressions. This feels like cheating. BTW: I can see that progn/do syntactically produce expressions, but the value of all but the last one are thrown away - similar to python in that respect. This seems against the spirit of expressions.
This is a common misconception. You are thinking of pure functional programming, not Lisp. Certainly a lot of Lisp programmers, myself included, prefer functional programming. Scheme, especially, leans toward functional programming. Haskell, not Lisp, is rightly known for embracing functional to the exclusion of all other paradigms.
What really stands out about Lisp is support for ALL paradigms, even those that haven't yet been invented. Lisp is an extensible language, that can be changed to fit your needs. Features that would require language extensions in other programming languages can be implemented as ordinary libraries in Lisp. Lisp was the language that allowed experimentation with new paradigms like functional programming, object-oriented programming, and logic programming long before more specialized languages (Haskell, Smalltalk, Prolog) were created to provide specific support for these paradigms.
I agree except that Clojure is specifically intended to be used functional, and not as OO. Clojure is not pure FP as it does allow state changes (in a controlled way), but that's an acknowledgement that state changes are useful and purity can be, I'll say, difficult. The way Java's OO embraces state changes is not the same principle, and makes things more difficult. OO style is possible in Clojure, but that's not what the language is meant for.
Sure, they're represented as objects in the JVM, and you can access this via refection; but they're not treated as objects in Java's syntax. I'd argue that OOP is a property of a language's syntax, rather than how it is internally represented.
In a trivial setup it's pretty easy to get the jvm up and running, but making a good cached deploy of apache httpd fronting tomcat and a database server isn't very easy. It's not very easy to set up a server with rails either (easier these days but still a pain if you're a noob). I'm not sure how easy something deploys is critical for the value of a platform. Developers should understand how stuff are deployed but it's not necessary that they know how to do it correctly, nor should every developer deploy their own applications. (I mean, it doesn't hurt if they know how to do it, but it's better that developers spend their main time developing not minding the server farms).
PLT scheme is primarily used for education. Pedagogy is (or at least was) the project's central goal.
Clojure is a general purpose project. It is not specifically competing for that space.
I'm sure that the average student can get up and running with DrScheme/PLT faster than with Clojure, but I doubt anyone is going to write an angry article about that.
See, that's the common misconception with PLT. While it was built for education, it's really a nice full featured system for any use. Just use something other than the "Beginning Student" language.
I have to agree. I know CL quite well, and decided to have a look at scheme last week. I wrote a small (but useful) program with PLT and was rather impressed by the amount of library code available. Distributing the program as a small stand-alone executable to a friend was also incredibly simple. Also, I particularly liked the module system and wish CL had something similar.
Clojure can be as fast as Java on benchmark-type code using type hints, Java interop and unchecked math. Idiomatic Clojure code will be slower on benchmarks. Operations on persistent data structures are slower than mutation. Reflection takes time.
Back in the real world, Clojure actually does pretty well for itself. As an example, it seems to be fairly common to generate collections of various types and then only use part of them. In Clojure, most of the time those collections would be lazy, saving computations every time the whole thing isn't needed. Also, using clojure.parallel, many operations can be parallelized trivially. I got a 50% speedup running a genetic algorithm on a dual-core machine just by changing a sort to psort.
Of course, hand-optimized Java may still be faster, but Clojure makes it easier.
"Yes it [Common Lisp] does [look bloated]. It has at least 4 different ways to loop, 4 different types of arguments to functions, 5 or 6 different lets (functions, macros, let* , normal let, ...), 3 or 4 different kinds of variables (with no unifying underlying theme), and at least 3 different flow models (the nested lists, tagbodies, loops with returns, etc...). That is exactly the same problem with C++. Instead of finding unifying abstractions which give the same functionality with 1 idea, they have chosen to add in multiple specific quick fixes to the language. They have chosen to amend the language with a thousand small changes, each suited to its own little use case, and have ended up with a monster of a standard that takes up 15 megabytes in 2300 files with 110,000 hyperlinks. Thats 15 mega bytes mostly of text.
Scheme is a lot better but its going the way of CL, slowly but surely."
MySQL:
Jetty also works from Rhino: Obviously these could be wrapped up in more JavaScripty libraries, but all the hard work is done for you.