deprecate lazy-catch
authorAndy Wingo <wingo@pobox.com>
Sun, 31 Jan 2010 11:35:19 +0000 (12:35 +0100)
committerAndy Wingo <wingo@pobox.com>
Fri, 26 Feb 2010 10:56:02 +0000 (11:56 +0100)
* libguile/deprecated.h:
* libguile/deprecated.c (scm_internal_lazy_catch, scm_lazy_catch):
  Deprecate, and print out a nasty warning that people should change to
  with-throw-handler.

* libguile/throw.h:
* libguile/throw.c (scm_c_with_throw_handler): Deprecate the use of the
  lazy_catch_p argument, printing out a nasty warning if someone
  actually passes 1 as that argument. The combination of the pre-unwind
  and post-unwind handlers should be sufficient.

* test-suite/tests/exceptions.test: Remove lazy-catch tests, as they are
  deprecated. Two of them fail:
  * throw/catch: effect of lazy-catch unwinding on throw to another key
  * throw/catch: repeat of previous test but with lazy-catch
  Hopefully people are not depending on this behavior, and the warning is
  sufficiently nasty for people to switch. We will see.

* test-suite/tests/eval.test ("promises"): Use with-throw-handler
  instead of lazy-catch.

* doc/ref/api-debug.texi:
* doc/ref/api-control.texi: Update to remove references to lazy-catch,
  folding in the useful bits to with-throw-handler.

doc/ref/api-control.texi
doc/ref/api-debug.texi
libguile/deprecated.c
libguile/deprecated.h
libguile/throw.c
libguile/throw.h
test-suite/tests/eval.test
test-suite/tests/exceptions.test

index c76bdfe..0e84d89 100644 (file)
@@ -1,6 +1,6 @@
 @c -*-texinfo-*-
 @c This is part of the GNU Guile Reference Manual.
-@c Copyright (C)  1996, 1997, 2000, 2001, 2002, 2003, 2004, 2009
+@c Copyright (C)  1996, 1997, 2000, 2001, 2002, 2003, 2004, 2009, 2010
 @c   Free Software Foundation, Inc.
 @c See the file guile.texi for copying conditions.
 
@@ -606,8 +606,7 @@ more conveniently.
 @menu
 * Exception Terminology::       Different ways to say the same thing.
 * Catch::                       Setting up to catch exceptions.
-* Throw Handlers::              Adding extra handling to a throw.
-* Lazy Catch::                  Catch without unwinding the stack.
+* Throw Handlers::              Handling exceptions before unwinding the stack.
 * Throw::                       Throwing an exception.
 * Exception Implementation::    How Guile implements exceptions.
 @end menu
@@ -800,17 +799,53 @@ Operations}).
 @subsubsection Throw Handlers
 
 It's sometimes useful to be able to intercept an exception that is being
-thrown, but without changing where in the dynamic context that exception
-will eventually be caught.  This could be to clean up some related state
-or to pass information about the exception to a debugger, for example.
-The @code{with-throw-handler} procedure provides a way to do this.
+thrown before the stack is unwound. This could be to clean up some
+related state, to print a backtrace, or to pass information about the
+exception to a debugger, for example. The @code{with-throw-handler}
+procedure provides a way to do this.
 
 @deffn {Scheme Procedure} with-throw-handler key thunk handler
 @deffnx {C Function} scm_with_throw_handler (key, thunk, handler)
 Add @var{handler} to the dynamic context as a throw handler
 for key @var{key}, then invoke @var{thunk}.
+
+This behaves exactly like @code{catch}, except that it does not unwind
+the stack before invoking @var{handler}. If the @var{handler} procedure
+returns normally, Guile rethrows the same exception again to the next
+innermost catch or throw handler. @var{handler} may exit nonlocally, of
+course, via an explicit throw or via invoking a continuation.
 @end deffn
 
