Munich Lisp Talk, 10th November 2009

Last Tuesday, I gave short talk about a library I have been writing on: Sequence Iterators.
The library is perhaps a bit misnamed because at the moment, it's really a convenience layer on top of iterators. It's supposed to provide tools to make writing functions that operate on sequences convenient, and yet not blatantly inefficient.

I'd be very much interested in feedback regarding rough corners if you find a case to apply the library. If you want to give it a shot, there's a file "more-sequence-functions.lisp" which contain prototypes of useful sequence function for which I haven't yet had the time to write them.

Please notice that the library is still work in progress.


Looking for a Lisp project?

You're an intermediate to the Common Lisp language and are desperately looking for a practical project to try your Lisp skills at? You're longing for fame and glory?

If that's the case, I have something for you:
  1. write a library to access the Web API provided by launchpad,
  2. afterwards, using that library, make it possible to conveniently add and update tickets in a (not yet existing) bug tracker for clbuild. The tickets are supposed to add/update repository urls.
Sounds interesting? If so, drop me a mail.


SLIME tidbits (2009-10-24)

  • To quickly find out the "revision" of your slime checkout, you can now use M-x slime-changelog-date.
  • Sometimes, e.g. due to character encoding confusion, the Emacs side of Slime can be brought to a dysfunctional state. M-x slime-reset will hopefully get you back to business.
  • Restarts as shown in the Slime Debugger are now numbered reversely. The advantage is that often-existing restarts will now very likely get associated with the same number as you can see on the screenshot below. (Remember that the numeric keys are mapped to invoke the corresponding restarts.) This may mean that you have to invalidate some of your muscle memory -- notice that often-needed restarts do come with a static, symbolic mapping, i.e. q to abort to toplevel, a to invoke the most recently established abort restart, and c to invoke a continue restart.

  • Commands which open an Xref buffer (in particular M-?) do not select that buffer anymore. Instead, you're now supposed to use the commands C-M-. and C-M-, to cycle through the entries in the Xref buffer from within your source buffer. That's more ergonomic from my experience. The intended key sequence is: M-? C-M-. C-x 1 frob C-M-. C-x 1 frob etc.


SLIME tidbits (2009-10-21)

Stas Boukarev just comitted two useful new commands to CVS: slime-open-system, and slime-browse-system.

As you can see on the above screenshot, M-x slime-open-system, or alternatively the REPL shortcut ,open-system, will open all the files listed in a system's .asd file. Optionally, it'll also load the system if it's not already loaded.

And on the screenshot below, you can see M-x slime-browse-system (or ,browse-system at the REPL, respectively) which will open the directory a system's .asd file lays in using dired.



Common Lisp is a wonderfully complex language, and probably no matter how long you've been studying it, you'll always find a thing you didn't know before.

What, for example, do you think #0AFFFF represents?

Perhaps you're thinking of the color turquoise represented as a hexadecimal RGB value?

Well, witness for yourself:
CL-USER> (setf *read-base* 16)

(Bonus point if you know how to restore *READ-BASE* to a value of 10 again.)

Still no idea?
CL-USER> (type-of *)
Right, #0AFOO is literal syntax for (make-array nil :initial-element 'foo).

And, yeah, even though Common Lisp is surely a complex beast, it's at the same time very well engineered. Witness thus:
CL-USER> (defvar *a*
           (make-array nil :initial-element 41))
CL-USER> (incf (aref *a*))
CL-USER> *a*
And if you want to see really quirky stuff, take a look at strings with an element-type of nil.


ANN: Named-Readtables 0.9

The editor-hints project is pleased to announce Named-Readtables.

What are Named-Readtables?

It's a library a) to help you to organize your readtable hacks, and b) to help your development environment to deal with these hacks. For detailed information see What are Named-Readtables? in the documentation.


DEFREADTABLE (analogously to DEFPACKAGE) can be used to specify the content of a readtable.

IN-READTABLE (analogously to IN-PACKAGE) can be used to specify what readtable should be used while compiling a .lisp file.

Named-Readtables has an API very much inspired by the existing API of packages. But see Important API idiosyncrasies in the documentation.


See here.


darcs get http://common-lisp.net/project/editor-hints/darcs/named-readtables/

Release Notes

The release was tagged as 0.9 even though it's actually pretty much a 1.0. Experience tells that no matter how much you try to polish a piece of software, there will be two to three issues. The 1.0 will wait for these issues be reported.


