On Monday, 5 June 2017 at 14:05:27 UTC, Steven Schveighoffer
wrote:
I don't think this will work. Only throwing Error makes a
function nothrow. A nothrow function may not properly clean up
the stack while unwinding. Not because the stack unwinding code
skips over it, but because the compiler knows nothing can
throw, and so doesn't include the cleanup code.
If the function is @pure, then the only things it can set up will
be stored on local or GC data, and it won't matter if they're not
properly cleaned up, since they won't be accessible anymore.
I'm not 100% sure about that, though. Can a pure function do
impure things in its scope(exit) / destructor code?
Not to mention that only doing this for pure code eliminates
usages that sparked the original discussion, as my code
communicates with a database, and that wouldn't be allowed in
pure code.
It would work for sending to a database; but you would need to
use the functional programming idiom of "do 99% of the work in
pure functions, then send the data to the remaining 1% for impure
tasks".
A process's structure would be:
- Read the inputs from the socket (impure, no catching errors)
- Parse them and transform them into database requests (pure)
- Send the requests to the database (impure)
- Parse / analyse / whatever the results (pure)
- Send the results to the socket (impure)
And okay, yeah, that list isn't realistic. Using functional
programming idioms in real life programs can be a pain in the
ass, and lead to convoluted callback-based scaffolding and weird
data structures that you need to pass around a bunch of functions
that don't really need them.
The point is, you could isolate the pure data-manipulating parts
of the program from the impure IO parts; and encapsulate the
former in Error-catching blocks (which is convenient, since those
parts are likely to be more convoluted and harder to foolproof
than the IO parts, therefore likely to throw more Errors).
Then if an Error occurs, you can close the connection the client
(maybe send them an error packet beforehand), close the database
file descriptor, log an error message, etc.