Clojure is interesting in a lot of ways. I've toyed with it a lot, but what actually keeps me from using it much is how tightly coupled it is with the JVM. I know this is its big selling point for a lot of people but for me personally I don't enjoy having to know Java's APIs and ecosystems to get things done.
Is anyone else out there like me who wishes there was a standalone clojure implementation that wasn't a hosted language? Add a modern package manager on top of that like cargo or mix and I would love to write new projects in it, because clojure itself is a very pleasant experience.
Since Clojure is advertised a lot whenever there's a Common Lisp story, let me do the reverse: give Common Lisp a look.
It's a member of the Lisp family that:
- has a lot of high quality, implementations on a lot of different platforms be they native or hosted,
- is multi-paradigm so it doesn't lock you into just functional programming, or just object-oriented, etc.,
- can go from high-level code to fast compiled code (coming close to C++ speeds, like twice as slow.. not many high-level languages manage this),
- has been an ANSI standard for a long time and because of that:
- is a stable language: code from decades ago can be run without much (or no) porting. A while ago code from the early 1970's (or was it the 1960's) was made to run relatively easily, although I cannot find the link,
- is still a joy to program in, it brings together features that have been popping up in other languages but only in CL they feel so seamless,
- has a really nice development environment in Emacs + Slime (if you can stomach Emacs),
- has IMHO a nice and helpful community,
- has a great history, you'll come across almost any aspect of software & computer history when diving into CL.
The CL community has always been hotly debated and is usually negatively depicted on HN. I've never found it to be too bad, although it has attracted it fair share of trolls in the past.
In the spirit of highlighting other, non-Clojure, lisps to look at, I'll mention Racket.
Compared to Clojure:
- Not hosted (on JVM)
- Similar disposition on nudging you toward functional programming
- Less syntactic sugar (some of Clojure's sugar I find nice, but is divisive for some)
- Older
Compared to CL:
- One canonical implementation. This is good (consistency) and bad (choice, variety)
- More biased toward functional programming than CL
- People seem to think Racket's macros are more powerful than CL's, but I'm no macro-master
- Package management (raco) feels much more pleasant, subjectively, to me.
- Develop in Emacs or DrRacket; the latter being a pretty decent IDE for newcomers and others who'd haven't seen the true light of Emacs.
- Newer, feels newer
I started carving off small chunks of time a few years ago to try and hear the music of the spheres everyone talks about with lisps. I started with CL, then tried Clojure, and have mainly been dabbling in Racket these days. Subjectively, Racket has been the best beginner experience by far. As for hearing the music of the spheres, I'm still waiting.
EDIT: I forgot Rackjure! Racket is also a framework for building new languages (languages that are compatible with Racket, generally). Rackjure adds some of the Clojure-isms to Racket and seems to be used by a number of packages
Also, Typed Racket is another such variant of Racket that uses types for safety and performance reasons.
I'd say SBCL and CCL, but CL implementations are not like Schemes where there are huge incompatibilites and practically you have to target a certain compiler. With CL the compiler-specific stuff are very-rare and small in number, so most of the time you should be fine on any compiler with ongoing development.
Windows I'd do Lispworks or Allegro (both commercial lisps), although rumor has it SBCL for windows has gotten much better. Admittedly my last experience doing anything on windows was probably ~5-6 years ago.
Great thing is, the language is standard, so generally you can just pick one and start messing around.
lispworks actually looks very good to build in house Line Of Business applications
but the cost and price, really stand in the way of it being used in a greenfield/side project, where you work on something new without necessarily having your management approval, and then present it to them once .. it works
Clojure is interesting in a lot of ways. I've toyed with it a lot, but what actually keeps me from using it much is how tightly coupled it is with the JVM.
Clojure the language's coupling with the JVM is actually rather loose, precisely because it's hosted. However, Clojure the ecosystem is definitely coupled. However, I think this only rears its head when you need to incorporate a library and deploy. Once you set up your CI environment, I don't see this as being that big a deal that often.
Add a modern package manager on top of that like cargo or mix and I would love to write new projects in it, because clojure itself is a very pleasant experience.
There are elements of the Clojure design philosophy that are likely to keep it in the realm of "hosted language" for some time to come. That said, with the advent of self-hosted ClojureScript, there is no reason that you need be tied to the JVM just to use Clojure. In some regards, I see the ClojureScript community growing at an even faster clip than the parent language (though Clojure does have a large head-start).
> what actually keeps me from using it much is how tightly coupled it is with the JVM
I'm curious: where do you actually see that coupling?
I find that I barely notice the JVM in practice. There is the main function, sure, but otherwise I rarely use the Java APIs myself. What I do notice is the fantastic runtime with state-of-the-art garbage collection, something I've learned to appreciated after spending years with various Common Lisp implementations.
> I find that I barely notice the JVM in practice.
slow startup time, difficult dumping/loading images, difficult AOT native compilation, overly complex loading of code (-> custom class loaders), no TCO, no late binding for functions, host numerics shines through, delegation of functionality to the host environment using host language constructs, no resumeable condition system, jvm stack traces, error messages displaying JVM details, ...
I'm curious how you avoid the Java APIs since Clojure uses uses parts of the Java standard library for things like strings and dates rather than implementing a Clojure wrapper. Are there good Clojure libraries to use? It's been a while since I looked.
As for the APIs, I almost never use anything from Java directly (well, maybe except for Thread/sleep?). I use libraries like clj-time. Mind you, I'm not actively going out of my way to avoid the Java APIs, it's just that I don't encounter them that often in practice.
Regarding being a hosted language... that was it's intent. Use one of the best run-times available, with a better language. Granted once you design the language to be hosted, it can find other hosts as we see in ClojureScript.
With ClojureScript you end up relying on Google Closure Compiler as much as you rely on Java with plain Clojure.
It's true that being a hosted language is one of the goals of Clojure, but it's also true that being a hosted language is a non-feature (at best) for some people, including GP and me :)
How is Clojure 'designed' to be hosted? What is the design there, other than just leaving out functionality and delegating it to the host environment?
Other languages which weren't 'designed to be hosted' can't be hosted? Hmm, I was under the impression that the JVM hosts a lot of standard languages, for example Scheme dialects and Common Lisp.
The main advantage of keeping Clojure hosted is in being able to leverage the host ecosystem. It's simply not practical to implement an ecosystem comparable to the JVM or Node from scratch, especially for a niche language.
mainly because the CLs aren't clojure i.e. AFAIK don't use persistent data structures, and don't focus on robust concurrency primitives, don't have STM, etc...
But if there is a CL out there that does all that I'd give it a try tonight :)
You could try LFE[1] instead if what you want is concurrency, but it still is a hosted language, the only difference being that it relies on Erlang instead of Java ecosystem.
Lisp (what is a Common Lisp "flavor"? Racket is Scheme) has answers to all... Of course the benefit of Clojure baking those things in is you can rely on them in other people's programs, but still idiomatic Lisp seems to do an ok job managing state, especially compared to other languages. Plus its other features that Clojure lacks might make the tradeoff worth it.
Racket is not Scheme (anymore). Racket is a Lisp-1 with lots of different features and "batteries included" stdlib. It's a "descendant of Scheme".
Worth taking a look into definitely, but it doesn't have STM and "persistent data structures" which jfaucett seems to want. It does have solid concurrency and parallelism primitives, though.
Is anyone else out there like me who wishes there was a standalone clojure implementation that wasn't a hosted language? Add a modern package manager on top of that like cargo or mix and I would love to write new projects in it, because clojure itself is a very pleasant experience.