The library has been tested on SBCL, CCL, Clisp, ABCL (head), ECL, Allegro 8.1, Lispworks 5.1.



Stas Boukarev polished up Juho Snellman's slime patch which nicely integrates SBCL's statistical profiler into Slime, turned it into a proper contrib (slime-sprof) and committed it to CVS. The patch dates back as far as 2005, with an update in 2006, and I'm glad that it eventually turned up into Slime itself.

Here's the link to the documentation explaining how to use it.

Thanks Juho and Stas!

  • Up-to-date screenshot by Stas:

  • Earlier screenshot by Juho:


SLIME tidbits (2009-09-20)

Today I'll write about a very recent new addition: slime-edit-uses bound to the keys M-? and M-_.

It is the logical counterpart to slime-edit-definition (M-.) .

Basically, it's nothing more than a wrapper around the already existing Xref commands (slime-who-calls, etc.) but it's a pleasure to use because a) it's just one key binding which does all instead of a multitude of different special-purpose bindings, and b) it's an easy binding (M-? vs. C-c C-w KEY) and obvious as well (right next to M-. its counterpart.)

What does it do? Well see for yourself:

  • on functions, it'll show a list of all call sites.
  • on macros, it'll show a list of the sites the macro is expanded.
  • on special variables, it'll list all the places the variable is set, bound, or referenced.
  • on classes, it'll show a list of methods that specialize on that class. (no screenshot)
Of course, the usual disclaimer applies: The quality of this feature highly depends on how much Xref information your implementation is able to store.

Now, for me this begets the following question: How easy would it be to make SBCL collect Xref data during the build of itself?


WANTED: trivial without-package-locks

Has anyone written a trivial wrapper definition for WITHOUT-PACKAGE-LOCKS ?

"Trivial" as in trivial-utf8, trivial-backtrace, trivial-garbage, trivial-shell, trivial-timeout, et cetera perge perge.


Common Lisp & Vim

Nagging about how preposterous it is to be forced to learn Emacs, is no more.

Frank Duncan has been working on Nekthuth, a Vim plugin for Common Lisp. While it's not completely prime time right now, it certainly looks very promising. Definitively, the most feature-full plugin I've seen so far.

Now if you're one of those few lost souls who just do not want to find absolution in the Church of Emacs, take a look at it and give Frank a hand, or two. For example, make it use Slime's SWANK-BACKEND, not the server, just the portability layer.

Alternatives: Cusp, a plugin for Eclipse. ABLE, a standalone text editor written in Common Lisp.


Erik Naggum, RIP.

It's sad but seems to be true: Erik Naggum was found dead in his home.

Last September, I wrote him a mail to thank him for the wealth of postings
he had contributed to comp.lang.lisp and for the impact they had on me.
I now feel incredibly glad I did that as I had always postponed doing so
for years.

Following is his response.

RIP, Erik.

* Tobias C. Rittweiler (2008-09-19 00:37)
> for a long time I've wanted to send an e-mail to express the
> gratitude I feel for the countless usenet postings that you have
> written in your comp.lang.lisp history. Now I finally came around
> doing so:

It’s been quite a while since I posted my last article to c.l.l, but
very warm and welcome messages like yours still keep coming in at a
rate of about one a week. It amazes me.

> Thank you for the time and energy you spent in writing so many
> sophisticated and thought-provocating articles. I never understood
> where you drew this massive amount of energy and the will to
> continue from, considering the feedback you received back at that
> time.

