Lisp, documenting my encounter with, step #1

27/07/19, modified 27/07/19

Dear blog, Yesterday I started to learn the LISP language. I do not remember how many times I tried to do this (probably about 5 times), but this time will be different. For one, I'm going to document the process. For two, I'm going to use the language. I tried some books before, this time I'll just use the Hyperspec1.

Let's just dive right in at DESTRUCTURING-BIND2. In the description we find 2 lines, the links in the first line refer to page we are on3. Plus, the language is weird, it reads as if dead things (or ideal objects) somehow posses agency. The real information is probably in the link to the description of the lambda form, but that part I'll do later in another post. On this page we have to example to parse.

 (defun iota (n) (loop for i from 1 to n collect i))       ;helper
 (destructuring-bind ( (a &optional (b 'bee)) one two three)
     `((alpha) ,@(iota 3))
   (list a b three two one)) =>  (ALPHA BEE 3 2 1)

Let's explain something with the most convoluted example we can think of. First the helper function, I could not image this would be lisp, it reads like python with "loop",  "for", "from", "to" and "collect" syntax. Next, from the existence of this helper function in the documentation, can I then conclude that no standard function has been specified to generate a sequence of consecutive integers?. Finally, this function was not needed for the example as in the next line it will be used to create an array of 3 items!. Next, the actual use of the function with an attempt to put most of the special syntax into the call, all of this could be put in the documentation of the syntax itself. The whole line does provide a good exercise to learn and figure out a whole host of the special common lisp syntax trick (look at that we have ', ` and ,@).  In the next line the bound variables are used, this time not using special syntax but a call to the list function4. Finally the result of the last form is printed5.

After I gave up on using the destructuring-bind function, I came to 'if' and so into progn. Both, to be done next.

  1. Let's read that first page

    The ANSI Common Lisp standard contains nearly 1100 pages describing nearly a thousand functions and variables in sufficient detail to accommodate hosting of the language on a wide variety of hardware and operating system platforms

    First, the nearly, these numbers should be easy enough to determine exactly, especially the number of functions and variables (one could even write a LISP program to do so). Next, somehow by describing functions it is possible to accommodate hosting? or is it the containing of the pages that does this?.

    Another page with this information can be found here, clearly an earlier version of the page. With dead links and reference to a Harlequin company, which seems to have disappeared into thin air.

    []

  2. How I got there; I wanted to write a function to concatenate strings. A function exists to concatenate the contents of all kinds of sequences. But it's to generic for my taste, so let's write a wrapper function. Then I have a list in my caller,  where a &rest parameter is expected and so I found DESTRUCTURING-BIND []
  3. How does that help?  It seems that the links have been auto-generated []
  4. Could this also be done with special syntax? note to self: this list function is a good candidate for a next post []
  5. No, '=>' is not special syntax []

8 Responses to “Lisp, documenting my encounter with, step #1”

  1. > First, the nearly, these numbers should be easy enough to determine exactly

    You are absolutely right ; and cop-out however they might attempt, the lisp folks are guilty of perlthought here, no question about it.

    The likely reason 1st generation started doing it (in the 90s) was the perception that precise numbers are scary to [imbecile] undergrads, based as it was in fact, derived from direct experience in US "colleges" ; and then the guilty expectation that imbecile undergrads are all the undergrads, and that the goal of education is socialism and no imbecile left behind instead of republic, painful & humiliating evisceration of imbeciles and the cult of the elite ; and so they "adapted".

    By now this continues out of mere inertia, the imbecile undergrads just continue the world they saw, which was the subset of the world that the guilty showed them, an inconsequential and fundamentally false subset of the actual world.

  2. ave1 says:

    Mircea Popescu, So then let's try to count the functions, with bash. All functions in the hyperspec have a title with CLHS: Function blabla. Simple bash line;

    sed -n "s/CLHS: Function \(.*\)/\1/p" * | tr ', ' '\n'|sed '/^$/d' | wc -l

    GIves a count of: 438 functions!

  3. The bash counting has gotta be the more insulting thing to happen to the lisp ecosystem in weeks.

  4. spyked says:

    > Let's explain something with the most convoluted example we can think of.

    Apparently Lispers have this tendency to come up with weird toy examples, huh?

    > Next, from the existence of this helper function in the documentation, can I then conclude that no standard function has been specified to generate a sequence of consecutive integers?

    Not AFAIK. I don't recall ever using a specific function for this purpose myself.

    > this also be done with special syntax? note to self: this list function is a good candidate for a next post

    Likbez on "list" versus quotation: list is generally used to build lists whose elements have been evaluated beforehand, i.e. when the call was made. Meanwhile, quotes, quasiquotes (the backquote thingie) and unquotes (the comma thingie) are used to define (usually compile-time) expressions and control the evaluation within them. For example:

    > (defparameter x 1)
    X
    > (list x 2 3)
    (1 2 3)
    > '(x 2 3)
    (X 2 3)
    > `(,x 2 3)

    Note however a fundamental difference between how they work:

    > (defparameter *a-list* nil)
    *A-LIST*
    > (defun f(x)
    (push (list x 'a 'b) *a-list*))
    F
    > (f 1) (f 2)
    ((2 A B) (1 A B))
    > (setf (cadar *a-list*) 'd)
    D
    > *a-list*
    ((2 D B) (1 A B))
    > (defun g (x)
    (push `(,x a b) *a-list*))
    G
    > (setq *a-list* nil) (g 1) (g 2)
    ((2 A B) (1 A B))
    > (setf (cadar *a-list*) 'd)
    D
    > *a-list*
    ((2 D B) (1 D B))

  5. ave1 says:

    Spyked, now you are doing it again....

  6. spyked says:

    What I'm saying is that if you're trying to understand the thing from first principles, maybe starting from each x, `, ' and destructuring-bind is not such a great idea. Aside from some basic syntax (i.e. what do the parens and the period denote) and a few functions (car, cdr and cons), you need to first look at how the evaluation machine works and get at least an intuition of how things are laid out in memory. Otherwise this'll boil down to a very frustrating exercise in reading Mandarin.

    Having said that, the Hyperspec is as far as I can tell so bad as learning material because it's mostly prescriptive, not descriptive, i.e. it's the system *implementer* who needs to "accommodate the language on X hardware" and ensure that top-level progn forms are handled this and not that way. You might be better off starting with McCarthy's Lisp manual, then building up from there.

    Which isn't to say that this Hyperspec review is in itself a bad idea, I for one have really enjoyed reading so far.

  7. lispm says:

    Well, you took a spec-like thing to learn a language. There starts your problem. But why not... Actual Lisp books for learning the language: ANSI CL from Paul Graham, Practical Common Lisp by Peter Seibel, Successful Lisp: How to understand and use Common Lisp by David Lamkins, Lisp 3rd Edition, Winston/Horn, Common Lisp: A gentle introduction to symbolic computation by Touretzy , .... and a bunch of others...

  8. [...] begin with my own version of (ac)counting the functions in acceptor.lisp. First, we read all the top-level S-expressions in the [...]

Leave a Reply