CL21 – Common Lisp in the 21st Century
github.com
github.com
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
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.
Library-wise, CL-PPCRE and SPLIT-SEQUENCE are your friends, along with a bunch of the sequence operations in the ANSI spec, and finally, you should get comfortable doing some string stuff in LOOP going char by char or word by word.
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/output/stumpwm-better-modeline.html
The best thing I've done is watch a video on making a reddit clone in Lisp. I couldn't get the libraries to work, but I plan on using other libraries to do the same thing either tomorrow or the next day. It's made me realize that I really need to start walking through other people's code. https://vimeo.com/138249727
Google's LISP koans which is ~30 exercises where you complete the code and make the tests pass. Covers everything from mapcar to multi-threading. https://github.com/google/lisp-koans
I'm currently on Ch. 9/32 of Peter Seigel's "Practical Common Lisp". I find the book to be a much better resource after already being familiar with the topics covered. It does a great job of going into the nuances and gotchas of the language, but because is so much more text than code, it's hard for me to appreciate all of those little details if I'm still trying to grasp the fundamentals of the topic. http://www.gigamonkeys.com/book/
I write all the code I see with a pencil and paper (including all of those koans). I read a block of code and then try to rewrite it from memory.
Currently using vim. Haven't gotten around yet to using a live environment.
Future resources:
Paul Graham's "Roots of Lisp"
Paul Graham's "On Lisp"
Build a Lisp compiler
SICP
Paradigms of Artificial Intelligence Programming
Upgrade my editor
Yeah, there's a lot I want to go through. It's gonna take me a few months just to go through all of the resources I have bookmarked so far. And I haven't even started looking for code that I want to read. End goal is to master Lisp.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/
2: https://common-lisp.net/project/alexandria/draft/alexandria....
3: http://www.lispworks.com/documentation/HyperSpec/Front/Conte...
Selecting a subcollection of elements that satisfy a predicate is a natural primitive. My favorite name for it is 'filter'; that's what I've called it in FSet [0]. I haven't defined 'filter-not'; usually the predicate is an explicit lambda expression, in which case adding the negation is straightforward, and even when a lambda is not needed, it's easy enough to write something like '(filter (complement #'integerp) ...)'.
Anyway, even though I prefer 'filter', I could live with 'keep-if'. And by the argument I just gave, we wouldn't really need 'remove-if' anymore. The problem is 'delete-if'/'delete-if-not'; what do we do with them? I guess I would rename 'delete-if-not' to 'nkeep-if' (by analogy with 'nreverse' and 'nsubstitute') and discard 'delete-if'.
(remove-if (complement #'prime-p) ...)
and not (remove-if-not #'prime-p ...)
and thus REMOVE-IF-NOT was deprecated in the ANSI CL standard.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.)
'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.
lispm already covered that cl: is packages, not a prefix but I'd like to add one of the reasons elisp doesn't have any similar of namespaces is due RMS thiking "prefixes are better"[0]
[0]: https://lists.gnu.org/archive/html/emacs-devel/2013-07/msg00...
Creating a consensus language specificatoin is hard. It takes a community of people willing to work over a long period of time in very detailed ways. Throwing a proposal up on Github is unlikely to create a community and organization with the required commitments.
TBH, if I found those things annoying enough to seek out this library, I would probably just use Clojure or some other language.
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.
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.
I would like to hear them nonetheless.
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.
I dream of meeting someone who wants to build something like mesos on top of cells.
Emacs, Guile, and the common lisp in this project have doc strings?
What implementations are you referring to, and what features do you think they're missing?
http://www.lispworks.com/documentation/HyperSpec/Body/f_docu...
(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?I would like to see more structure: expected arguments, return type, etc.
https://github.com/bbatsov/emacs-lisp-style-guide#docstrings
Edited to add: Documentation strings actually predate Common Lisp. They were available at least as early as Zetalisp (mid-1970s).
If you mean structure within the docstrings, there's no official standard, but markup languages for that exist, see Codex[2].
[0]: http://clhs.lisp.se/Body/f_fn_lam.htm
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.lispAre all of the standard functions documented this way?
(declaim (ftype (function (number string) number) add-string))
(defun add-string (a b) ...)