Newsgroups: comp.lang.lisp
Path: cantaloupe.srv.cs.cmu.edu!das-news2.harvard.edu!news2.near.net!howland.reston.ans.net!ix.netcom.com!netcom.com!hbaker
From: hbaker@netcom.com (Henry G. Baker)
Subject: Re: Captured lexical environments
Message-ID: <hbakerCz7sy6.3sE@netcom.com>
Organization: nil
References: <398PVc1w165w@sytex.com>
Date: Sun, 13 Nov 1994 16:39:42 GMT
Lines: 68

In article <398PVc1w165w@sytex.com> smcl@sytex.com (Scott McLoughlin) writes:
>        My question is: has anyone compared these 
>two methods, "all else being equal". The ribcage
>model is "too conservative", in that dead references
>might be viewed as "live" by the gc as a lambda
>captures a whole "ribcage".
>        Alternatively, the copying model could add
>additional copying overhead if lexically bound
>variables were copied multiple times and could
>allocate more memory as well. In its favor, the
>copying model is less conservative, and variable
>reference will be a single indexed reference
>usually, with an extra indirection for updatable
>cells.  The ribcage model can require "walking"
>the chain of environments.
>        Additionally, the "ribcage" model _could_
>require manipulating an environment register when
>crossing a binding contour, which makes for extra
>compiler tracking and/or runtime work. The
>copying model only requires setting an environment
>register at procedure entry.
>        The more I think about it, the more the
>copying model looks like a win, but has anybody
>done an "empirical investigation" or would like
>to share implementation experiences regarding
>these two runtime representations of lambda
>bound lexical environements?

Part of the problem you refer to is a result of a basic bug in
Lisp/Scheme -- that name bindings aren't permanent.  In other words,
the binding itself is changed, instead of having a side-effectable
'cell' being permanently bound to the name.  As a result of this bug,
variables which occur as arguments to a function are passed 'by value'
instead of being passed 'by reference' the way everything else is
passed in Lisp/Scheme.

Thus, the replacement of side-effectable environments by
side-effectable 'cells' isn't just an implementation issue, but
evidence of a more fundamental principle.

Most good compilers detect SETQ/SET! of lexically-scoped variables in
an early pass, and either immediately replace this with a
side-effectable cell (improved with later stack-allocation
optimizations) or otherwise handle this case differently.

By making side-effectable bindings lexically distinct from permanent
bindings, the readability of programs is dramatically improved.  Furthermore,
the programmer has also been put on notice that these bindings are likely
to be more expensive (especially in closures) than permanent bindings.

The Algol-68, Bliss and ML languages have all gotten this issue right,
and nearly every other language -- including Common Lisp and Scheme --
has gotten it wrong.

The ML implementors have done large amounts of research on various
schemes to minimize the space required for closures.  Check the Princeton
and CMU sites for papers on these issues.

This bug in Lisp is discussed to some extent in my paper "Equal Rights
for Functional Objects" and its companion paper "CONS Should Not CONS
its Arguments".  I may have touched on it in "Critique of DIN Kernel
Lisp Definition".  These papers are available in my ftp directory.


      Henry Baker
      Read ftp.netcom.com:/pub/hbaker/README for info on ftp-able papers.
      Contact hoodr@netcom.com if you have trouble ftping

