Possible tip: sneak in ABCL when they're not looking. ABCL is a Common Lisp implementation for JVM, with (what seems like) relatively OK interop between Lisp and Java code.
The latest release (1.5) was earlier this month.
it's common lisp. if the language spec hasn't changed, and your code works, you don't really need to change the interpreter.
As for being a hard sell - my personal experience is that if you're in a position that allows you to choose your implementation language, in most cases you can choose Brainfuck and nobody will care. As an example, I introduced F#, Erlang, Elixir and a bit of Prolog to a Python shop that way: all that mattered in these cases was whether the code worked, and it did, so no one complained. The Erlang microservice actually outlived the project it was written for by a year and a half.
On the other hand (still, in my experience) if you're not in a position where you can choose your language you're basically screwed, and should stop trying to convince your team to switch to something else. You have almost no chance of succeeding and a high chance of disrupting teamwork by pushing your opinions on others.
So I was thinking about the former situation, where you have some degree of freedom of choice and can decide the language on technical merits alone.
The whole thread is about primarily Common Lisp; people who enjoy the design choices made by the CL standardization committee and subsequent evolution of the language's ecosystem would most likely want to know that there exists a proper CL implementation for JVM.
Well, it's definitely a Lisp; however, I don't think the "nice" qualifier fits here.
Clojure has a few interesting features which are well integrated with each other, but it also comes with a lot of opinionated choices one might not like. Another thing - not a language issue per-se - is that relying on Java ecosystem can be painful (and ClojureScript, fortunately finally bootstrapped a while back, is not quite the same language).
Personally, I feel that, in pursuit of simplicity, Clojure dropped a lot of useful features. As an example, in both CL and Racket, you have 2-3 times more ways of structuring your code than in Clojure. This is important, because different parts of a codebase benefit from different structuring mechanisms - and the more choice you have, the easier it is to find the right one. In Clojure, all you have are maps and defrecord, with the latter being almost never used.
Of course, you have macros to combat this, but then you're put in the shoes of language inventor and implementer, which is a lot more complexity than most programmers would like to fight just to be able to order the function definition the way they want.
To summarize: in my opinion, Clojure did some things right but then got locked into that single track and refused to incorporate additional features (and lessons learned) from other Lisps. So no, I don't think it's a "nice Lisp." OTOH, it may well be a good language, especially if your problem and domain are a good fit for it.
It's 'Lisp'-like where the basic primitive list processing has been replaced with a different higher-level data structure (persistent sequences) built on top of an alien infrastructure which leaks through everywhere and which was not developed for interactive programming (the JVM)... That was one of its original design decisions: being hosted on top of the JVM.
Given it's Lisp (CL in particular) that's "built with alien technology"™, I'd say Clojure is built on top of terran architecture, with the usual human stuff leaking everewyhere... ;).
What are those?
user=> (list 1 2 3)
(1 2 3)
user=> (list? (list 1 2 3))
true
user=> '(1 2 3)
(1 2 3)
user=> (list? '(1 2 3))
true
user=> (cons 1 '(2 3))
(1 2 3)
user=> (list? (cons 1 '(2 3)))
false
It might not be a big deal, but from a language design view I would expect the single most important external data structure representation in Lisp - a list - is not overloaded with different data structures, where basic operators give different results. I personally would also think that in Lisp the predicate list? is fundamental and returns true for everything which looks printed like a list.Common Lisp has a related problem for arrays: there are some attributes of arrays which have no printed representation. One will read an array back, but it might lack some features - like not having a fill-pointer. But atleast ARRAYP will still return true.
This seq/list thing might not be a big deal in practice, but it's another design wart. The language has in several places names, which are fundamental in Lisp and which mean something totally different now. Like 'atom'. Since the concept of a Lisp atom no longer applies - remember we have seqs, not linked conses - the name was reused to mean something different. atom used to mean (not (consp thing)) now it is something else.
Of course the meaning of (not (consp thing)) for atom is classical, but don't you think it's a bit weird? It always struck me that way. In a language where lists were the only composite data structure (i.e. not being a cons means being a number or a string or a symbol), it made sense, but that meaning degrades once you have vectors and hashtables. Those are no more deserving of the name 'atom' than lists are. Indeed if one indulges in the oxymoron of treating atomicity as a spectrum, vectors feel more atomic to me than lists while hashtables feel less atomic.
See: http://www-formal.stanford.edu/jmc/recursive/node4.html
(1 2 3)
isn't the printed representation of a list. It's just the printed representation of a sequence, which could be a list, a lazy seq, or others.I'm not a Clojure expert, but when I use it, it looks like everything that responds to seq? prints in brackets. And so I tend to think of a seq as the fundamental, most important data structure in the language, and think of a list of just one kind of seq. And following from that, the seq? predicate is fundamental and returns true for everything that prints like a seq - which includes lists.
So maybe this seq primacy means it would be more accurate to call Clojure "Lisp like" or "a Lisp descendant" rather than "a Lisp"? I'm not sure.
I like Clojure, I like CL, and I tend to use and enjoy them both without worrying too much about taxonomy. Having said that, it's totally fair and important to ask the questions you asked!
For me, though, the answers to those questions don't make me like or dislike Clojure or CL more or less relative to each other. They're both fun and useful, and I'm glad they both exist. :)
That isn't a complaint about Clojure at all, Clojure is a really cool language and does some things better than Lisp, but it's just not a Lisp, it's a Clojure. It borrows some syntax from Lisp in the same way that Java borrows some syntax from C, and it makes about as much sense to refer to Clojure as Lisp as it does to call Java C.
If you want to say that Clojure uses sexprs for source representation, say that; if you want to say that Clojure has dynamic typing and lexical closures (the latter of which most Lisps have not had), say that. Calling it "Lisp" to mean whatever handful of features that you personally think are the defining elements of Lisp doesn't aid clear discussion.
Clojurescript, which is nearly identical semantics to Clojure, also is quite a practical skill for front-end development.
It's important to note here though that this is a feature, not a bug. CL is a multi-paradigm and extremely pragmatic language.
1) I never said it was a bug. 2) Whether CL's multi-paradigm nature is an advantage or not is subjective.
Where do you live?