[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]


    (defvar *flag*)

    (defun f ()
      (let-if (some-condition-that-may-be-satisfied-several-times)
              ((*flag* nil))
        ;; large body that will call f recursively and possibly set *flag*
        (when *flag*
          ;; perform special processing

It's hard for me to see exactly what is intended here, since I think
you've got some bugs in your example.  If that condition isn't true,
*flag* stays unbound and the WHEN form gets an error.  It looks to me
like you're trying to establish some sort of handler whenever you find
the hairy condition to be true, so that when you emerge from the body
you will do something at this level (only) whenever the flag has been
set.  But in the code you give, the "special processing" will occur at
all calls to F between the place where flag is set and the innermost
surrounding F where the condition was true.

I think that in most cases I would be inclined to handle this upward
communication by the return value rather than by side-effecting some
conditionally bound variable.  It's less confusing that way.

But if you must do something like this, I see no reason not to use
PROGV.  It shouldn't be any more inefficient than any other way of
binding a special, as long as the list of variables is a quoted constant
at compile time.  If your local compiler generates lousy code for PROGV,
it should be easy to add an optimization to handle the
constant-variable-list case as efficiently as any other binding of a
special.  If you don't like the looks of PROGV, then you can easily
write your own LET-IF macro in terms of PROGV, as long as you restrict
this form to binding special variables only.  I perhaps mistakenly
assumed that the "overkill" you referred to earlier was in being forced
to use a special variable when you wanted a lexical one, but that is not
the case in your example.

-- Scott