Even when I was posting at a high rate, I received more mail from
those who appreciated what I had posted. I needed that encouragement
and knowing that despite the increasing amount of insanity on the
newsgroup, lots of people were reading what I wrote with a positive
attitude. However, there are some people whose evil ways are truly
destructive, and those are the moralists and the punishers who are
utterly unable to produce anything good at all, but all the more
hell-bent on making others pay for such things as not living up to
their expectations, doing what they think is right, etc, and I drew a
considerable amount of energy from my life-long desire to rid the
planet of moralists and punishers. It may sound contradictory, but I
hold that the use of force and violence and the lesser evils of
moralizing and punishment should only be used to prevent any of them,
never to seek any other goal: Telling a moralist that moralizing is
wrong, punishing those who punish others, using force and violence to
stop those who initiate the use of force and violence — you get the
picture — is the right thing to do. Unfortunately, this gets the
moralizers and punishers all worked up, and they prove that they
really are the psychopaths they only appeared to be when someone had
the gall to do something against /their/ desires. So even though my
general outlook on life went under-appreciated, namely that if you
know what other people should have done in the past, you never have
any clue what you or anyone else ought to do in the future, and if you
are concerned with what you yourself ought to do in the future, you
generally leave other people alone to figure out what /they/ ought to do
in the future, too, lots of people picked up on the positive message:
Exposing moralists and punishers for what they really are —
psychopaths — does a great service to any community who suffers from
their pernicious effects. Of course, if you are a horribly bad person
like that, you can only see others as reflections of yourself, and you
never understand why anyone would want to moralize against or punish
/you/, because part and parcel of being rabidly insane is never being
able to see yourself from the outside, and you think insane thoughts
like “How /dare/ anyone moralize against or punish /me/, when I‘m the sole
moral authority in the whole Universe and everyone, everywhere have a
moral duty to behave the way /I/ tell them!”. Or, in other words, people
who partition the world population into “the good” and “the bad”
always make the mistake of believing that they fall into the “the
good” partition, when they are actually among the very few that are
truly evil: No monumental evil act in the history of mankind has been
committed by anyone who thought of themselves as “evil” — on the
contrary, the worse the (objective) evil, the more the perpetrator was
completely convinced of the goodness of himself and of his
“purification”. So when the newsgroup became plagued by the evil kind
of moron that has nothing to contributed and no rewards for anyone
doing the right thing, but only harm and punishment for those who do
the wrong thing in their eyes, it was time to quit. Had I had even
more energy, I could have stayed, but I had ran out of steam fighting
false accusations, which is another one of those hallmarks of truly
evil people who think nothing of harming the innocent in their crusade
against the “evildoers”. It turns out, as any study of history will
show, that those accused by moralists and punishers are always
innocent. That’s why we need courts, so those who accuse are not the
ones to decide on the guilt and the punishment. Stupid people tend not
to grasp this fact, and only see courts as means of letting people
they “know” are guilty avoid punishment.

> And I particularly mean your non-technical contributions. I read all
> those now already several years ago when I was sixteen if I'm
> remembering correctly. I recall how I was shocked at the tone you
> used, and the aggression you seemed to feel towards people, as I
> grew up in feel-good communities myself. [The postings] made me value
> technical expertise and competence over civil masquerade, and they
> revealed how the latter can sometimes even impair the communication
> for the former.

Civility and politeness are extremely useful tools in communication
with people who are more wrong than right, but of very little use with
people who are vastly more right than wrong. This counter-intuitive
observation comes directly from the fact that we simply do not need
civil and polite ways of telling people that they are right about
something. So the people who have most to gain from civility and
politeness are people who know they are and intend to /stay/ wrong while
they force everybody else hold their tongues. That may have been a
very good way of building societies before /anyone/ was usually right
about anything. It is only in the twentieth century that a sizable
fraction of the population had any means to know whether they were in
the right or in the wrong to begin with. Before we invented the
concept of the real world, everybody lived their entire lives in their
own emotional world. After science and technology invented the concept
of the real world and of truth as correspondence between thoughts and
reality, the internal, private world turned out to be /untrue/ almost
all the time. These days, I keep telling people that you only /really/
grow up and become a human being (as opposed to a mere animal) when
you realize that most of what you think and almost all you feel is
/wrong/ and every person, however smart or highly esteemed by their
peers, is utterly and completely incapable of determining where they
are right among all this wrongness on their own. We tend to believe we
are mostly right, however, and only notice when the consequences of
our actions contradict our best expectations. Now, there are many
areas of life where there /is/ no way to sort right from wrong, and it
would certainly be impolite to point out an error that was only
relative to our own personal values, which is where the impoliteness
of moralizing comes in, but modern man enjoys a growing number of
areas where we can unequivocally sort right from wrong, and then it is
impolite /not/ to point out an error, for that means we let someone
believe something that will cause them harm, or at least undesired
consequences, later on. This means that in the areas of life where
people are mostly wrong, it is indeed a good thing to be civil and
polite all the time, as one wouldn’t want others constantly to point
out one’s own mistakes, either, but in the many areas where it is
possible to be right, and positively harmful to be wrong, allowing
people to hold on to false beliefs in order to protect their feelings
is really, really bad for everyone. The key, therefore, is knowing
which areas can and which still cannot tell right from wrong. It is my
firm position that no areas of science, technology, engineering,
mathematics, and allied disciplines such as medicine, are proper
arenas for politeness and civility. If people are wrong and are
spreading dis- or misinformation in these fields, everybody hurts
because it becomes that much harder to know right from wrong. However,
in areas where no one can really tell, such as ethics, politics,
fashion, etc, even though we may have pretty good ideas and
communities who /choose/ a particular set of beliefs, it behooves people
to be humble and civil and polite because fighting with people who are
wrong, but believe they are right, yet there are no means to prove
that, would be extremely tiresome, as it became on c.l.l when people
who stopped thinking about issues where we /can/ decide right from
wrong, started to bother everyone with their /personal/ problems when
others disagreed with them.

