From: Dave Yost
Subject: Re: throw-catch :cancel
Date:
Message-ID: <3qv9e6$m4@Yost.com>
In article <·····················@[198.112.74.171]>,
>
>I've previously expressed the opinion that handling the cancel button on
>dialogs by doing a throw to :cancel is just a bad idea. It should signal a
>condition, just like anything else. This would allow the user to use a
>global condition handler instead of a stack-based one which wouldn't be
>applicable when the event is handled in another process.
Is the more general statement true?
Are throw/catch obsoleted by conditions in general?
(I came in after conditions were invented.)
Also, you seem to leave out the possibility of
per-thread condition handlers. Did you mean to do that?
Dave Yost
@ .com
In article <·········@Yost.com> ····@Yost.com (Dave Yost) writes:
>In article <·····················@[198.112.74.171]>,
>>I've previously expressed the opinion that handling the cancel button on
>>dialogs by doing a throw to :cancel is just a bad idea. It should signal a
>>condition, just like anything else. This would allow the user to use a
>>global condition handler instead of a stack-based one which wouldn't be
>>applicable when the event is handled in another process.
The CL condition system doesn't have global condition handlers, only
stack-based ones. Then again, CL doesn't have multiple threads, either; I
suppose an implementation that adds one could add the other as well.
Symbolics CL has global handlers, but I found that they were difficult to
use. What if two applications both try to establish a global handler for
the same condition?
>Is the more general statement true?
>Are throw/catch obsoleted by conditions in general?
Conditions can be considered a generalization of throw/catch. The tags in
catch and throw have to match exactly, while conditions use a hierarchy of
condition classes; thus, a handler for ERROR can catch a signal of
TYPE-ERROR.
In fact, conditions can (and often *are*) implemented using catch and
throw.
--
Barry Margolin
BBN Planet Corporation, Cambridge, MA
······@{bbnplanet.com,near.net,nic.near.net}
Phone (617) 873-3126 - Fax (617) 873-5124
In article <··········@tools.near.net>, ······@nic.near.net (Barry
Margolin) wrote:
> The CL condition system doesn't have global condition handlers, only
> stack-based ones. Then again, CL doesn't have multiple threads, either; I
> suppose an implementation that adds one could add the other as well.
In the discussion on comp.lang.lisp.mcl where this began, my solution
was to use BLOCK/RETURN-FROM rather than CATCH/THROW. I've included
the code below for reference.
Is this approach is guaranteed to work in any multi-threaded CL?
;;; A simple example of how to put up a window with a CANCEL button
;;; with a function attached that can interrupt a search process.
;;;
;;; Uses lexically-scoped BLOCK/RETURN-FROM tags rather
;;; than dynamically-scoped CATCH/THROW tags.
;;;
;;; Implementation notes:
;;;
;;; 1. The window is hidden until the UNWIND-PROTECT starts.
;;; 2. Instead of BLOCK, we could use (RETURN-FROM TEST-CANCEL ...).
;;; 3. For clarity and generality, both return values (:CANCELLED
;;; and :FINISHED) are specified by the calling function.
(defun test-cancel ()
(block search-loop
(let ((w (make-button-window
#'(lambda (dialog-item)
(declare (ignore dialog-item))
(return-from search-loop :cancelled)))))
(unwind-protect
(progn (window-show w)
(dotimes (i 200 :finished) ;; standing in for a real search
(princ ".")))
(window-close w)))))
(defun make-button-window (exit-fn)
(make-instance 'window
:window-show nil
:view-position :centered
:view-size ·@(100 100)
:view-subviews (list (make-cancel-button exit-fn))))
(defun make-cancel-button (exit-fn)
(make-dialog-item 'button-dialog-item
·@(20 30) ·@(60 20)
"Cancel"
exit-fn))
--
Chris
In article <·························@riesbeck.ils.nwu.edu> ········@ils.nwu.edu (Chris Riesbeck) writes:
>In the discussion on comp.lang.lisp.mcl where this began, my solution
>was to use BLOCK/RETURN-FROM rather than CATCH/THROW. I've included
>the code below for reference.
>
>Is this approach is guaranteed to work in any multi-threaded CL?
Nothing is guaranteed, since there's no standard for multi-threaded CL.
I haven't seen the discussion in c.l.l.mcl, so I don't know what problem
you're trying to solve. Do you want one thread to be able to cause a
function in another thread to return? The only multi-threaded Lisp I have
lots of experience with is Symbolics CL, and I don't think it handled
RETURN or THROW from a different thread than the BLOCK or CATCH.
--
Barry Margolin
BBN Planet Corporation, Cambridge, MA
······@{bbnplanet.com,near.net,nic.near.net}
Phone (617) 873-3126 - Fax (617) 873-5124
In article <··········@tools.near.net>, ······@nic.near.net (Barry
Margolin) wrote:
> ... Do you want one thread to be able to cause a
> function in another thread to return? The only multi-threaded Lisp I have
> lots of experience with is Symbolics CL, and I don't think it handled
> RETURN or THROW from a different thread than the BLOCK or CATCH.
OK. Brain cells finally started working again and I re-read the
implementation note in Chapter 3 (p 44) and the scope/extent rules for
BLOCK tags. As I now understand it, the problem with code like this:
In thread A:
(block FOO
-- start code running in thread B, passing it the closure
#'(lambda () (return-from FOO nil))
-- other stuff in block FOO, thread A)
-- other stuff in thread A, after block FOO
is that FOO may be disestablished at any time in thread A.
The original MCL code explicitly deleted the closure in thread B
before exiting block FOO, so it's probably OK.
--
Chris