Cloture: Clojure in Common Lisp
github.com
github.com
And ruricolist has written (and maintained/forked) some nice libraries. In particular his FXML is the modern successor to cxml and plays nice with xpath, etc...
https://github.com/clojure/clojure/blob/89fc0caa43811c7dfcb4...
Alternatively I could spend some time assessing rutils or some other fundamental extension library... I'd like, one day, for one of those to gain a good tutorial and a bigger mindshare in the community.
Quite handy, it turned out.
I thought about extending the reader to allow for clojuresque applicable dicts (racket allows for this quite easily), but I never got to it.
Beside the obvious: cloture is a parliamentary procedure to end debate on a subject, and I would like to end certain debates. Yes, Common Lisp is “modern.” Yes, Clojure is a Lisp.
While this doesn't actually explain why the person started the project itself, it does shed light on one possible explanation.
Some Java:
public class Main {
public int addTwoNumbers(int a, int b) {
return a + b;
}
}
Calling it from ABCL: (defun void-function (param)
(let* ((class (jclass "Main"))
(intclass (jclass "int"))
(method (jmethod class "addTwoNumbers" intclass intclass))
(result (jcall method param 2 4)))
(format "calling addTwoNumbers(2, 4): ~a~%" result)))
Calling it from Clojure: (defn f []
(prn "calling addTwoNumbers(2, 4): " (.addTwoNumbers (Main.) 2 4)))
Note that the Clojure version creates the object, and the ABCL version doesn't do that for you; you still need to instantiate a Main yourself. (require :jss)
(defun f()
(format t "calling addTwoNumbers(2, 4): ~A" (#"addTwoNumbers" 'Main 2 4))Clojure on the other hand compelled me enough to learn lisp and emacs.
I wish I had time for FSet work, but I just don't right now.
The author drank too much Kool aid or is probably still in his functional programming honeymoon phase so anything mutable is of course bad and odd.
On a more fundamental level, they also suffer more than sequences from the fact that common lisp has no well thought out concept of equality.
There was briefly an attempt by Raphael Amiard to compile Clojure to Lua, which could also test this theory, but it was never completed and I doubt anyone else feels like doing that much work for free:
That's fennel: https://github.com/bakpakin/Fennel
https://www.jwz.org/doc/cadt.html
Of course this same critique could have been leveled at Clojure from its outset, but Hickey has really stuck with it for the long haul and made Clojure a very good language in itself as well as just being a Lisp on the JVM (and it even has sort of an ecosystem, a rarity among Lisps and what made me interested). I thought a few times about writing my own language when I was younger, but I realized it's a life-consuming task, and not something you can just do. But I do wish the author the best.
I'd also like it to conform well enough to the JVM implementation that I could use my full-blown Lispy Clojure for development, and still deploy with confidence on the JVM Clojure.
Obviously, someone's going to want to know what I think is missing from Clojure, so following is a partial list. These are things I've been accustomed to relying on for decades now, and that I always miss keenly when working with Clojure.
Instant startup with my environment already customized to my specifications.
Comprehensive reflection with full UI support. Support for inspecting absolutely everything in the runtime, with the ability to interactively edit everything you inspect.
The ability to reproduce my whole development environment and its entire dynamic runtime state on a different account or machine simply by copying over a file.
A real Lisp repl that can inspect and redefine everything in memory, save and restore the complete dynamic state of the running system, and deliver a finished executable from an expression typed at the repl. In short, anything you can do with the Lisp, you should be able to do from within the Lisp, by evaluating an s-expression at the repl.
Proper Lisp-style error-handling. The ability to catch any error or exception in an interactive breakloop, walk up and down the call stack, inspect and modify variables, types, and functions, and resume execution with the changed definitions just as if the pending function had been called with them in place originally.
People rightly complain about Clojure's atrocious error messages. They've gotten better, but they're still very far from what I expect in a Lisp error-handling system. I want the real thing: when something unexpected happens you get a proper Lisp-style interactive breakloop from which you can see and modify everything on the call stack and, indeed, everything in the running system, and you can tell the runtime where to resume execution from, either interactively or under program control.
A runtime designed with the understanding that you're going to be writing your application by changing it while it runs. Lisp and Smalltalk have had these features forever. Apple's Dylan and SK8 had them. It's disappointing that Clojure doesn't.
Common Lisp, for example, defines a standard protocol that enables you to redefine classes with the confidence that the Lisp will automatically update any existing instances to conform to the new definition. When Lisp can't figure out how to make things consistent, it doesn't quit or spew a dead stack trace; it starts a breakloop that captures the pending call stack. As I mentioned before, you can use the breakloop to inspect everything on the stack, make whatever changes are needed, and then resume computation with the changes in place.
I wish it were as easy to subsume foreign type systems into Clojure as it is in Common Lisp. Clojure's Java interop is good, but it's special. You have the nice Java interop, but you don't have a standard API for building your own equally-nice interops. Compare with Clozure Common Lisp's Cocoa interop. It's also good, but more importantly, it's built on common APIs (CLOS and the MOP) that you can use to make your own interop subsystems that are just as good.
To me, these are table stakes for a Lisp. I've already had them for decades. Working in Clojure means I have to give them up, and the whole time I'm missing them. A Lisp that doesn't know how to do them is only part of a toolbox. Whole drawers of essential tools are missing. I mean, sure, you can build apps with them. And you can build a house with stone knives and bearskins, but if you've used a proper toolbox before, you'll be missing it the whole time.
If there were a Clojure implementation with these features, then I wouldn't miss Common Lisp so much the whole time I'm working in Clojure. I probably wouldn't spend as much time looking forward to when I can get back to using a real Lisp. I'd get more done faster and with greater joy in my work.
I'm sort of hoping Cloture will turn out to be a step in the right direction.
Im interested to see how well this will fare. Personally, Im a little depressed that Clojure-in-Clojure has been postponed for nearly a decade. It would have made changing compiler targets much easier.
Is this an implementation detail or a common lisp idiom to work with case (in)sensitivity?
https://github.com/oracle/graal/blob/master/substratevm/LIMI...
Where SBCL just adds some compiled code, writes a memory dump out in a second. Then this can be run as a new SBCL with added code - it still includes the compiler, and all other stuff. One can also then add more code and write another image... The new image is just like the other one, just with more code and otherwise the usual feature set.
This includes the whole SBCL and my code, not just a static application with limited dynamic features.
Many Common Lisp systems have a way to write a snapshot of the developed environment, which then starts in subsecond.
Additionally some Common Lisps have ways to do application or shared library delivery, which can remove dynamic features, remove parts of the development tools, remove unused code/data, etc. This may be similar like doing heap dumps, but with added optimization phases.