POS, OOFS, CL v Scheme, etc.

Kelly Murray kem@Franz.COM
Tue, 13 May 1997 13:50:55 -0700

> I was always amazed that they implemented dynamic binding that way.
> But that is a low-level implementation decision you could alter
> without effecting much else.  Things have changed:  Memory writes are
> more expensive, coding style uses much less dynamic binding, and
> threads are used much more widely.  I'd be willing to bet a beer that
> a deep-binding approach will win.  Dereferencing dynamic bindings

Agreed.  In my shared-memory multiprocessor Common Lisp (TopCL),
I used deep binding, and wrote highly efficient assembly code
that did the lookups, which was fast, with one important exception:
global variables.  They required scanning the entire binding stack
first, before looking at the global value cell.

I introduced the concept of global variables for Common Lisp.
(defglobal *foo* 10)  declared *foo* so the compiler did not do
dynamic binding lookup for the variable.  This was very important
to achieve high performance.

Unfortunately, Common Lisp defines a bunch of dynamic variables
which mucks everything up.  *print-length*, *print-level*, etc, etc.
They should be killed dead and replaced with something else,
like only a single variable *printer-control*, which is bound
to a CLOS instance that holds the values for these fields,
or something like that.

Note that recently bound dynamic variables are found very fast,
they are at the top of the stack.
The compiler depended on this, since it used the variable "for-value"
to indicate whether a form was being compiled for its value or not.
Looking it up was always fast.  To make sure it was, you can always
do this (let ((for-value for-value)) ...)

However, dynamic bindings should be avoided whenever possible.