Edi Weitz | 29 Aug 11:10 2015

PRINT-OBJECT for built-in classes

The following "works" in three different CL implementations I tried
while in three others the way complex numbers are printed doesn't

? (defmethod print-object ((obj complex) stream)
     (format stream "#< ~A + ~A * I >"
                (realpart obj) (imagpart obj)))
? #c(1 1)
#< 1 + 1 * I >

My understanding of 22.1.2 of the standard is that each Lisp MUST have
a PRINT-OBJECT method for complex numbers.  The question then is
whether I'm allowed to redefine it like above (I think I am) and/or
whether an implementation is allowed to accept this redefinition
without a warning but then to ignore it (which, as I said, is what
happens in three respectable Lisps).


[Note: There's no point in talking me out of this as I don't actually
want to do it anyway.  It's just an example and I'm only interested in
what exactly is governed by the standard.  Complex numbers are also
just an example.  I'm interested in PRINT-OBJECT for built-in classes
in general.]

Jean-Claude Beaudoin | 3 Aug 23:27 2015

Proper behavior of slot-initforms in defstruct?

Please consider the following code:

(defparameter init-a 1)

(let ((init-a 42) (serial-no 0))
  (defstruct foo (a init-a) (b (incf serial-no)))
  (defun get-foo-serial-no () serial-no))

(defstruct (bar (:include foo)) (c 33) d)

When one loads the above and then try to call #'make-bar the result
varies widely from one lisp implementation (clisp) to another.

clisp: (make-bar) --> #S(BAR :A 1 :B 1 :C 33 :D NIL)
ccl: (make-bar) --> <enter the debugger saying: "Unbound variable: SERIAL-NO">

lispworks, allegro and sbcl also behave more or less like ccl.

What is the proper ANSI-CL behavior in this case here?
Is clisp right in evaluating the slot initform in its "proper" lexical context?
Or is the correct behavior to replicate the slot initform verbatim
in the sub-structure constructor regardless of its original lexical context
like the others do?

I guess that this question has probably been asked before, in a somewhat
distant past, but my google skills have not been sharp enough to find it, sorry.

shenanigans | 3 Aug 17:12 2015

Erlang style processes in Common Lisp

Creators of Erlang have a Lisp background, and one feature of the Erlang 
VM (BEAM) that I'd like back-ported into Common Lisp is their process.

An Erlang "process" is cheap to create, cheap to destroy, cheap when 
blocked, and upon exit performs bulk gc of its allocated memory; e.g., 

Handling tens of thousands of requests per second per node isn't 
uncommon, and these often have *several* workers per request or 
connection: hundreds of thousands of processes.  Under such scenarios, 
anything less than this approach to lightweight processes might suffer 
from stalls during long gc runs that would be avoided or significantly 
reduced under Erlang's model.

How might we get equivalent cheap ephemeral processes into a 
contemporary Common Lisp implementation?

For those unfamiliar with it, what Erlang means by "process" stems from 
an implementation of Actor Model with caveats.  Each process is more 
co-routine than thread, and many may run within the same OS thread 
managed by the Erlang scheduler.  The BEAM VM pre-empts processes via 
"reduction" counting, which may be understood as unit of VM time.  Their 
famed tag line, "Let it crash," may be loosely understood in CL terms as 
an implicit HANDLER-CASE.

The open question here is to address a stated non-goal of CL-MUPROC, "we 
rely on the CL implementation's MP system" and "considerably heavier 
than Erlang processes".  [See presentation link from 
https://common-lisp.net/project/cl-muproc/ ]

Some Erlang-on-CL packages use OS threads or in the case of 
Erlang-in-Lisp, fork().  While easier for a library author to implement, 
these contradict the definition of cheap here.  Other such packages punt 
the issue altogether and instead focus only on pattern-matching aspects 
of Erlang the language.

Then there's Lisp-Flavoured-Erlang, and Elixir offers hygienic macros 
that manipulate the full AST properly-- all play nice on same Erlang VM 
at runtime-- for people simply looking to avoid Erlang syntax or 
semantics.  But let's focus on cheap Erlang style processes in Common 
Lisp here, please.

