gcl-devel
[Top][All Lists]
Advanced

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

Re: [Gcl-devel] compute-restarts


From: Peter Wood
Subject: Re: [Gcl-devel] compute-restarts
Date: Mon, 21 Oct 2002 20:24:58 +0200
User-agent: Mutt/1.4i

On Tue, Oct 15, 2002 at 01:08:59PM -0400, Camm Maguire wrote:

<snip>
 
> If I make the following small patch to handler.lisp undoing my fix:
> (Here 'error called above invokes 'signal in turn, which then calls
> each handler funtion registered by handler-case and handler-bind.)
> 
> 'signal patch:
> 
>             (WHEN (TYPEP CONDITION (CAR HANDLER))
>                   (progn
>                     (setf *HANDLER-RESTART-CLUSTERS* *RESTART-CLUSTERS*)
> +                   (format t "in signal, restart clusters is ~S~%" 
> *restart-clusters*)
>                     (FUNCALL (CDR HANDLER) CONDITION)
>                     (setf *HANDLER-RESTART-CLUSTERS* nil))
>               (RETURN NIL) ;?
> 
> 
> 'handler-case patch:
> 
> @@ -128,8 +129,8 @@
>                                      `(RETURN-FROM ,TAG
>                                         ,(COND ((CADDR ANNOTATED-CASE)
>                                                 `(LET ((,(CAADDR 
> ANNOTATED-CASE)
> -                                                       ,VAR) 
> -                                                      (*RESTART-CLUSTERS* 
> *HANDLER-RESTART-CLUSTERS*))
> +                                                       ,VAR))
> +;                                                     (*RESTART-CLUSTERS* 
> *HANDLER-RESTART-CLUSTERS*))
>                                                    ,@BODY))
>                                                ((NOT (CDR BODY))
>                                                 (CAR BODY))
> 
> 
> I get the folowing behavior:
> 
> =============================================================================
> >    (handler-case
>       (make-package "A")
>       (error (c)
>         (if (position 'abort (compute-restarts c)
>                       :key #'restart-name :test-not #'eq)
>             'success
>           'failure)))
> 
> 
> #<"A" package>
> 
> >    (handler-case
>       (make-package "A")
>       (error (c)
>         (if (position 'abort (compute-restarts c)
>                       :key #'restart-name :test-not #'eq)
>             'success
>           'failure)))
> 
> in signal, restart clusters is ((#<RESTART.0>))
> FAILURE
> 
> >    (handler-case
>       (make-package "A")
>       (error (c)(format t "restart-clusters is ~S~%" 
> conditions::*restart-clusters*)
>         (if (position 'abort (compute-restarts c)
>                       :key #'restart-name :test-not #'eq)
>             'success
>           'failure)))
> 
> in signal, restart clusters is ((#<RESTART.1>))
> restart-clusters is NIL
> FAILURE
> 
><snip>

Hi

OK, my brain is sort of exploding, and I feel like I'm in one of those
old adventure games ("You are in a twisty maze of passages, all
alike...") :-) 

I have run these three forms through 3 other Common Lisps (with
#'format removed because some of the others don't have "CONDITIONS"
package and/or *restart-cluster*).

The results are identical for all of them (LispWorks 4-2 personal,
CMUCL-2.4.19, and Clisp-2.28).  They all returned #<PACKAGE A>,
FAILURE, FAILURE, respectively.

GCL _without_ the patch undoing Camm's fix returns #<PACKAGE A>,
SUCCESS, SUCCESS.  Using an older (ie, undoing the fix) #'handler-case
causes GCL to return the same as the other Lisps (#<PACKAGE A>,
FAILURE, FAILURE).

I realise this doesn't answer the issue about lexical binding
behaviour (if there _is_ an issue!).  But I think we can be reasonably
certain that if three other CL's return these values they are probably
correct.

I think the following article by Kent Pitman may have some bearing on
this issue. 

It's at:

http://world.std.com/%7Epitman/Papers/Condition-Handling-2001.html

See the section "Handling in the context of the signaller".  


"Note that the Common Lisp operator handler-case, which is more
                                    ^^^^^^^^^^^^^
analogous to facilities offered in other languages, does not allow
programmer-supplied code to run until after the transfer of control;"

whereas 

"By contrast, handler-bind takes control inside the dynamic context of
              ^^^^^^^^^^^^
the call to SIGNAL, and so is capable of accessing restarts that are
dynamically between the call to SIGNAL and the use of HANDLER-BIND."
 
> =============================================================================
> When handler-case defines the new error processing lambda function, it
> is appearing to carry with it the current *restart-clusters* as
> opposed to the dynamically bound value at invocation time.  Or
> something similar.  What I'd like to know is if this is the correct
> lexical binding behavior, i.e. whether the bug is in handler.lisp, or
> in the lexical binding.  If the former, it would seem rather difficult
> to know in LISP which variables need exporting in this manner amd in
> which circumstances.

Regards,
Peter




reply via email to

[Prev in Thread] Current Thread [Next in Thread]