
CL21: An experimental project redesigning Common Lisp - phabian
http://cl21.org/
======
mark_l_watson
This looks cool enough but it would need a big community to really change the
common lisp landscape (in my opinion). I wonder how the lazy sequence support
stacks up to Clojure, Haskell, etc. support.

One difficulty with promoting a more modern layer to common lisp is that
Clojure is already such a productive and practical language. I have written a
few common lisp books, and remain a fan of the language, and an upgrade does
sound good.

I am curious to hear the opinions of the heavy hitters in the common lisp
world.

~~~
Immortalin
I can understand the reasons why people prefer to target the
CLR/JVM/LLVM/BEAM/Name-your-favorite-vm but I yearn for more compiled-to-
native-languages such as Golang. As attractive as partially-
compiled/interpretated languages are, I simply do not enjoy creating programs
in a language that can be decompiled to source so easily. We need more
languages that have decent performance instead of having to drop down to
pointer optimizing in C wherever we need some performance. A functional
Fortran would certainly be nice...

~~~
bmh100
By functional Fortran, do you mean like a "functional programming language" or
"more productive Fortran"? As one who has developed in Fortran before, I would
also like to see enhanced functional capabilities, as well as a more
productive way to write code. I have spent so much time on declaring variables
and function arguments over and over across subroutines that it becomes quite
a pain. To avoid writing many subroutine interfaces, I also tend to put
everything in a single module. My dream is to combine the expressiveness of
Lisp with the numerical performance and memory efficiency of Fortran and C.

~~~
phabian
What happened with Fortress, fortran like enchanced language Guy Steele was
developing with his team?

~~~
bmh100
I had not heard of Fortress before. It seems that Oracle's sponsorship of the
project ended in 2012. Guy Steele emphasizes the difficulty of implementing
Fortress's type system on virtual machines. [1]

[1]:
[https://blogs.oracle.com/projectfortress/entry/fortress_wrap...](https://blogs.oracle.com/projectfortress/entry/fortress_wrapping_up)

------
bachmeier
One of the things I don't like about Common Lisp is the unusual names. Just on
the basis of the linked page, CL21 doesn't fix that.

Take princ #"Hello, ${name}\n". Why not just use print like the rest of the
programming world. Okay, some languages use writeln, etc. But princ? Why not
print?

A little further down, we see while-let1. Why the number? If you want to call
it "Common Lisp in the 21st Century" you need to clean up the syntax.

~~~
agumonkey
As odd as it may seem, I ended up prefering car/cdr over anything else (except
when access to pattern matching and destructuring). I know first/rest,
head/tail or even fst/snd are clearer names, but car/cdr ended up as symbols
having precisely this meaning in LISP idioms (recursion over cons-cell based
lists).

My 1.5cents

~~~
jerf
As a non-Lisper, I can assure you beyond a shadow of a doubt that having "car"
& "cdr" show up in the first few sections of a tutorial is not something that
wins people over to Lisp.

I don't mean that _I_ don't understand it. I even know they come from
assembler instruction names. And they still look weird to me and still have no
meaning despite having read what the abbreviation expands to three or four
times.

You'd be far better off shipping "first" & "rest" and whispering to the old
hands that you're sure they know how to "fix" the problem in their code, than
presenting new people with car & cdr and then try to wedge an explanation into
a brain that just threw an exception and went "Wait, what?"

~~~
beeworker
Ah, but how would you easily access the number 6 out of the nested list '((((5
4 3 2 1) 6) 7) 8 9) without one of the cute compositions of "car" and "cdr"?
In this case, "cadaar". (Rhetorical question. "car" and "cdr" are neat for
their cute composition, but I would never inflict that on someone first
learning the language.)

~~~
chongli
One word: lenses.

~~~
Flow
And how would that look for this particular example?

~~~
chongli
Definitely not as terse but far more general, flexible and powerful. With car
and cdr you're restricted to working on cons cells while lenses are generic.

Some examples (from Haskell):

    
    
        >>> ((((5,4,3,2,1),6),7),8,9) & view (_1 . _1 . _2)
        6
        >>> ((((5,4,3,2,1),6),7),8,9) & (_1 . _1 . _2) .~ 4
        ((((5,4,3,2,1),4),7),8,9)
        >>> let foo = ((((5,4,3,2,1),6),7),8,9)
        >>> foo & view (_1 . _1 . _2)
        6
        >>> let six = _1 . _1 . _2
        >>> foo & view six
        6
        >>> foo & six .~ 4
        ((((5,4,3,2,1),4),7),8,9)
        >>> foo & six .~ "abc"
        ((((5,4,3,2,1),"abc"),7),8,9)

------
jwr
As a former common lisper, I don't see the point. Clojure is better in pretty
much every respect and incorporates many fresh ideas (such as excellent
concurrency support). Syntax is the least of CL's limitations. I didn't switch
to Clojure because it was "easy" (quite the contrary).

And no, I do not miss reader macros. Perhaps more surprisingly, I don't miss
CLOS at all, much as I always admired its design. It's just... Unnecessary.

What I do enjoy is STM, good performance, Java interop, ClojureScript,
core.async and lots of excellent code with fresh ideas popping up all over the
landscape.

~~~
agentultra
Clojure is nice and all but I wouldn't suggest it's even close to being better
in many respects, let alone _every_ respect.

When I was working with it on a non-trivial project I despised the JVM stack
traces, image-less environment, and lack of access to the reader. I assume
that eventually Clojure will steal these ideas and adopt it in its own way...
but these old, un-modern ideas of conditions and restarts, images, and reader
macros are actually really useful. I hope they do take a hint.