+Typically @var{handler} is used to display a backtrace of the stack at
+the point where the corresponding @code{throw} occurred, or to save off
+this information for possible display later.
+
+Not unwinding the stack means that throwing an exception that is handled
+via a throw handler is equivalent to calling the throw handler handler
+inline instead of each @code{throw}, and then omitting the surrounding
+@code{with-throw-handler}. In other words,
+
+@lisp
+(with-throw-handler 'key
+  (lambda () @dots{} (throw 'key args @dots{}) @dots{})
+  handler)
+@end lisp
+
+@noindent
+is mostly equivalent to
+
+@lisp
+((lambda () @dots{} (handler 'key args @dots{}) @dots{}))
+@end lisp
+
+In particular, the dynamic context when @var{handler} is invoked is that
+of the site where @code{throw} is called. The examples are not quite
+equivalent, because the body of a @code{with-throw-handler} is not in
+tail position with respect to the @code{with-throw-handler}, and if
+@var{handler} exits normally, Guile arranges to rethrow the error, but
+hopefully the intention is clear. (For an introduction to what is meant
+by dynamic context, @xref{Dynamic Wind}.)
+
 @deftypefn {C Function} SCM scm_c_with_throw_handler (SCM tag, scm_t_catch_body body, void *body_data, scm_t_catch_handler handler, void *handler_data, int lazy_catch_p)
 The above @code{scm_with_throw_handler} takes Scheme procedures as body
 (thunk) and handler arguments.  @code{scm_c_with_throw_handler} is an
@@ -838,141 +873,13 @@ everything that a @code{catch} would do until the point where
 then it rethrows to the next innermost @code{catch} or throw handler
 instead.
 
+Note also that since the dynamic context is not unwound, if a
+@code{with-throw-handler} handler throws to a key that does not match
+the @code{with-throw-handler} expression's @var{key}, the new throw may
+be handled by a @code{catch} or throw handler that is @emph{closer} to
+the throw than the first @code{with-throw-handler}.
 
-@node Lazy Catch
-@subsubsection Catch Without Unwinding
-
-Before version 1.8, Guile's closest equivalent to
-@code{with-throw-handler} was @code{lazy-catch}.  From version 1.8
-onwards we recommend using @code{with-throw-handler} because its
-behaviour is more useful than that of @code{lazy-catch}, but
-@code{lazy-catch} is still supported as well.
-
-A @dfn{lazy catch} is used in the same way as a normal @code{catch},
-with @var{key}, @var{thunk} and @var{handler} arguments specifying the
-exception type, normal case code and handler procedure, but differs in
-one important respect: the handler procedure is executed without
-unwinding the call stack from the context of the @code{throw} expression
-that caused the handler to be invoked.
-
-@deffn {Scheme Procedure} lazy-catch key thunk handler
-@deffnx {C Function} scm_lazy_catch (key, thunk, handler)
-This behaves exactly like @code{catch}, except that it does
-not unwind the stack before invoking @var{handler}.
-If the @var{handler} procedure returns normally, Guile
-rethrows the same exception again to the next innermost catch,
-lazy-catch or throw handler.  If the @var{handler} exits
-non-locally, that exit determines the continuation.
-@end deffn
-
-@deftypefn {C Function} SCM scm_internal_lazy_catch (SCM tag, scm_t_catch_body body, void *body_data, scm_t_catch_handler handler, void *handler_data)
-The above @code{scm_lazy_catch} takes Scheme procedures as body and
-handler arguments.  @code{scm_internal_lazy_catch} is an equivalent
-taking C functions.  See @code{scm_internal_catch} (@pxref{Catch}) for
-a description of the parameters, the behaviour however of course
-follows @code{lazy-catch}.
-@end deftypefn
-
-Typically @var{handler} is used to display a backtrace of the stack at
-the point where the corresponding @code{throw} occurred, or to save off
-this information for possible display later.
-
-Not unwinding the stack means that throwing an exception that is caught
-by a @code{lazy-catch} is @emph{almost} equivalent to calling the
-@code{lazy-catch}'s handler inline instead of each @code{throw}, and
-then omitting the surrounding @code{lazy-catch}.  In other words,
-
-@lisp
-(lazy-catch 'key
-  (lambda () @dots{} (throw 'key args @dots{}) @dots{})
-  handler)
-@end lisp
-
-@noindent
-is @emph{almost} equivalent to
-
-@lisp
-((lambda () @dots{} (handler 'key args @dots{}) @dots{}))
-@end lisp
-
-@noindent
-But why only @emph{almost}?  The difference is that with
-@code{lazy-catch} (as with normal @code{catch}), the dynamic context is
-unwound back to just outside the @code{lazy-catch} expression before
-invoking the handler.  (For an introduction to what is meant by dynamic
-context, @xref{Dynamic Wind}.)
-
-Then, when the handler @emph{itself} throws an exception, that exception
-must be caught by some kind of @code{catch} (including perhaps another
-@code{lazy-catch}) higher up the call stack.
-
-The dynamic context also includes @code{with-fluids} blocks
-(@pxref{Fluids and Dynamic States}),
-so the effect of unwinding the dynamic context can also be seen in fluid
-variable values.  This is illustrated by the following code, in which
-the normal case thunk uses @code{with-fluids} to temporarily change the
-value of a fluid:
-
-@lisp
-(define f (make-fluid))
-(fluid-set! f "top level value")
-
-(define (handler . args)
-  (cons (fluid-ref f) args))
-
-(lazy-catch 'foo
-            (lambda ()
-              (with-fluids ((f "local value"))
-                (throw 'foo)))
-            handler)
-@result{}
-("top level value" foo)
-
-((lambda ()
-   (with-fluids ((f "local value"))
-     (handler 'foo))))
-@result{}
-("local value" foo)
-@end lisp
-
-@noindent
-In the @code{lazy-catch} version, the unwinding of dynamic context
-restores @code{f} to its value outside the @code{with-fluids} block
-before the handler is invoked, so the handler's @code{(fluid-ref f)}
-returns the external value.
-
-@code{lazy-catch} is useful because it permits the implementation of
-debuggers and other reflective programming tools that need to access the
-state of the call stack at the exact point where an exception or an
-error is thrown.  For an example of this, see REFFIXME:stack-catch.
-
-It should be obvious from the above that @code{lazy-catch} is very
-similar to @code{with-throw-handler}.  In fact Guile implements
-@code{lazy-catch} in exactly the same way as @code{with-throw-handler},
-except with a flag set to say ``where there are slight differences
-between what @code{with-throw-handler} and @code{lazy-catch} would do,
-do what @code{lazy-catch} has always done''.  There are two such
-differences:
-
-@enumerate
-@item
-@code{with-throw-handler} handlers execute in the full dynamic context
-of the originating @code{throw} call.  @code{lazy-catch} handlers
-execute in the dynamic context of the @code{lazy-catch} expression,
-excepting only that the stack has not yet been unwound from the point of
-the @code{throw} call.
-
-@item
-If a @code{with-throw-handler} handler throws to a key that does not
-match the @code{with-throw-handler} expression's @var{key}, the new
-throw may be handled by a @code{catch} or throw handler that is _closer_
-to the throw than the first @code{with-throw-handler}.  If a
-@code{lazy-catch} handler throws, it will always be handled by a
-@code{catch} or throw handler that is higher up the dynamic context than
-the first @code{lazy-catch}.
-@end enumerate
-
-Here is an example to illustrate the second difference:
+Here is an example to illustrate this behavior:
 
 @lisp
 (catch 'a
@@ -990,14 +897,7 @@ Here is an example to illustrate the second difference:
 
 @noindent
 This code will call @code{inner-handler} and then continue with the
-continuation of the inner @code{catch}.  If the
-@code{with-throw-handler} was changed to @code{lazy-catch}, however, the
-code would call @code{outer-handler} and then continue with the
-continuation of the outer @code{catch}.
-
-Modulo these two differences, any statements in the previous and
-following subsections about throw handlers apply to lazy catches as
-well.
+continuation of the inner @code{catch}.
 
 
 @node Throw
index c29bfdf..3c9ec11 100644 (file)
@@ -1,6 +1,6 @@
 @c -*-texinfo-*-
 @c This is part of the GNU Guile Reference Manual.
-@c Copyright (C)  1996, 1997, 2000, 2001, 2002, 2003, 2004, 2007
+@c Copyright (C)  1996, 1997, 2000, 2001, 2002, 2003, 2004, 2007, 2010
 @c   Free Software Foundation, Inc.
 @c See the file guile.texi for copying conditions.
 
@@ -400,13 +400,12 @@ equivalent in C.  In Scheme, this means you need something like this:
 @end lisp
 
 @noindent
-The @code{catch} here can also be @code{lazy-catch} or
-@code{with-throw-handler}; see @ref{Throw Handlers} and @ref{Lazy Catch}
-for the details of how these differ from @code{catch}.  The @code{#t}
-means that the catch is applicable to all kinds of error; if you want to
-restrict your catch to just one kind of error, you can put the symbol
-for that kind of error instead of @code{#t}.  The equivalent to this in
-C would be something like this:
+The @code{catch} here can also be @code{with-throw-handler}; see @ref{Throw
+Handlers} for information on the when you might want to use
+@code{with-throw-handler} instead of @code{catch}. The @code{#t} means that the
+catch is applicable to all kinds of error; if you want to restrict your catch to
+just one kind of error, you can put the symbol for that kind of error instead of
+@code{#t}. The equivalent to this in C would be something like this:
 
 @lisp
 SCM my_body_proc (void *body_data)
index 54f0055..95f6f46 100644 (file)
@@ -1816,6 +1816,56 @@ scm_i_subr_p (SCM x)
 }
 
 \f
+
+SCM
+scm_internal_lazy_catch (SCM tag, scm_t_catch_body body, void *body_data, scm_t_catch_handler handler, void *handler_data)
+{
+  scm_c_issue_deprecation_warning
+    ("`scm_internal_lazy_catch' is no longer supported. Instead this call will\n"
+     "dispatch to `scm_c_with_throw_handler'. Your handler will be invoked from\n"
+     "within the dynamic context of the corresponding `throw'.\n"
+     "\nTHIS COULD CHANGE YOUR PROGRAM'S BEHAVIOR.\n\n"
+     "Please modify your program to use `scm_c_with_throw_handler' directly,\n"
+     "and adapt it (if necessary) to expect to be within the dynamic context\n"
+     "of the throw.");
+  return scm_c_with_throw_handler (tag, body, body_data, handler, handler_data, 0);
+}
+
+SCM_DEFINE (scm_lazy_catch, "lazy-catch", 3, 0, 0,
+           (SCM key, SCM thunk, SCM handler),
+           "This behaves exactly like @code{catch}, except that it does\n"
+           "not unwind the stack before invoking @var{handler}.\n"
+           "If the @var{handler} procedure returns normally, Guile\n"
+           "rethrows the same exception again to the next innermost catch,\n"
+           "lazy-catch or throw handler.  If the @var{handler} exits\n"
+           "non-locally, that exit determines the continuation.")
+#define FUNC_NAME s_scm_lazy_catch
+{
+  struct scm_body_thunk_data c;
+
+  SCM_ASSERT (scm_is_symbol (key) || scm_is_eq (key, SCM_BOOL_T),
+             key, SCM_ARG1, FUNC_NAME);
+
+  c.tag = key;
+  c.body_proc = thunk;
+
+  scm_c_issue_deprecation_warning
+    ("`lazy-catch' is no longer supported. Instead this call will dispatch\n"
+     "to `with-throw-handler'. Your handler will be invoked from within the\n"
+     "dynamic context of the corresponding `throw'.\n"
+     "\nTHIS COULD CHANGE YOUR PROGRAM'S BEHAVIOR.\n\n"
+     "Please modify your program to use `with-throw-handler' directly, and\n"
+     "adapt it (if necessary) to expect to be within the dynamic context of\n"
+     "the throw.");
+
+  return scm_c_with_throw_handler (key,
+                                   scm_body_thunk, &c, 
+                                   scm_handle_by_proc, &handler, 0);
+}
+#undef FUNC_NAME
+
+
+\f
 void
 scm_i_init_deprecated ()
 {
index 9832cfb..7f26f3f 100644 (file)
@@ -611,6 +611,16 @@ SCM_DEPRECATED int scm_i_subr_p (SCM x);
 
 \f
 
+/* Deprecated 2010-01-31, use with-throw-handler instead */
+SCM_DEPRECATED SCM scm_lazy_catch (SCM tag, SCM thunk, SCM handler);
+SCM_DEPRECATED SCM scm_internal_lazy_catch (SCM tag,
+                                            scm_t_catch_body body,
+                                            void *body_data,
+                                            scm_t_catch_handler handler,
+                                            void *handler_data);
+
+\f
+
 void scm_i_init_deprecated (void);
 
 #endif
index fd08e6e..22d1c4f 100644 (file)
@@ -30,6 +30,7 @@
 #include "libguile/alist.h"
 #include "libguile/eval.h"
 #include "libguile/eq.h"
+#include "libguile/deprecation.h"
 #include "libguile/dynwind.h"
 #include "libguile/backtrace.h"
 #include "libguile/debug.h"
@@ -93,12 +94,11 @@ struct jmp_buf_and_retval   /* use only on the stack, in scm_catch */
   SCM retval;
 };
 
-/* These are the structures we use to store pre-unwind handling (aka
-   "lazy") information for a regular catch, and put on the wind list
-   for a "lazy" catch.  They store the pre-unwind handler function to
-   call, and the data pointer to pass through to it.  It's not a
-   Scheme closure, but it is a function with data, so the term
-   "closure" is appropriate in its broader sense.
+/* These are the structures we use to store pre-unwind handling information for
+   a regular catch, and put on the wind list for a with-throw-handler. They
+   store the pre-unwind handler function to call, and the data pointer to pass
+   through to it. It's not a Scheme closure, but it is a function with data, so
+   the term "closure" is appropriate in its broader sense.
 
    (We don't need anything like this to run the normal (post-unwind)
    catch handler, because the same C frame runs both the body and the
@@ -108,7 +108,6 @@ struct pre_unwind_data {
   scm_t_catch_handler handler;
   void *handler_data;
   int running;
-  int lazy_catch_p;
 };
 
 
@@ -187,7 +186,6 @@ scm_c_catch (SCM tag,
   pre_unwind.handler = pre_unwind_handler;
   pre_unwind.handler_data = pre_unwind_handler_data;
   pre_unwind.running = 0;
-  pre_unwind.lazy_catch_p = 0;
   SCM_SETJBPREUNWIND(jmpbuf, &pre_unwind);
 
   if (SCM_I_SETJMP (jbr.buf))
@@ -303,9 +301,18 @@ scm_c_with_throw_handler (SCM tag,
   c.handler = handler;
   c.handler_data = handler_data;
   c.running = 0;
-  c.lazy_catch_p = lazy_catch_p;
   pre_unwind = make_pre_unwind_data (&c);
 
+  if (lazy_catch_p)
+    scm_c_issue_deprecation_warning
+      ("The LAZY_CATCH_P argument to `scm_c_with_throw_handler' is no longer.\n"
+       "supported. Instead the handler will be invoked from within the dynamic\n"
+       "context of the corresponding `throw'.\n"
+       "\nTHIS COULD CHANGE YOUR PROGRAM'S BEHAVIOR.\n\n"
+       "Please modify your program to pass 0 as the LAZY_CATCH_P argument,\n"
+       "and adapt it (if necessary) to expect to be within the dynamic context\n"
+       "of the throw.");
+
   SCM_CRITICAL_SECTION_START;
   scm_i_set_dynwinds (scm_acons (tag, pre_unwind, scm_i_dynwinds ()));
   SCM_CRITICAL_SECTION_END;
@@ -319,15 +326,6 @@ scm_c_with_throw_handler (SCM tag,
   return answer;
 }
 
-/* Exactly like scm_internal_catch, except:
-   - It does not unwind the stack (this is the major difference).
-   - The handler is not allowed to return.  */
-SCM
-scm_internal_lazy_catch (SCM tag, scm_t_catch_body body, void *body_data, scm_t_catch_handler handler, void *handler_data)
-{
-  return scm_c_with_throw_handler (tag, body, body_data, handler, handler_data, 1);
-}
-
 \f
 /* scm_internal_stack_catch
    Use this one if you want debugging information to be stored in
@@ -354,7 +352,7 @@ static SCM
 cwss_body (void *data)
 {
   struct cwss_data *d = data;
-  return scm_internal_lazy_catch (d->tag, d->body, d->data, ss_handler, NULL);
+  return scm_c_with_throw_handler (d->tag, d->body, d->data, ss_handler, NULL, 0);
 }
 
 SCM
@@ -566,7 +564,7 @@ scm_handle_by_throw (void *handler_data SCM_UNUSED, SCM tag, SCM args)
 
 
 \f
-/* the Scheme-visible CATCH, WITH-THROW-HANDLER and LAZY-CATCH functions */
+/* the Scheme-visible CATCH and WITH-THROW-HANDLER functions */
 
 SCM_DEFINE (scm_catch_with_pre_unwind_handler, "catch", 3, 1, 0,
            (SCM key, SCM thunk, SCM handler, SCM pre_unwind_handler),
@@ -664,37 +662,6 @@ SCM_DEFINE (scm_with_throw_handler, "with-throw-handler", 3, 0, 0,
 }
 #undef FUNC_NAME
 
-SCM_DEFINE (scm_lazy_catch, "lazy-catch", 3, 0, 0,
-           (SCM key, SCM thunk, SCM handler),
-           "This behaves exactly like @code{catch}, except that it does\n"
-           "not unwind the stack before invoking @var{handler}.\n"
-           "If the @var{handler} procedure returns normally, Guile\n"
-           "rethrows the same exception again to the next innermost catch,\n"
-           "lazy-catch or throw handler.  If the @var{handler} exits\n"
-           "non-locally, that exit determines the continuation.")
-#define FUNC_NAME s_scm_lazy_catch
-{
-  struct scm_body_thunk_data c;
-
-  SCM_ASSERT (scm_is_symbol (key) || scm_is_eq (key, SCM_BOOL_T),
-             key, SCM_ARG1, FUNC_NAME);
-
-  c.tag = key;
-  c.body_proc = thunk;
-
-  /* scm_internal_lazy_catch takes care of all the mechanics of
-     setting up a lazy catch key; we tell it to call scm_body_thunk to
-     run the body, and scm_handle_by_proc to deal with any throws to
-     this catch.  The former receives a pointer to c, telling it how
-     to behave.  The latter receives a pointer to HANDLER, so it knows
-     who to call.  */
-  return scm_internal_lazy_catch (key,
-                                 scm_body_thunk, &c, 
-                                 scm_handle_by_proc, &handler);
-}
-#undef FUNC_NAME
-
-
 \f
 /* throwing */
 
@@ -815,19 +782,7 @@ scm_ithrow (SCM key, SCM args, int noreturn SCM_UNUSED)
     {
       struct pre_unwind_data *c =
        (struct pre_unwind_data *) SCM_SMOB_DATA_1 (jmpbuf);
-      SCM handle, answer;
-
-      /* For old-style lazy-catch behaviour, we unwind the dynamic
-        context before invoking the handler. */
-      if (c->lazy_catch_p)
-       {
-         scm_dowinds (wind_goal, (scm_ilength (scm_i_dynwinds ())
-                                  - scm_ilength (wind_goal)));
-         SCM_CRITICAL_SECTION_START;
-         handle = scm_i_dynwinds ();
-         scm_i_set_dynwinds (SCM_CDR (handle));
-         SCM_CRITICAL_SECTION_END;
-       }
+      SCM answer;
 
       /* Call the handler, with framing to set the pre-unwind
         structure's running field while the handler is running, so we
index 1ed6ba6..d14cbf8 100644 (file)
@@ -52,12 +52,6 @@ SCM_API SCM scm_internal_catch (SCM tag,
                                scm_t_catch_handler handler,
                                void *handler_data);
 
-SCM_API SCM scm_internal_lazy_catch (SCM tag,
-                                    scm_t_catch_body body,
-                                    void *body_data,
-                                    scm_t_catch_handler handler,
-                                    void *handler_data);
-
 SCM_API SCM scm_internal_stack_catch (SCM tag,
                                      scm_t_catch_body body,
                                      void *body_data,
@@ -91,7 +85,6 @@ SCM_API int scm_exit_status (SCM args);
 SCM_API SCM scm_catch_with_pre_unwind_handler (SCM tag, SCM thunk, SCM handler, SCM lazy_handler);
 SCM_API SCM scm_catch (SCM tag, SCM thunk, SCM handler);
 SCM_API SCM scm_with_throw_handler (SCM tag, SCM thunk, SCM handler);
-SCM_API SCM scm_lazy_catch (SCM tag, SCM thunk, SCM handler);
 SCM_API SCM scm_ithrow (SCM key, SCM args, int noreturn);
 
 SCM_API SCM scm_throw (SCM key, SCM args);
index c253b2d..fd5d750 100644 (file)
@@ -1,5 +1,5 @@
 ;;;; eval.test --- tests guile's evaluator     -*- scheme -*-
-;;;; Copyright (C) 2000, 2001, 2006, 2007, 2009 Free Software Foundation, Inc.
+;;;; Copyright (C) 2000, 2001, 2006, 2007, 2009, 2010 Free Software Foundation, Inc.
 ;;;;
 ;;;; This library is free software; you can redistribute it and/or
 ;;;; modify it under the terms of the GNU Lesser General Public
       exception:wrong-type-arg
       (+ (delay (* 3 7)) 13))
 
-    ;; Tests that require the debugging evaluator...
-    (with-debugging-evaluator
-
-      (pass-if "unmemoizing a promise"
-        (display-backtrace
-        (let ((stack #f))
-          (false-if-exception (lazy-catch #t
-                                          (lambda ()
-                                            (let ((f (lambda (g) (delay (g)))))
-                                              (force (f error))))
-                                          (lambda _
-                                            (set! stack (make-stack #t)))))
-          stack)
-        (%make-void-port "w"))
-       #t))))
+    (pass-if "unmemoizing a promise"
+      (display-backtrace
+       (let ((stack #f))
+         (false-if-exception
+          (with-throw-handler #t
+                              (lambda ()
+                                (let ((f (lambda (g) (delay (g)))))
+                                  (force (f error))))
+                              (lambda _
+                                (set! stack (make-stack #t)))))
+         stack)
+       (%make-void-port "w"))
+      #t)))
 
 
 ;;;
index c2ec5f4..bcaa282 100644 (file)
@@ -1,5 +1,5 @@
 ;;;; exceptions.test --- tests for Guile's exception handling  -*- scheme -*-
-;;;; Copyright (C) 2001, 2003, 2004, 2006 Free Software Foundation, Inc.
+;;;; Copyright (C) 2001, 2003, 2004, 2006, 2010 Free Software Foundation, Inc.
 ;;;;
 ;;;; This library is free software; you can redistribute it and/or
 ;;;; modify it under the terms of the GNU Lesser General Public
@@ -75,9 +75,9 @@
        (lambda () (throw 'a))
        (lambda (x y . rest) #f))))
 
-  (with-test-prefix "with lazy handler"
+  (with-test-prefix "with pre-unwind handler"
 
-    (pass-if "lazy fluid state"
+    (pass-if "pre-unwind fluid state"
       (equal? '(inner outer arg)
        (let ((fluid-parm (make-fluid))
             (inner-val #f))
                     (lambda (key . args)
                       (push 2))))
 
-  (throw-test "catch and lazy catch"
+  (throw-test "catch and with-throw-handler"
              '(1 2 3 4)
              (catch 'a
                     (lambda ()
                       (push 1)
-                      (lazy-catch 'a
-                                  (lambda ()
-                                    (push 2)
-                                    (throw 'a))
-                                  (lambda (key . args)
-                                    (push 3))))
+                      (with-throw-handler
+                        'a
+                        (lambda ()
+                          (push 2)
+                          (throw 'a))
+                        (lambda (key . args)
+                          (push 3))))
                     (lambda (key . args)
                       (push 4))))
 
-  (throw-test "catch with rethrowing lazy catch handler"
+  (throw-test "catch with rethrowing throw-handler"
              '(1 2 3 4)
              (catch 'a
                     (lambda ()
                       (push 1)
-                      (lazy-catch 'a
-                                  (lambda ()
-                                    (push 2)
-                                    (throw 'a))
-                                  (lambda (key . args)
-                                    (push 3)
-                                    (apply throw key args))))
+                      (with-throw-handler
+                        'a
+                        (lambda ()
+                          (push 2)
+                          (throw 'a))
+                        (lambda (key . args)
+                          (push 3)
+                          (apply throw key args))))
                     (lambda (key . args)
                       (push 4))))
 
                     (lambda (key . args)
                       (push 4))))
 
-  (throw-test "effect of lazy-catch unwinding on throw to another key"
-             '(1 2 3 5 7)
-             (catch 'a
-                    (lambda ()
-                      (push 1)
-                      (lazy-catch 'b
-                                  (lambda ()
-                                    (push 2)
-                                    (catch 'a
-                                           (lambda ()
-                                             (push 3)
-                                             (throw 'b))
-                                           (lambda (key . args)
-                                             (push 4))))
-                                  (lambda (key . args)
-                                    (push 5)
-                                    (throw 'a)))
-                      (push 6))
-                    (lambda (key . args)
-                      (push 7))))
-
   (throw-test "effect of with-throw-handler not-unwinding on throw to another key"
              '(1 2 3 5 4 6)
              (catch 'a
                     (lambda (key . args)
                       (push 7))))
 
-  (throw-test "lazy-catch chaining"
-             '(1 2 3 4 6 8)
-             (catch 'a
-               (lambda ()
-                 (push 1)
-                 (lazy-catch 'a
-                   (lambda ()
-                     (push 2)
-                     (lazy-catch 'a
-                        (lambda ()
-                         (push 3)
-                         (throw 'a))
-                       (lambda (key . args)
-                         (push 4)))
-                     (push 5))
-                   (lambda (key . args)
-                     (push 6)))
-                 (push 7))
-               (lambda (key . args)
-                 (push 8))))
-
   (throw-test "with-throw-handler chaining"
              '(1 2 3 4 6 8)
              (catch 'a
                (lambda (key . args)
                  (push 8))))
 
-  (throw-test "with-throw-handler inside lazy-catch"
-             '(1 2 3 4 6 8)
-             (catch 'a
-               (lambda ()
-                 (push 1)
-                 (lazy-catch 'a
-                   (lambda ()
-                     (push 2)
-                     (with-throw-handler 'a
-                        (lambda ()
-                         (push 3)
-                         (throw 'a))
-                       (lambda (key . args)
-                         (push 4)))
-                     (push 5))
-                   (lambda (key . args)
-                     (push 6)))
-                 (push 7))
-               (lambda (key . args)
-                 (push 8))))
-
-  (throw-test "lazy-catch inside with-throw-handler"
-             '(1 2 3 4 6 8)
-             (catch 'a
-               (lambda ()
-                 (push 1)
-                 (with-throw-handler 'a
-                   (lambda ()
-                     (push 2)
-                     (lazy-catch 'a
-                        (lambda ()
-                         (push 3)
-                         (throw 'a))
-                       (lambda (key . args)
-                         (push 4)))
-                     (push 5))
-                   (lambda (key . args)
-                     (push 6)))
-                 (push 7))
-               (lambda (key . args)
-                 (push 8))))
-
   (throw-test "throw handlers throwing to each other recursively"
              '(1 2 3 4 8 6 10 12)
              (catch #t
                (lambda (key . args)
                  (push 12))))
 
-  (throw-test "repeat of previous test but with lazy-catch"
-             '(1 2 3 4 8 12)
-             (catch #t
-                (lambda ()
-                 (push 1)
-                 (lazy-catch 'a
-                    (lambda ()
-                     (push 2)
-                     (lazy-catch 'b
-                       (lambda ()
-                         (push 3)
-                         (lazy-catch 'c
-                           (lambda ()
-                             (push 4)
-                             (throw 'b)
-                             (push 5))
-                           (lambda (key . args)
-                             (push 6)
-                             (throw 'a)))
-                         (push 7))
-                       (lambda (key . args)
-                         (push 8)
-                         (throw 'c)))
-                     (push 9))
-                   (lambda (key . args)
-                     (push 10)
-                     (throw 'b)))
-                 (push 11))
-               (lambda (key . args)
-                 (push 12))))
-
   (throw-test "throw handler throwing to lexically inside catch"
              '(1 2 7 5 4 6 9)
              (with-throw-handler 'a