From: Silver
Subject: scheme parameter frames
Date: 
Message-ID: <Apr.14.00.53.21.1992.10295@blaze.rutgers.edu>
Peace-of-mind request.  I get the impression that the frame for associating
parameters for a function call remains accessable after the call completes.
("Off the stack", if you will.)  For example,

    (define (foo a)
      (define (bar b)
        (write a)
        (newline)
        (set! a b)
        a)
      bar)
    foo

    (define bar (foo 1))
    bar

    (bar 2)
    1
    2

    (define baz (foo 100))
    baz

    (bar 3)
    2
    3

I do have this right, don't I?  I think so...

Anyone care to comment on semantic and efficiency issues?

I'm a little uncomfortable with the notion of a physical attribute of a
function call persisting beyond the invocation.  What do you think are
reasonable alternatives in resolving the reference?  Make it unbound or voided
in some way?  This is kind of inefficient, heap-intensive, no?  Well, seems
that this cost can be written off under the assumption that most functions
don't provide access to their invocation frames after invocation, and that this
condition can be detected statically and subject to relatively easy
optimization.

Regards, [Ag]
From: Barry Margolin
Subject: Re: scheme parameter frames
Date: 
Message-ID: <kum22oINN9qu@early-bird.think.com>
In article <··························@blaze.rutgers.edu> ······@paul.rutgers.edu writes:
>Peace-of-mind request.  I get the impression that the frame for associating
>parameters for a function call remains accessable after the call completes.

Yes.  These are generally called "lexical closures."  Section 4.1.4 of R4RS
specifically says, "The environment in effect when the lambda expression
was evaluated is remembered as part of the procedure."  The same is true in
Common Lisp; page 45 of CLtL2 says, "Variable bindings normally have
lexical scope and indefinite extent."

>Anyone care to comment on semantic and efficiency issues?

This feature was introduced in Scheme, and picked up by Common Lisp,
because of the powerful semantic capabilities that it provides.  This basic
facility can be used to implement object-oriented programming systems and
many other advanced features.  See the book "Structure and Interpretation
of Computer Programs" for many examples.

>I'm a little uncomfortable with the notion of a physical attribute of a
>function call persisting beyond the invocation.  

Many function calls have side effects.  Isn't setting a variable a
"physical attribute" that persists?

When you see this facility used in proper ways, I think you'll be more
comfortable.  Here's a simple example:

(define (make-adder increment)
  (lambda (z) (+ z increment)))

(define (add3 x)
  ((make-adder 3) x))

(define (add5 y)
  ((make-adder 5) y))

>						  What do you think are
>reasonable alternatives in resolving the reference?  Make it unbound or voided
>in some way?  

That's what older Lisps did.

>	       This is kind of inefficient, heap-intensive, no?  

Well, it's certainly not as cheap as stack allocation, but it's not much
more expensive than other heap allocation (like cons).

>								 Well, seems
>that this cost can be written off under the assumption that most functions
>don't provide access to their invocation frames after invocation, and that this
>condition can be detected statically and subject to relatively easy
>optimization.

Right.  Also, you don't have to copy the entire stack to the heap, just
those variables that are referenced by closures that can be returned.  The
static analysis for this is pretty easy, and just about every Common Lisp
and Scheme compiler does it.
-- 
Barry Margolin
System Manager, Thinking Machines Corp.

······@think.com          {uunet,harvard}!think!barmar