1. Semantics of library elements are straight-forward enough (e.g., 
SPAWN, EXIT) and may be borrowed wholesale and safely named within their 
own package.

2. Memory allocation & garbage collection:

Erlang BEAM VM doesn't begin to reclaim memory until very late, so an 
initial implementation here might assume ephemeral worker processes and 
omit gc until exit of a worker.  However, some processes are long-lived 
in practice.

One compromise might be acceptable: one nursery per process, but 
anything promoted to higher generations gets handled however your gc 
does it now.

This states nothing about use of shared versus multiple heaps across OS 
threads, so such matters may continue to be implementation-dependent.

3. Co-routines:

For something similar to Erlang's reductions, there would need to be a 
measure of runtime complexity per process.

However, I've used single thread co-routines for near realtime systems 
in C and CL with a loop of function pointers and ensuring that each 
referenced function executes under some threshold determined through 
experimentation and confirmed via test cases.  No pre-empting needed.  
While fragile and not easily portable across different hardware 
(including same architecture), this may be acceptable for a preliminary 

Using CL-MUPROC routines as an example and extending MUPROCN: perhaps 
its body becomes this top-level list of functions from which 
interleaving across processes may occur. Then add variations for playing 
well with DO or LOOP semantics.

4. Message-passing:

SBCL's sb-concurrency extension with Queue and Mailbox (implementation 
of "Optimistic FIFO Queue") can be the solution here too.  More aligned 
with CL principles, allowing for multiple mailboxes-- and therefore 
priority messaging-- would be a welcome advancement beyond Erlang.  
(Erlang allows only one mailbox per process: sequential but with pattern 
matching, nothing out-of-band...)

An important implementation detail that simplifies gc and increases 
cache locality across NUMA nodes: messages get duplicated when 
delivered-- each process only references its own copy!

5. (Almost) nothing shared:

Erlang enforces strict prohibition against shared memory, and common 
practice is to use an in-memory database (ETS) as key/value store in 
lieu of globals.  Scala allows but discourages shared memory.

A CL-inspired take on this might be to use SBCL's approach with thread 
creation: upon creating a new process, you get: A) global special 
values, but modify at own risk... B) LET bindings are local to each 
process; C) threads don't inherit dynamic bindings from parent.  i.e., 

6. Scheduling processes on OS threads:

This is delicate in Erlang, and I've experienced specialized use cases 
interfering with their scheduler when under heavy load. Instead for our 
purposes, let the programmer handle the mapping of processes to OS 
threads.  Less is more here.

7. Finally, gen_server & OTP fiends may be implemented as their own 
packages... or skipped entirely!

Thoughts on feasibility?


Edi Weitz | 21 Jul 09:46 2015

Caching of effective methods in custom method combinations

Hi everybody,

Here's some behavior I see on SBCL as well as LispWorks, so I'm
assuming for now they're right in doing so.  My question would be why
they are.

