On Wed, Oct 22, 2008 at 05:52:14PM +0100, Tomas Hlavaty wrote:
> Well, I think this version has one important limitation: if Prg has a
> recursive call(s) to foo, the deeper foo won't see any values set by
> the foo above, or will it?

Yes, that's right. 'run' takes care to skip the corresponding frames,
because otherwise it would violate its own principle of undoing the
local bindings of 'foo'.

This has the drawback, of course, that you cannot bind things locally.
This tradeoff has to be decided individually. Take 'scl' in "lib.l"

   (de scl (*Scl . "Prg")
      (run "Prg") )

Here we *want* to bind '*Scl' locally, this is the sole purpose of this
function. So we do not supply an env spec to 'run'. And here it also
does not harm, as '@' is not influenced.

> So if I want to write recursive <xml> function, I cannot use (run ... 1).
> So far, I have this:
> (====)
> (de <xml> "Lst"
>    (let ("At" @
>          "Tag" (pop '"Lst"))


But I would not waste stack frame space to bind '@' (as it is bound by
the call to <xml>' already).

For my taste, I would stick with the solution that is used, for example,
at the end of 'style' in "lib/xhtml.l":

      (and (up 2 @))
      (run "Prg") ) )

It uses 'and' to cause the 'set'ting of '@' as a side effect.

BUT: I just see that this is wrong! I cannot use 'and' here, as it will
not set the value of '@' if 'up' evaluates to NIL.

I changed this now to

      (case (up 2 @))
      (run "Prg") ) )

because 'case' will always set '@'.

So I would propose this construct, as a general recommendation to handle
such functions. What do you think?

> I don't think it could possibly work without me being esotheric:-)

Let's hope :-)

- Alex

Reply via email to