>
>
> I mean the example is not a useful example because it doesn't show the
> problem "my" representation solves, which is to make closures independent of
> their enclosing activations if they outlive their dynamic extent.
Yes I'm starting to finish the chapter explanation on explicit return and now I
will go in "opening the trunk section" and study for real your implementation
because I really want to fully understand it.
Stef
>
>
> (define (%apply proc largs)
> (cond ((%primitive? proc) (%apply-internal proc largs))
> ((%closure? proc) (%apply-closure proc largs))
> (else (error "Bad ! Un-apply-able object !" proc))))
>
> (define (%apply-closure proc largs)
> ;; apply a closure: evaluate proc body in
> ;; extended the closure environment with
> ;; proc arguments and largs
> (%eval (%closure-body proc)
> (%extend-env (%closure-args proc) largs (%closure-env proc))))
>
> (define (%eval-lambda expr env)
> ;; lambda in Scheme captures the environment at compile time
> ;; expr = ((x) (+ x 2))
> (%make-closure (car expr) (cadr expr) env))
>
> > You need to consider how to implement this example:
> >
> > Object subclass: #AbstractSuperclass
> >
> > AbstractSuperclass>>computeV
> > | v |
> > v := 0.
> > self maybeCapture: [v := v + 1. v].
> > ^self maybeBlock: v
> >
> > AbstractSuperclass subclass: #CaptureBlock
> > instanceVariableNames: 'block'
> >
> > CaptureBlock>>maybeCapture: aBlock
> > block := aBlock
> >
> > CaptureBlock>>maybeBlock: value
> > ^block
> >
> > AbstractSubclass subclass: #DontCaptureBlock
> >
> > DontCaptureBlock>>maybeCapture: aBlock
> >
> > DontCaptureBlock>>maybeBlock: value
> > ^value
> >
> >
> > Then
> > | thingOne thingTwo |
> > thingOne := CaptureBlock computeV.
> > thingTwo := DontCaptureBlock computeV.
> > (1 to: 10) collect: [:ignore| { thingOne value. thingTwo value }]
> >
> > should answer
> > #((1 0) (2 0) (3 0) ... (10 0))
>
> if 0 value returns 0? yes. (it confused me for a while).
>
> > right? So where does the l-value for v in computeV live? Iy must be an
> > l-value since it is assigned to in the block in computeV. It must outlive
> > the activation of computeV since CaptureBlock>maybeCapture: captures the
> > block and CaptureBlock>>maybeBlock: answers it and the doit evaluates it.
> > If it lives on the stack of the activation of computeV then there is no
> > problem in a Context VM, but in a VM that maps activations to stack frames
> > something special (and slow) has to happen when returning from computeV.
> > However, if the l-value lives in a separate Array (as it does in my
> > VisualWorks and Squeak closure implementations, and as happens in some Lisp
> > implementations), nothing special has to happen. The block refers to the
> > Array, *not* to the activation of computeV.
> >
> > Make sense now?
>
> Yes you allocate on the heap closure binding to be orthogonal to activation
> context.
>
>
> I will reread your blog now.
>
> Stef
>
>
>
> --
> best,
> Eliot
>