------
Guthur
In the examples I see nothing overly compelling which would justify
fragmenting the mind share.

Some of them could possible be considered for alexandria [https://common-
lisp.net/project/alexandria/](https://common-lisp.net/project/alexandria/).
Admittedly I am not sure how alive development is but it certainly would be
worth breathing new life into as it is probably the most heavily used CL
library.

As things like STM and lazy which Clojure has, they have been implemented at
the library level for CL.

[https://common-lisp.net/project/cl-stm/](https://common-lisp.net/project/cl-
stm/)

The beauty about a Lisp is that you can easily add so much on top of the
language that will feel as if it was always there. CLOS is a good example of
this.

In the case of JVM with CLojure, and of course others will disagree, I don't
think accessing the Java ecosystem is a good thing. The mindset there is
monolith "Enterprise Solutions" "Inversion of Control frameworks" which
invariable mean systems that are so complex the authors don't even understand
them and lets write XML above all else.

Also if you want CL->Javascript; Parenscript.

------
eslaught
Interesting, but for looping I think a better point of comparison is iterate:

[https://common-lisp.net/project/iterate/](https://common-
lisp.net/project/iterate/)

In my personal opinion, the iterate loops read better than the code samples of
the main page.

~~~
PuercoPop
Looping is still under discussion, check Dan Lentz's comments on the issue:
[https://github.com/cl21/cl21/issues/18](https://github.com/cl21/cl21/issues/18)

------
joesb
Three things I don't like about Common Lisp.

1\. It has CLOS but it doesn't really embrace it in standard library. You have
list, vector, hash-table, each with its own iterator function. You have lots
of #with-xxx macro. All modern languages utilize the idea of common interface
like #iterator or #dispoable. You can clearly see CLOS library and pre-CLOS
library in CL. CL needs to eat its own dog food (CLOS) more.

2\. It lacks basic practical API library, while another containing big
complicate academic functions. Its #format function is probably Turing
complete. It has function to format number in Roman numeral. But it doesn't
have function to deal with datetime. No networking IO function. No Threading
library.

3\. Condition and Restart could take the idea from Dylan. Tying condition to
available restarts, and making class hierarchy of them, is a better idea. This
problem stems from CL not actually utilizing CLOS.

Also, PACKAGE should take the idea of LOCALE, allowing easier local package
rename, and less symbol conflicts problem.

~~~
Moyamo
I agree with all your points.

One of my main gripes with Common Lisp is its complexity. When I started
learning Lisp, I expected to find a beautiful and elegant language, one
without a need for syntax. The way C is almost an elegant assembly. Maybe I
should have tried Scheme instead.

Common Lisp is anything but elegant. Instead of a regular syntax, you get all
these "mini-languages", like the _format_ syntax e.g.

    
    
        (format t "~{~a~^, ~}" '(1 2 3))
        ; prints out
        ; 1, 2, 3
    

This works fine for list, but not for vectors, which is a problem, since I
needed vectors often (for random access).

The loop macro is also quite powerful and complicated. e.g.

    
    
        (loop :for i :from 1 :to 1000 :collect (* i i))
    

will create a list of square of 1 to 1000. The loop macro can become really
convoluted, not at all simple.

The fact that Common Lisp is a Lisp-2 makes treating functions as first-class
as rather awkward. I could never remember when I needed to prepend a lambda
with #'.

This article may be of interest
[http://xahlee.info/comp/Common_Lisp_quotations.html](http://xahlee.info/comp/Common_Lisp_quotations.html)

I found much of the elegance I was expecting in Haskell. But maybe Scheme is a
better lisp.

------
mordocai
By the way, looking at the github there are 40 open issues 5 open pull
requests and no changes to master for 6 months. I think this project may be
dead, or at least on hold for the time being.

~~~
malisper
It looks like they are using the issues to keep track of feature requests.

------
lisper
Another effort along the same lines:

[https://github.com/rongarret/ergolib](https://github.com/rongarret/ergolib)

------
arturventura
I've been thinking about this for a while. I've wrote some thoughts I had over
the years about modernising Lisp.

[https://news.ycombinator.com/item?id=9078444](https://news.ycombinator.com/item?id=9078444)

------
wedesoft
I can recommend having a look at GOOPS [1] (GNU Guile's implementation of
CLOS) for inspiration. It provides multiple dispatch and facilitates
overloading of existing functions (such as "+").

[1] [http://www.wedesoft.de/oop-with-goops.html](http://www.wedesoft.de/oop-
with-goops.html)

------
arh68
I think this is an okay idea, but the comparison to Clojure is really lacking.
Why build on CL when you can build on Clojure? I get the inter-operability,
but when _Multi-Threading and Multi-Processing_ is listed under _Deferred_ ,
Clojure could provide so much of that for free. _On_ Clojure, etc.

~~~
pekk
What if you aren't interested in targeting the JVM?

~~~
arh68
Then I think the CLR would be a good starting point [1]. Or you could settle
for single-threaded ClojureScript/JavaScript.

[1] [https://github.com/clojure/clojure-
clr](https://github.com/clojure/clojure-clr)

~~~
pekk
You seem to be assuming that everyone writing code should be writing code for
either the JVM or CLR, which is a really weird assumption.

------
bitwize
Inb4 the newLISP cultists arrive.

------
ajarmst
Oh, god. Not again. Stopped reading at "More Object-Oriented".

