When using a language that has try/catch/finally, are D's failure/success/exit scope statements still useful? D doesn't seem to have finally which may explain why those statements are used in D. But with a language like C# is it useful? I am designing a language so if I see many pros I'll add it in.
scope(X)
isn't necessary in the same way that for
isn't necessary provided you have if
and goto
.
Here's a paraphrased example from some code I've been writing today:
sqlite3* db;
sqlite3_open("some.db", &db);
scope(exit) sqlite3_close(db);
sqlite3_stmt* stmt;
sqlite3_prepare_v2(db, "SELECT * FROM foo;", &stmt);
scope(exit) sqlite3_finalize(stmt);
// Lots of stuff...
scope(failure) rollback_to(current_state);
make_changes_with(stmt);
// More stuff...
return;
Contrast this to using try/catch:
sqlite3* db;
sqlite3_open("some.db", &db);
try
{
sqlite3_stmt* stmt;
sqlite3_prepare_v2(db, "SELECT * FROM foo;", &stmt);
try
{
// Lots of stuff...
try
{
make_changes_with(stmt);
// More stuff...
}
catch( Exception e )
{
rollback_to(current_state);
throw;
}
}
finally
{
sqlite3_finalize(stmt);
}
}
finally
{
sqlite3_close(db);
}
The code has turned into spaghetti, spreading the error recovery all over the shop and forcing a level of indentation for every try block. The version using scope(X) is, in my opinion, significantly more readable and easier to understand.