ABCL – Common Lisp on the JVM
common-lisp.net
common-lisp.net
https://abcl.org/svn/tags/1.6.0/CHANGES
As an "old" I learned LISP in college but have never had the opportunity to use it in my career. Still on my todo list!
For a little more money they serve the furniture to your house and ensemble it.
Lisp is like a wood and metal shop. It may take a little more time to become proficient with the basic tools, but once you do, anything is possible. You don't hear Lisp programmers complain they can't do X with Y, and you don't hear builders complain they don't have the right piece to attach X to Y. If you don't have one sitting around, you take a few minutes and make one.
When I make my own language, I'll make sure to make macro calls as clumsy and hideous as possible to discourage their unexpanded use. I'll also make the whole language available at compile time but without syntax manipulation (a la Zig) to make most macros unnecessary.
So no, Lisp is far from "the language to end all languages" or whatever it is you smug Lithp weenies imagine it to be.
[0] https://www.teamten.com/lawrence/writings/the_language_squin...
Sounds like Rust beat you to it.
Syntax is highly subjective, and funny that you mention Smalltalk, as I had a hard time selling that to some developer friends of mine because the method based syntax really put them off.
I also prefer statically typed languages, at least in the context of professional work with developers with various degrees of expertise contributing to the codebase. Then again, if I have to work in a dynamic language, I definitely take something image based with great tooling and feedback loop such as Pharo or LispWorks over Python or Ruby any day of the week.
Lisp generally favors flexibility, easy code generation/transformation, code as simple data structures, extensibility... that's attractive and useful for some.
> I claim that this squint test is important, and that languages should deliberately make different constructs look different.
For your example, you just happened to pick a programming language you already know well. If this is a beneficial goal, why pick that particular point on the spectrum? Java and Lisp aren't the only games in town. It would be a remarkable coincidence if the language you already know were the optimal point.
COBOL's constructs look even more distinct from each other. A COBOL programmer probably thinks your Java methods all look the same despite having completely different calling conventions. After all, COBOL was definitely designed for "us good ole' humans".
(defun foo (x)
(declare (type fixnum x))
(1- x))
If you don't specify them, types all default to T.Just this from 2009: https://news.ycombinator.com/item?id=930514
and a bit from 2017: https://news.ycombinator.com/item?id=14605334
public final class Cons extends LispObject
{
public LispObject car;
public LispObject cdr;
}
I would have thought it would provide that abstraction to the programmer but use another representation internally. Chasing pointers like this on modern hardware is surely crazy?> In computer science CDR coding is a compressed data representation for Lisp linked lists. It was developed and patented by the MIT Artificial Intelligence Laboratory, and implemented in computer hardware in a number of Lisp machines derived from the MIT CADR.
> CDR coding is in fact a fairly general idea; whenever a data object A ends in a reference to another data structure B, we can instead place the structure B itself there, overlapping and running off the end of A. By doing this we free the space required by the reference, which can add up if done many times, and also improve locality of reference, enhancing performance on modern machines. The transformation is especially effective for the cons-based lists it was created for; we free about half of the space for each node we perform this transformation on.
(Consider that the detail of improper lists is enshrined in the language.)
As it turns out, arrays aren't actually used that much (except for strings of course) in CL code. Most lists are just a few elements long, and regular lists are perfect for that.
Arrays, struts, all other things are possible, but the things that make Lisp Lisp mean that you may get a list where repeatedly calling cdr may result in something that is not listp (cons or nil). And that’s weird. It enables some things that are wonderful, but I think the Lisps are practically unique in conflating pairs and list elements.
http://www.lispworks.com/documentation/HyperSpec/Body/c_sequ...
There are some problems with this design. The main motivations for it were:
* basic operations in Lisp are type specific, one wanted to have some generic operations and a generic sequence abstraction over lists and vectors
* the low-level data structures like conses, arrays, tables are not object-oriented and generic
* generic operations in a dynamically typed language are slower, since there is always a runtime dispatch necessary
* to remove runtime dispatch one can use type declarations (which are optional in Common Lisp) or a JIT compiler (which is not used in most implementations, they do AOT compilation)
* the language at the type of this design had no agreed OOP extension - CLOS came some years later -> sequences are non-extensible and don't support adding new sequence types
The design of this was later improved in languages like Dylan: see the Collections of Dylan
http://lispm.de/docs/prefix-dylan/book.annotated/ch12.html
Recently some CL implementations experiment with extensible sequences.
http://www.doc.gold.ac.uk/~mas01cr/papers/ilc2007/sequences-...
This is one of the reasons that Clojure wasn’t written to be backwards compatible with CL. Rich chose to implement all of his core functions on the first/rest abstraction instead, as explained in his Clojure for Lisp Programmers talk.
As such, they are required to hold any value or reference possible, and aren't exactly amenable to different format.
There is one technique which had somewhat large use, CDR-coding, based in the idea that you can tag a cell in a way that tells the system that the next field isn't a reference to a CONS cell, but the CAR of one, and thus linearize lists in memory. However, doing it fast requires a custom cpu so you can resolve this fast in transparent way, as well as it turned out to not give much benefit. However, widening gap between cpu and memory might make it attractive again...
http://www.gigamonkeys.com/book/collections.html
> Vectors are Common Lisp's basic integer-indexed collection, and they come in two flavors. Fixed-size vectors are a lot like arrays in a language such as Java: a thin veneer over a chunk of contiguous memory that holds the vector's elements.2 Resizable vectors, on the other hand, are more like arrays in Perl or Ruby, lists in Python, or the ArrayList class in Java: they abstract the actual storage, allowing the vector to grow and shrink as elements are added and removed.
Since lists in typical Lisp implementations are made with cons cells, some form of two element data structure is needed. Using Java objects has the drawback, that this is not the most efficient representation.
Good Lisp implementations typically make sure that the cons cell has very little overhead:
* cons cells are just objects made of two memory words without type tag. The tag is encoded in pointers to these cons cells.
* cons cells can directly encode some simple data like fixnum integers, characters, ...
* cons cells might be allocated in special memory regions and GCs might take special care
OTOH, more efficient low-level representations like CDR-coding, which allows some lists to be represented in vector like ways is mostly not used in current implementations, since it was not see worth the effort anymore - it was thought worth on older systems with much small main memories than we have today. Smaller main memories than the caches on a modern CPU.
True, especially considering that parametric polymorphism is done via "everything is a pointer" way (although I've heard something about introducing "value types" in Java in the future).
Also Common Lisp's pairs are heterogeneous, polymorphic by nature, so I doubt there could be any other solution but pointers.
For performant computations you would need unboxed arrays in Java, just as you would use SIMPLE-ARRAY in Common Lisp (which should be implemented efficiently in ABCL as well).
kawak - scheme for the JVM https://www.gnu.org/software/kawa/
bigloo is a scheme can compile to C. I think it can also make java class files with bindings https://www-sop.inria.fr/mimosa/fp/Bigloo/
(There is actually a very-incomplete Common Lisp implementation as well in Kawa, but the Kawa Scheme dialect is the main Kawa language.)
(Hoping to make an official Kawa 3.1 release by the end of the year - but no promises. Until then, use git HEAD.)
Ahh, HN - never change. Sorry I mean, Hacker News - never change. :)
Seems like we've had about 60 posts as Armed Bear: https://hn.algolia.com/?dateRange=all&page=0&prefix=true&que...
and 200 as ABCL: https://hn.algolia.com/?dateRange=all&page=0&prefix=false&qu...
https://en.wikipedia.org/wiki/Wojtek_(bear)
It seems it's the author's brand name for software, and is a pun on the US constitution's second amendment:
http://armedbear-j.sourceforge.net/
We may thus infer that you would arm bears because of the threat of armed bears. After all, to stop a bad bear with a gun, it takes a good bear with a gun.
I spent a lot of time learning and coding CL during the last decade. I love lots of things about the language. Overall, it's great it's true multiparadigm. Few languages achieve that.
However, the implementations are too fragmented which makes the standard quite stagnant. And libraries are falling a bit behind.
I love Clasp is putting CL on top of LLVM. I wish we could have something with the best ideas of Racket, Clojure and CL on the LLVM.
Clasp is nice, but SBCL is fast enough that it's mostly extraneous unless you really need to talk to c++ code.
There's a bit more description here: https://news.ycombinator.com/item?id=21550123
That said, there is Ferret which is Clojure-like, and compiles to c++: https://ferret-lang.org/
Racket is also lovely, and I hope that their port to Chez Scheme will enable alternative implementations, since more of Racket is now written in Racket rather than c.
As always, it depends on your application. For instance I decided recently that I would work my way through the cryptopals challenges, and opted to avoid Lisp since bit-twiddling is such a pain in that language.
I think at least it's hard to argue CL would be a bad choice in general, and it's certainly proved itself over the decades in many domains and circumstances... But there are always tradeoffs, and other languages can be better choices when circumstances push different ones.
A particular blog post that gets passed around (you may very well have seen it) is https://www.darkchestnut.com/2017/pragmatic-reasons-for-choo... It's just an example of the process, but it's still valid. His list of requirements might not be your list, or your weighting might be different. (It's been fun reading tweets from https://twitter.com/rainerjoswig this month just to appreciate how portable CL code is across CPU architectures and implementations and if you value that a lot why wouldn't you consider CL very highly; meanwhile others don't value portability and are fine with an effectively iOS-only language or whatever.)
I don't really follow your statement about implementations being fragmented --> stagnant standard. The standard is the standard, it's as immutable as C89. Or do you mean you're sad that there's unlikely to be a new revision to the standard that all the implementations will adopt, unlike C99 and beyond (which still isn't fully supported by all the big players)? That's understandable, but you probably used the portable libraries that offer the big things one might want from a new standard, so...
There are more modern Lisps which have a much better concurrent programming story — which is why after years of working in Common Lisp I switched to Clojure.
The other huge advantage of Clojure is ClojureScript: most of my business logic code these days compiles to both Clojure and ClojureScript, which is important for modern applications and lets me keep my line count low.
See my Quora answer (from several years ago, so some things have changed) for more on why I switched: https://www.quora.com/What-do-veteran-Lisp-programmers-think...
I would love to see a slightly more modern CL, but it's good enough to get work done, and it's still light-years ahead of everything else.