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

catch-cancel

1 view
Skip to first unread message

Alice Hartley

unread,
Jun 3, 1995, 3:00:00 AM6/3/95
to
At 4:55 PM 5/31/95, Michael Korcuska wrote:
>In article <gclements-3105951036250001@mac21_58.keps.com>,
>gcle...@keps.com (Geoffrey Clements) wrote:
>
>>
>> I belive the problem is that the scope that (throw *tag* "Cancelled") is
>> different from the scope that (catch *tag ...) is set up in. The throw is
>> called from low level event handling code which is different from where
>> the loop is running. I also think that the throw-cancel/catch-cancel
>> mechanism is reserved for modal-dialogs. (i'm relatively new to MCL so I
>> could be wrong about this.)
>
>(my email reply to you previously was incorrect, Geoff. sorry about that)
>
>I originally suspected this too. But if this were the case then (throw
>:foo) would cause an error. My best guess (from Chris Wisdo actually) is
>that the event processing code is setting up a (catch :cancel) inside the
>dynamic scope of my catch. Anybody at Apple/Digitool care to comment on
>this?
>

Yes its true that there is a (catch :cancel ...) withing the event processing
code. It should probably be mentioned somewhere in the documentation
that MCL uses the catch tag :cancel for some internal purposes.


Al...@digitool.com

Kalman Reti

unread,
Jun 5, 1995, 3:00:00 AM6/5/95
to

Maybe the catch tag should be something like the (this is from memory so
I might not get it quite right) Lispm tag: if-you-throw-to-this-you-deserve-to-lose.

>
>
>Al...@digitool.com

Kalman Reti

unread,
Jun 5, 1995, 3:00:00 AM6/5/95
to
At 9:58 6/5/95, Kalman Reti wrote:
>At 18:49 6/3/95, Alice Hartley wrote:
>>At 4:55 PM 5/31/95, Michael Korcuska wrote:
>>>In article <gclements-3105951036250001@mac21_58.keps.com>,
>>>gcle...@keps.com (Geoffrey Clements) wrote:

[stuff removed]

>>>
>>
>>Yes its true that there is a (catch :cancel ...) withing the event processing
>>code. It should probably be mentioned somewhere in the documentation
>>that MCL uses the catch tag :cancel for some internal purposes.
>
>Maybe the catch tag should be something like the (this is from memory so
>I might not get it quite right) Lispm tag: if-you-throw-to-this-you-deserve-to-lose.

Sorry, it was too early in the morning. That suggestion of mine doesn't
apply here, since it needs to catch the :CANCEL throws sprinkled liberally
throughout the existing code.

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.

>
>>
>>
>>Al...@digitool.com

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

Kalman Reti

unread,
Jun 6, 1995, 3:00:00 AM6/6/95
to
At 8:55 6/5/95, Dave Yost wrote:
>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.)

Yes and no. If their cost (in terms of efficiency) were
equivalent you could make a case for it, but throwing
is often more efficient than signalling a condition. In
fact, most implementations of conditions are implemented
on top of throw.

>
>Also, you seem to leave out the possibility of
>per-thread condition handlers. Did you mean to do that?

Only in the context of this discussion. The original problem was that
someone had set up a window event handler that did a throw. However,
because MCL 3.0 handles events in a different process, the target of the
throw wasn't dynamically present when it was being executed. Of course,
the vast majority of all condition handlers are per-process.

>
>Dave Yost
> @ .com

Michael Korcuska

unread,
Jun 6, 1995, 3:00:00 AM6/6/95
to
In article <v02110100abfa24ce31eb@[198.112.74.171]>,
re...@cambridge.apple.com (Kalman Reti) wrote:

>
> >
> >Also, you seem to leave out the possibility of
> >per-thread condition handlers. Did you mean to do that?
>
> Only in the context of this discussion. The original problem was that
> someone had set up a window event handler that did a throw. However,
> because MCL 3.0 handles events in a different process, the target of the
> throw wasn't dynamically present when it was being executed. Of course,
> the vast majority of all condition handlers are per-process.
>

Just to clarify, the original problem was in 2.0, not 3.0. The target of
the the throw *was* dynamically present. It's just that the event
handling system introduced a (catch :cancel) between the (catch :cancel)
and the throw. Any tag other than :cancel worked fine. Alice Hartley has
helpfully confirmed this.

But MCL 3.0 will have threads and, I assume, the event processing will be
handled by a separate thread. I guess this means that in 3.0 the catch
won't be dynamically present. This raises the question of how
block/return will behave in a multi-threaded MCL?

Michael Korcuska
Institute for the Learning Sciences
Northwestern University
korc...@ils.nwu.edu

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 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