I start with the following code which I compile and load:


  (defvar *current-qualifiers* '(:a :b :c))

  (define-method-combination test ()
      ((methods *))
    (let ((selected-methods (loop for method in methods
                                  when (intersection (method-qualifiers method)
                                    collect method)))
      `(call-method ,(first selected-methods)
                    ,(rest selected-methods))))

  (defgeneric foo (thing)
    (:method-combination test))
  (defmethod foo :a (thing)
  (defmethod foo :b (thing)


Now, in the REPL I do the following:

  CL-USER> (foo 42)
  CL-USER> (setq *current-qualifiers* '(:a :c))
  (:A :C)
  CL-USER> (foo 42)

I almost expected this.  The effective method obviously isn't computed
anew but was cached.  But even if I now re-evaluate the
DEFINE-METHOD-COMBINATION form, (FOO 42) will still return (:BLUE).
Only if I re-evaluate the DEFGENERIC form will the return value change
to (:RED).

My question is if the standard somewhere allows this caching to
happen.  That would for example mean that any kind of "dynamic method
combination" (for example based on the time of the day, just for
grins) is impossible.

Or am I missing something and my interpretation is wrong?


Elias Mårtenson | 4 Jul 13:30 2015

Should GC hooks be used to help broken software?

The following question was raised during my development of an asynchronous library I'm currently building for RabbitMQ.

In summary, the library allows you to create an object of type ASYNCH-CONNECTION, from which instances of ASYNC-CHANNEL can be retrieved. A connection holds a reference to all channels that it uses, and each channel holds a reference to its connection. The connection object has a pointer to a native CFFI object that for the underlying connection (my library is built on the RabbitMQ C API).

My question is: Should I use trivial-garbage to create a GC hook for the connection object so that if the user of the library forgets to close the connection, it will get closed eventually once it's GC'ed?

I can see arguments for both behaviours:
  • It's a bad idea, since losing the reference to the connection object means that the program is broken, and silently cleaning up the underlying connection might hide the fact there is a bug (if the GC doesn't run often enough I might have hundreds or even thousands of lingering connections)
  • On the other hand, it might be a good idea since Lisp developers often use the REPL to experiment, so it's easy to accidentally lose a reference to an object during testing. Thus, using the GC hook will improve the stability of one's development environment.
To me, there is no strictly correct answer to the question, which is why I'm asking for suggestions from you guys.

Elias (loke on #lisp)
Edi Weitz | 3 Jul 09:09 2015

Do symbols need to be EQ?

Just out of curiosity and without any relevance in practise:

Is there one place in the standard where it is explicitly said that
two symbols which are the "same" symbol must be "identical"?  I know
that there are a couple of examples where this is implied, but
formally the examples aren't part of the standard, right?

The EQ dictionary entry for example shows this example:

  (eq 'a 'a)  =>  true

and then it continues with this note (emphasis mine): "Symbols that
print the same USUALLY are EQ to each other because of the use of the
INTERN function."

And the entry for INTERN is actually the closest I could find in terms
of clarification because it says that if a symbol of a specified name
is already accessible, _IT_ is returned -- which sounds like object
identity to me.

But how does this fit into the picture?

  CL-USER 1 > (defparameter *s* 'foo)
  CL-USER 2 > (unintern 'foo)
  CL-USER 3 > (defparameter *s2* 'foo)
  CL-USER 4 > (eq *s* *s2*)

*S* has lost its home package and is thus not EQ to *S2*, sure, but
how do we explain this in terms of object identity?  Has the UNINTERN
operation changed the identity of *S* which once was the one and only
CL-USER::FOO but can't be anymore because this role is now occupied by

Did I miss some clarifying words in the standard?  Did I just manage
to confuse myself?


PS: The UNINTERN entry warns about side effects which could harm
consistency, so maybe this is what they meant?

Mark H. David | 2 Jul 21:16 2015

cl-ppcre:split question

The examples for cl-ppcre:split here


include this tempting recipe:

(split "\\s+" "foo   bar baz

=> ("foo" "bar" "baz" "frob")


(split "\\s+" "   foo   bar baz

=> ("" "foo" "bar" "baz" "frob")

I.e., the result list includes an empty string as the first element if there are one or more whitespace
characters at the beginning of the string.

How can I get rid of the empty string at the beginning? Is there a regexp match for this that would work with split?



David McClain | 8 May 20:35 2015

Heads up on Graphics Ports

Hi all,

I just ran into a glitch in the new LW7 for Mac and Windows. Starting some time ago, there is an additional
parameter in GRAPHICS-STATE called SCALE-THICKNESS. Up to now, it had defaulted to NIL, and that’s why
i never noticed when it was introduced. Starting in LWM7.0 and LWW7.0 it defaults to T. 

Not sure when scaling thickness to transformed coordinates would make sense. I have scaled things in the
past according to zoom state: if you double the window pane size, then thicknesses of lines also doubles in
my plotting package.

I’m hard pressed to imagine a situation in which I’d ever want line thickness to scale according to the
affine transform in effect. And how would that work, when the domain covers (-1 1) while a range covers (10 1000)?

At any rate, just a heads up to everyone. Not broken, just different in the new version of LW.

73 de Dave, N7AIG

David McClain

Didier Verna | 1 Apr 11:15 2015

[CfPart] ELS 2015, April 20-21 2015, London

		 ELS'15 - 8th European Lisp Symposium
		    Goldsmiths College, London, UK

			  April 20-21, 2015


    Sponsored by EPITA, Goldsmiths University of London, Franz Inc.,
	    Lispworks Ltd., Clozure Associates and Google

Recent news:

- A few seats left, still time to register!
- Programme now online (schedule may still change a little)
- Invited speakers announced: Zach Beane, Bodil Stokke, Martin Cracauer

The purpose of the European Lisp Symposium is to provide a forum for
the discussion and dissemination of all aspects of design,
implementation and application of any of the Lisp and Lisp-inspired
dialects, including Common Lisp, Scheme, Emacs Lisp, AutoLisp, ISLISP,
Dylan, Clojure, ACL2, ECMAScript, Racket, SKILL, Hop and so on. We
encourage everyone interested in Lisp to participate.

The 8th European Lisp Symposium features 3 invited talks, one tutorial,
4 technical sessions and 2 lightning talks slots. The full programme is now
available on the website: http://www.european-lisp-symposium.org/.

Programme chair:
  Julian Padget, University of Bath, UK

Local chair:
  Christophe Rhodes, Goldsmiths, University of London, UK

Programme committee:
  Sacha Chua — Toronto, Canada
  Edmund Weitz — University of Applied Scicences, Hamburg, Germany
  Rainer Joswig — Hamburg, Germany
  Henry Lieberman — MIT, USA
  Matthew Flatt — University of Utah, USA
  Christian Queinnec — University Pierre et Marie Curie, Paris 6, France
  Giuseppe Attardi — University of Pisa, Italy
  Marc Feeley — University of Montreal, Canada
  Stephen Eglen — University of Cambridge, UK
  Robert Strandh — University of Bordeaux, France
  Nick Levine — RavenPack, Spain

Search Keywords:

#els2015, ELS 2015, ELS '15, European Lisp Symposium 2015,
European Lisp Symposium '15, 8th ELS, 8th European Lisp Symposium,
European Lisp Conference 2015, European Lisp Conference '15


My new Jazz CD entitled "Roots and Leaves" is out!
Check it out: http://didierverna.com/records/roots-and-leaves.php

Lisp, Jazz, Aïkido: http://www.didierverna.info

Edi Weitz | 10 Mar 17:02 2015

Default safety level and specialized arrays

Hi everybody,

After rummaging around in the HyperSpec and various implementation
manuals I came to the following conclusion:

1. The standard doesn't prescribe such thing as a default safety level
for CL implementations and there's no portable way to figure out the
safety level of the global environment.  (And the same holds for other
optimize qualities.)  The closest I could find in the CLHS is 3.3.1
where they talk about an "implementation that always processes code as
if safety were high."  From this I conclude that implementations are
allowed NOT to do this or otherwise there would be no need to mention

The LispWorks manual for example describes the defaults in section 9.5
about compiler control, but for SBCL I couldn't find them in the

2. The standard doesn't prescribe what should happen if you try to
write an element of a wrong type to a specialized array, even in safe

Both LispWorks and SBCL will by default complain in this case but my
understanding is that you can't rely on this in portable code.

So, my question is whether the above is correct or if I missed something?


Max Rottenkolber | 23 Feb 01:22 2015

Re: RavenPack Lisp Job

On Mon, 09 Feb 2015 18:01:55 +0100, Andrew Lawson wrote:

> Good afternoon all
>     We at RavenPack in Marbella, Spain, are searching for a Common
> Lisp developer. The webpage linked below goes into more detail. I'd like
> to encourage anyone with an interest to have a look. We are a growing
> company with an expanding development group and offer the opportunity to
> work with interesting technologies and a great group of people.
> Applicants must already be able to work legally in the E.U. The job is
> situated in our Marbella office, no remote work is available. We are
> looking for someone interested in building a career with us, not a
> short-term contractor.
> http://www.ravenpack.com/company/careers/

Oh boy, this would be my dream job if it was remote (or in Bonn ;)). I 
know this is not a desired reply but: If you ever need a remote 
contractor let me know. As long term as you can pay for.