Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

throw-catch :cancel

4 views
Skip to first unread message

Dave Yost

unread,
Jun 5, 1995, 3:00:00 AM6/5/95
to
In article <v02110105abf8da609000@[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

Barry Margolin

unread,
Jun 6, 1995, 3:00:00 AM6/6/95
to
In article <3qv9e6$m...@Yost.com> yo...@Yost.com (Dave Yost) writes:
>In article <v02110105abf8da609000@[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
barmar@{bbnplanet.com,near.net,nic.near.net}
Phone (617) 873-3126 - Fax (617) 873-5124

Chris Riesbeck

unread,
Jun 6, 1995, 3:00:00 AM6/6/95
to
In article <3r0vig$c...@tools.near.net>, bar...@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

Barry Margolin

unread,
Jun 8, 1995, 3:00:00 AM6/8/95
to
In article <riesbeck-060...@riesbeck.ils.nwu.edu> ries...@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.

Clint Hyde

unread,
Jun 9, 1995, 3:00:00 AM6/9/95
to
In article <3r7pi3$m...@tools.near.net> bar...@nic.near.net (Barry Margolin) writes:

--> In article <riesbeck-060...@riesbeck.ils.nwu.edu> ries...@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.

I've worked with several, and what happens is that you get an error
about "NO LEXICALLY VISIBLE CATCH FOR TAG 'FOO" because there isn't one,
as those kind of tags are "local" to an individual stack-group.

if you want one stack-group to have an effect on another one, you'll
have to do it in the more obvious way of setting some global variable,
or a slot in a shared object, or something easy like that.

if you know how to control your stack-groups, it's perhaps also possible
to force this differently with functions like stack-group-resume,
stack-group-return, stack-group-frame-return, or that sort of thing. I
have NEVER done this, and I think it's probably dangerous.

both Lucid and Allegro have these kinds of functions. my CLIM-based
window-debugger makes use of them, but the interesting ones are
undocumented functions--I had to guess at what they did and experiment
with them to decide which ones to use.

-- clint


Chris Riesbeck

unread,
Jun 9, 1995, 3:00:00 AM6/9/95
to
In article <3radk0$i...@info-server.bbn.com>, Clint Hyde <ch...@bbn.com> wrote:

> In article <3r7pi3$m...@tools.near.net> bar...@nic.near.net (Barry
Margolin) writes:
>

>... 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.
>
> I've worked with several, and what happens is that you get an error
> about "NO LEXICALLY VISIBLE CATCH FOR TAG 'FOO" because there isn't one,
> as those kind of tags are "local" to an individual stack-group.

Right, that's the problem with CATCH/THROW, though the message seems
strange, since CATCH tags are lexically scoped.

For BLOCK/RETURN-FROM, at least in the code I posted, the tag *is* lexically
visible, but, I now realize, you can't be sure it won't be disestablished.

--
Chris

Chris Riesbeck

unread,
Jun 9, 1995, 3:00:00 AM6/9/95
to
In article <3r7pi3$m...@tools.near.net>, bar...@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

Chris Riesbeck

unread,
Jun 12, 1995, 3:00:00 AM6/12/95
to
In article <riesbeck-090...@riesbeck.ils.nwu.edu>,
ries...@ils.nwu.edu (Chris Riesbeck) wrote:

> In article <3radk0$i...@info-server.bbn.com>, Clint Hyde <ch...@bbn.com> wrote:
>
> > I've worked with several, and what happens is that you get an error
> > about "NO LEXICALLY VISIBLE CATCH FOR TAG 'FOO" because there isn't one,
> > as those kind of tags are "local" to an individual stack-group.
>
> Right, that's the problem with CATCH/THROW, though the message seems
> strange, since CATCH tags are lexically scoped.

Only one person caught me so far, but, yes that was supposed to read
"CATCH tags are *not* lexically scoped."

--
Chris

0 new messages