> In retrospect, I'm pretty sure that you helped me become the
> individuum I am now.

I’m very pleased to hear that, and particularly that you took the time
to write and tell me. I wish you the best of luck for the future!

Best regards, Erik Naggum
The United States of America still symbolizes individualism, rationality,
and intellectual achievement to me — even though most Americans disagree.


SLIME tidbits (2009-05-14)

First a small addendum: In my previous blog entry I demonstrated the improved font-lock magic in Slime to shadow forms suppressed by reader conditionals. Anyone who succumbed to the temptation and updated their Slime checkout, should really update to today's HEAD. There has been a couple of issues which have been fixed meanwhile.

In this blog posting I'll demonstrate my work on Slime's inspector for STANDARD-OBJECTs. Previously it looked like this:

I always found the [set value] and [make unbound]buttons after each slot entry pretty distracting, if not to say annoying. So I spent some time to replace them with a checklist as follows:

Quite cool that you can do this with Slime's inspector! Notice that I did not have to touch a single Elisp code line for all this.

You may have noticed the new [group slots by inheritance] button: by default the slots are sorted alphabetically by their name. After pressing this button, however, the slots will be grouped according to the class they were inherited from. Or in CLOS terminology: according to the class they're direct slots of.


SLIME tidbits (2009-05-02)

Since a long time SLIME tries to highlight forms specially that are suppressed due to reader conditionals. That feature has never worked reliably for me; sometimes such forms were highlighted, but most often not. And even if they were highlighted, redisplay (or rather refontification) would often remove the highlighting again.

While resuming to work on my named-readtables library -- which includes a little bit of portability glue --, I became annoyed^W intrigued enough to take a look at the cause of this non-deterministic behaviour.

The issue took more effort than I'd have initially expected. But as you can see from the screen shot, it should be fixed now. It shows the FINALIZE function from the trivial-garbage project. (I hope planet.lisp reader will be able to see the image, too.)


SLIME tidbits (2009-01-03)

  • When you update to HEAD make sure you enable the slime-repl contrib, otherwise you'll be stuck to an old-school inferior-lisp REPL, only.
    Recommended: Use the slime-fancy meta contrib which enables various useful features you'll probably enjoy.
  • C-u C-c C-c will compile the defun at point with maximum debug optimization setting. (SBCL only so far.)
  • Bleeding edge feature: M-- C-c C-c will compile the defun at point with maximum speed optimization setting (still SBCL only.) This is very useful to benefit from SBCL's type inference and elicit compiler notes.

On the order of macro expansions

Just a moment ago, I was able to dig out a definitive answer for an old question of mine: Can one expect macros to be expanded in the order they textually appear in a source file?

Answer: No, you cannot.

The expectation originated in Common Lisp's evaluation model (CLHS 3.1.2) which can be described to be basically top-down, left-to-right (CLHS

That expectation was short-sighted, though, as processing and evaluating are two differen things. And, indeed, item #6 in CLHS specifies:
Note that top level forms are processed in the order in which they textually appear in the file and that each top level form read by the compiler is processed before the next is read. However, the order of processing (including macro expansion) of subforms that are not top level forms and the order of further compilation is unspecified as long as Common Lisp semantics are preserved.
Which makes perfect sense as it allows compilers to do transformations on the Lisp source code before or along macroexpansion.

For example, UNWIND-PROTECT could be a macro turning
(unwind-protect (protected-form)
(let ((cleanup-thunk #'(lambda () (cleanup-form1) (cleanup-form2))))
  (declare (dynamic-extent cleanup-thunk))
  (%establish-unwind-guard cleanup-thunk)
  (funcall cleanup-thunk) ; no unwinding happened