After a few more „experiments“ with Clojure, by all the benefits it brings, there are a few things I clearly have to object about it. Before I start – I have no deeper expieriences with Clojure, everything I say could be wrong or not substantiated. Comments are welcome!
One thing is, I like nil punning. Clojure has no nil punning. I was told that this is due to the fact that Clojure supports lazy lists, and therefore, the empty list means that there are no more elements to read, while „nil“ can mean something else. I dont know if there was another way to achieve this, but at least I like nil punning a lot, it makes code more readable, as soon as you got used to it. It would be a nice thing to have.
The Syntax has compulsory square brackets, commas and curly braces – I dont like this. It is good that distinct types of brackets are allowed, but it should be my own decision, which ones I use.
There could be a little more support for tail-recursion. The Documentation sais „Since Clojure uses the Java calling conventions, it cannot, and does not, make the same tail call optimization guarantees. Instead, it provides the recur special operator, which does constant-space recursive looping by rebinding and jumping to the nearest enclosing loop or function frame.“. But clojure is a functional language, it has no real setf- and setq-directives (only for the Java-Interface). I understand that it cannot rely on Java when resolviong tail-calls. loop and recur are easy and intuitive to use, and there is also a function called trampoline, with which you can implement tail-calls yourself, but I think, a language claiming to be functional could have a bit more… Like, providing tail-call-optimization if the programmer requests it – say by some flag, declaration, etc. – which breaks complete compatibility with the Java Calling Conventions, but makes code more readable and easier to produce.
Another thing is the Java-Interoperability, which is – as far as I see now – very static. Seems like its even more static than it could be realized with Java. There are functions „gen-class“ and „gen-interface“, but they seem only to do something if you compile the source they are in. And then, they are creating a static class, which you cannot load directly. Then there is the proxy-macro, which takes a classname as an argument, and can then override methods in that class, i.e. used for implementing interfaces. But proxy takes only class-names, you cannot load an own class (using a class-loader for example) into a java.lang.Class-Object and pass it to proxy.
There seems not to be any possibility to do something like this.
Well, on the other hand, Java itself has the possibility to load classes from Bytecode in a byte-Array, which the programmer can generate itself in any way he wants. And it has the possibility to compile sourcecode – theoretically directly from a source-string, without involving the underlying filesystem. Unfortunately, this seems to be very complicated. So I myself tried to do this using the underlying filesystem – it works. I can generate new Interfaces and Classes on runtime, and can load them – with pure Java. Google finds a lot of projects implementing something similar (so I spare you the details of my code). It could be quite some work to extend the Java-Interoperability of Clojure for runtime-generated Classes, and Interfaces – and some people will counter that this is slow (which is not an argument at all, because you can provide both, static and dynamic class-generation), and that one never needs this. Well, there seems not to be any simple way to generate JavaBeans, but some Java Libraries rely on this possibility. On the other hand – Clojure itself is very dynamic, and it should be possible to create an external library for this.
On the whole, I still like Clojure – even though not as much as I liked it when noticed about its Object-System. It is a step into the right direction, and it is very famous, even under non-lispers, as I noticed. There are drawbacks with every language. And Clojure is comparably young – lets wait what it will become…