Search code examples
c#c++d

Is D's scope failure/success/exit necessary?


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.


Solution

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