Thanks everyone for the discussion!
I really like the
throws! marker idea. (I wonder by the way if it should be spelled
throws? to indicate that we don't know if there are any circumstances under which the function will actually throw -- thoughts? I'll keep calling it
throws! for now to avoid confusion.)
This would give us semantics that are close to C++: If the function throws and you don't have an exception handler, the program terminates; optionally, you can add a handler to catch the exception.
I assume we would disallow
throws! in user-written code (i.e. only allow it to be added to functions generated by ClangImporter)? Swift's philosophy is to be disciplined and explicit about exceptions, and it seems like allowing
throws! in pure Swift code would encourage programmers to be sloppy about exceptions. (Compiler complaining? Just put a
throws! on your function.)
We'd want to be able to use the
throws! concept in
@dynamicCallable, too, so that Python interop no longer needs the
.throwing to indicate that the user wants to handle exceptions. I see two ways of doing this:
throws! to be specified on
dynamicallyCall() to indicate that the
@dynamicCallable should have
throws! behavior. This would be a logical extension of what you can do today (where you can either put
dynamicallyCall() or not, and that propagates to the
@dynamicCallable), but it might be slightly strange to allow
throws! in just this one particular place in user code. Nevertheless, I think this is what I would prefer.
dynamicallyCall() is marked
throws, mark the
throws! (and not
throws, as is the case today). This would eliminate the need for
throws! in user code, but it would make it impossible to specify "you must handle exceptions thrown by this
My next steps
It sounds as if most here agree on the general direction, so here's what I'm planning to do:
Extend the C++ interop manifesto to capture what we've discussed here (i.e. exceptions trap by default but can optionally be caught).
Implement the "trap by default" behavior by installing a suitable personality routine. (It sounds from what @John_McCall says as if this may not work today.)
Write up a proposal for how
throws! should work. (IIUC this should take the format of a Swift Evolution proposal?)
I think it's likely that I would defer actual implementation of
throws! until we have some pieces of the more foundational C++ interop in place, as those seem higher priority. Does that sound acceptable?