
CL21 – Common Lisp in the 21st Century - eruditely
https://github.com/cl21/cl21
======
eudox
As someone who writes CL for fun, I think all "let's get the core language
(any language) API right _this_ time" efforts are ultimately doomed to
perdition and entropy.

I'd rather have an API that's not quite perfect, but has had much thought and
wisdom put into it, and is as stable as continents, than an API that's always
iterating towards some unreachable Platonic idea of perfection.

As an aside, the author has also created a -- likely more agreeable -- spin
off library that's a simpler interface to cl-ppcre:
[https://github.com/fukamachi/re21](https://github.com/fukamachi/re21)

------
such_a_casual
I am currently learning common lisp. The only thing I've really found lacking
is support for basic string operations. I'm sure there is a solid library out
there for things like replace(), but it seems silly for everyone to possibly
be using separate libraries, or in-house implementations for standard string
operations. It creates an unnecessary barrier to code readability. From what
I've heard around the grape vine, this is a result of the ANSI standard being
released prior to the popularization of these functions in other languages. If
the CL specification is ever updated, I am sure that this problem will be
solved. I am surprised this github project didn't acknowledge this.

P.S. Changing the name of 'Remove-if-not' makes absolutely no sense to me.
Remove-if and Remove-if-not make perfect sense together. Adding a whole new
word to memorize "Keep" just makes code less readable. Especially since Keep
isn't seen anywhere else in the language. Further-more the redundancy in the
names 'remove-if' and 'remove-if-not' make you think about how these functions
are actually the same, with only a small caveat. 'remove-if' and 'keep-if'
make you think of these functions as different things, as different ideas,
very unlispy.

edit: just checked cl-ppcre's documentation and learned that split and replace
are covered by that lib. Seeing as cl-ppcre seems to be used so widely, I take
back what I said. Lisp is perfect once again.

~~~
klibertp
> The only thing I've really found lacking is support for basic string
> operations. I'm sure there is a solid library out there for things like
> replace(), but it seems silly for everyone to possibly be using separate
> libraries

It's not that bad, there are other languages which have this problem - you can
see exactly the same situation in JS-land, for example. It would be much worse
if not for quicklisp. I think quicklisp and asdf are among the best package
distribution tools: I feel it's better than pip and gem and similar to npm.
Installing a library is literally a single line in your code. There's the
problem with finding the package you need and it's harder than with JS and
npm, but doable.

BTW: what do you do to learn CL? I'm using StumpWM as my window manager and I
think it's one of the best ways of learning CL. With SLIME, then, you get
almost Lisp-only environment, especially if you use Emacs for your other
editing too. I wrote a couple of blog posts[1] about StumpWM and posted my
config on GitHub[2].

[1]
[https://klibert.pl/posts/stumpwm.html](https://klibert.pl/posts/stumpwm.html)
[https://klibert.pl/output/stumpwm-better-
modeline.html](https://klibert.pl/output/stumpwm-better-modeline.html)

[2] [https://github.com/piotrklibert/stumpwm-
config/](https://github.com/piotrklibert/stumpwm-config/)

~~~
aidenn0
If you already know another programming language, you can try PCL[1]; it's a
decent introduction. If you get stuck on something feel free to ask on IRC
(#lisp on freenode).

There is a library called alexandria[2] that covers a lot of obvious missing-
features from the standard library (e.g. emptyp to test for an empty
sequence).

Lastly the hyperspec[3] is actually quite useful as a library reference.

1: [http://gigamonkeys.com/book/](http://gigamonkeys.com/book/)

2: [https://common-
lisp.net/project/alexandria/draft/alexandria....](https://common-
lisp.net/project/alexandria/draft/alexandria.html)

3:
[http://www.lispworks.com/documentation/HyperSpec/Front/Conte...](http://www.lispworks.com/documentation/HyperSpec/Front/Contents.htm)

------
dschiptsov
Currently there is an effort in GNU Emacs project to move a subset of Common
Lisp in Emacs Lisp under the _cl_ prefix, so one would say cl-let or cl-
values, etc.

It seems like a cool idea. If you disagree with some of CL's design or
stylistic choices, which people familiar with Arc or Scheme would do, moving
it out of the way is a good idea.

BTW, a long ago in order or incorporate CL into Symbolics Zeta Lisp they used
_cl:_ prefix for some functions. Nothing is new under the Moon.)

~~~
lispm
> BTW, a long ago in order or incorporate CL into Symbolics Zeta Lisp they
> used cl: prefix for some functions. Nothing is new under the Moon.)

'cl:' is no prefix in Zetalisp. Zetalisp uses packages (namespaces for
symbols) just like Common Lisp, and 'cl' is the name of a package and ':' is
the separator from package name and symbol name. A single colon shows that the
symbol is exported - some part of an external interface.

Thus cl:let is the 'let' exported from the 'cl' package.

Emacs Lisp has no packages, no namespaces, no exports, imports, ... So 'cl-'
is a part of the symbol name. It's just a prefix.

~~~
dschiptsov
Yeah, sorry. Having separate namespaces for packages is much better and
prefixing is just naming conventions.

------
eruditely
What on earth happened to this project? It looked really promising. Is it all
left to racket now?

~~~
jlarocco
For me personally, I'm already used to the ugly CL syntax that it's working
around (hashes), already familiar and comfortable with the underlying
libraries it's using (cl-ppcre, etc.), or don't find the features particularly
useful (laziness, etc.).

TBH, if I found those things annoying enough to seek out this library, I would
probably just use Clojure or some other language.

~~~
ScottBurson
That's the problem with any CL cleanup project: it's mostly going to appeal to
newcomers to CL, who don't already have a large code base in the language,
full of their own macros that address at least a few of the same issues.

Not that CL couldn't use cleaning up. But to really make the new dialect
popular, you'd have to focus on attracting new users, which would require
things like writing books, or at least updating some of the existing books
(e.g. Peter Seibel's). In short, defining and implementing the new dialect is
only the first step of a long slog.

~~~
dwc
> mostly going to appeal to newcomers to CL ... you'd have to focus on
> attracting new users

It's my observation that CL regularly attracts new users, who grumble a bit at
first and then fall in love. Then they drift away to other langs, keeping an
affection for sexps, macros, and the numerous elegant aspects of CL. But drift
away they do. IMO, if CL could keep more of the people who learn it well
enough to love it, then it would be thriving. I have some opinions on _why_
people drift away and how that could be addressed but they're not especially
well formed at this time.

~~~
ScottBurson
> I have some opinions on why people drift away and how that could be
> addressed but they're not especially well formed at this time.

I would like to hear them nonetheless.

~~~
dwc
I would rather not say until I've thought it out some more. A bag of mushy
thoughts with a grain of truth in them would probably be provocative and
wouldn't provide much utility for the CL community.

Instead, here's one of the things that started me thinking about this... Some
years back, Xach created the library manager Quicklisp, filling a huge hole in
the lisp ecosystem. It's nice work and quickly became the defacto standard.
Lots good to say about it and nothing bad, really. The thing that got me
thinking was that this actually needed to be done at the time Xach did it. CL
had been around a long time officially and even longer unofficially, and this
really important piece of infrastructure had not been done. How could that be?

"How could that be?" leads to more questions, and possible answers, and some
loose ideas about moving forward. That's where I'm at, and I don't want to say
more until I have something concrete and constructive. I wouldn't mind having
a speculative conversation (that would help _me_ greatly), but I think
throwing out half baked ideas would do nothing more than the existing corpus
of "why lisp isn't successful" blog posts, so I don't want to have that
conversation somewhere like HN.

------
mcculley
I'm surprised all of the modern attempts at Lisp don't provide some kind of
docstrings (i.e., JavaDoc-like documentation as a first class object available
in the REPL). Why isn't that something that everyone expects in a modern
language?

~~~
martinflack
If I'm understanding your question correctly, that's been in there from ANSI
CL. For example, when defining a function, after the lambda list, a string
will be interpreted as a docstring and stored with the function definition.

[http://www.lispworks.com/documentation/HyperSpec/Body/f_docu...](http://www.lispworks.com/documentation/HyperSpec/Body/f_docume.htm)

    
    
        (defun test ()
          "A test function"
          (+ 1 1))
        => TEST
    
        (documentation 'test 'function)
        => "A test function"
    

You can statically analyze source code to pull them out, or ask the Lisp image
for them, etc. Is there something missing?

~~~
mcculley
Ah. I see. It wasn't obvious in either the examples or the source code.

I would like to see more structure: expected arguments, return type, etc.

~~~
emidln
Why would you do that in a doc-string? If you just `declare` the types with
`declare` instead of putting them in the docstring, the compiler can also take
advantage of them. Then the system can automatically tell you that information
back. It will also infer the return type for you automatically.

A trivial example (your editor can do this for you):

    
    
        (defun add-string (a b)
          (declare (number a) (string b))
          "Parses b and adds to a"
          (+ a (parse-integer b)))
    
        CL-USER> (describe #'add-string)
        #<FUNCTION ADD-STRING>
          [compiled function]
        
        Lambda-list: (A B)
        Derived type: (FUNCTION (NUMBER STRING) (VALUES NUMBER &OPTIONAL))
        Documentation:
          Parses b and adds to a
        Source file: /home/bja/foo.lisp

~~~
mcculley
Ah. That's nice. Thanks for pointing that out. That's something I've not seen
in any introductions to Common Lisp.

Are all of the standard functions documented this way?

~~~
gkya
Why not check your favourite implementation's source?

~~~
mcculley
I have perused the source for Steel Bank Common Lisp, but it's far from clear
if everything in the standard is documented this way or if one must keep a tab
open to the Common Lisp specification for such references.

