24 |
Discussion |
Discussion |
25 |
========== |
========== |
26 |
|
|
27 |
|
There are two ways that longjmp may be invoked from a Scheme callback: |
28 |
|
raising an exception or invoking a continuation. Exceptions can be |
29 |
|
caught using scm_internal_catch, so it could be argued that the new |
30 |
|
interface only needs to block continuations. |
31 |
|
|
32 |
|
However there are two problems with this: firstly it's unlikely that |
33 |
|
anybody would want to block continuations without also catching |
34 |
|
exceptions, so it's more convenient to use a single facility set up |
35 |
|
both types of blocking. Secondly, the fact that exceptions and |
36 |
|
continuations can be treated separately in Guile is just an |
37 |
|
implementation detail: in general in Scheme it's possible to use |
38 |
|
continuations to implement an exception mechanism, and it's |
39 |
|
undesirable to tie a new language feature to an implementation detail |
40 |
|
when it can be avoided, even at the C level. |
41 |
|
|
42 |
|
Hence, the interface should take at least a) the callback to be |
43 |
|
protected b) and exception handler and associated handler data to be |
44 |
|
passed to scm_internal_catch. |
45 |
|
|
46 |
|
On which side of the continuation barrier should be exception handler |
47 |
|
be installed? Logically it belongs on the same side as the callback: |
48 |
|
i.e., if the callback raises an exception then the handler can catch |
49 |
|
it without crossing it the continuation barrier. But what happens if |
50 |
|
the handler raises another exception? This doesn't seem like an |
51 |
|
important concern, since the hander is under control of the same C |
52 |
|
code that is trying to protect itself. It should be sufficient to |
53 |
|
warn in the documentation that such exceptions produce undefined |
54 |
|
behaviour and allow them to cross the continuation barrier. |
55 |
|
|
56 |
|
How should the callback procedure be passed to the interface and |
57 |
|
invoked? Should it be like scm_internal_catch where it's passed as a |
58 |
|
C procedure (scm_t_catch_body) which is applied to user data (void *)? |
59 |
|
For a procedure designed to be used from C, this is the most |
60 |
|
convenient, since constructing closures in C is not very convenient. |
61 |
|
It also gives symmetry with scm_internal_catch. |
62 |
|
|
63 |
|
Hence the first four arguments to the C interface should be the same as for |
64 |
|
the old scm_internal_cwdr: |
65 |
|
|
66 |
|
scm_t_catch_body body, void *body_data, |
67 |
|
scm_t_catch_handler handler, void *handler_data |
68 |
|
|
69 |
|
The return value from the interface should be the result of calling |
70 |
|
the body, unless an exception occurred in which case it's the result |
71 |
|
of calling the handler. So the return type is SCM, as for |
72 |
|
scm_internal_catch. |
73 |
|
|
74 |
|
Yet to be discussed: libguile usage and threads, error handling and |
75 |
|
reporting, convenience of use, Scheme-level interface. |
76 |
|
|
77 |
Proposal |
Proposal |
78 |
======== |
======== |