Jump to page: 1 26  
Page
Thread overview
DIP 1002 (TryElseExpression) added to the queue
Sep 27, 2016
Dicebot
Sep 27, 2016
Jonathan M Davis
Sep 27, 2016
Idan Arye
Sep 27, 2016
pineapple
Sep 27, 2016
pineapple
Sep 27, 2016
John Colvin
Sep 28, 2016
Walter Bright
Sep 30, 2016
Nick Treleaven
Sep 28, 2016
Walter Bright
Sep 28, 2016
John Colvin
Sep 28, 2016
Walter Bright
Sep 28, 2016
ikod
Sep 28, 2016
pineapple
Sep 28, 2016
Andrea Fontana
Sep 28, 2016
pineapple
Sep 28, 2016
Dicebot
Sep 28, 2016
Idan Arye
Sep 28, 2016
Dicebot
Sep 28, 2016
John Colvin
Sep 28, 2016
pineapple
Sep 29, 2016
John Colvin
Sep 28, 2016
pineapple
Sep 28, 2016
pineapple
Sep 29, 2016
Walter Bright
Sep 29, 2016
Timon Gehr
Sep 28, 2016
Idan Arye
Sep 29, 2016
Walter Bright
Sep 29, 2016
Jack Stouffer
Sep 29, 2016
Marc Schütz
Sep 29, 2016
Walter Bright
Oct 02, 2016
Marc Schütz
Sep 29, 2016
Nick Treleaven
Sep 29, 2016
pineapple
Oct 01, 2016
crimaniak
Sep 29, 2016
ikod
Sep 28, 2016
Walter Bright
Sep 28, 2016
Jack Stouffer
Sep 28, 2016
Jack Stouffer
Sep 28, 2016
John Colvin
Sep 29, 2016
Jack Stouffer
Sep 29, 2016
pineapple
September 27, 2016
https://github.com/dlang/DIPs/blob/master/DIPs/DIP1002.md

PR: https://github.com/dlang/DIPs/pull/43

Abstract:

In Python, the try/catch/finally syntax is augmented with an additional clause, termed else. It is a fantastically useful addition to the conventional syntax. It works like this:

```
    try:
        do_something()
    except Exception as e:
        pass # Runs when an error inheriting from Exception was raised
    else:
        pass # Runs when no error was raised
    finally:
        pass # Runs unconditionally, evaluates last
```
September 27, 2016
On Tuesday, September 27, 2016 09:30:10 Dicebot via Digitalmars-d wrote:
> https://github.com/dlang/DIPs/blob/master/DIPs/DIP1002.md
>
> PR: https://github.com/dlang/DIPs/pull/43
>
> Abstract:
>
> In Python, the try/catch/finally syntax is augmented with an additional clause, termed else. It is a fantastically useful addition to the conventional syntax. It works like this:
>
> ```
>      try:
>          do_something()
>      except Exception as e:
>          pass # Runs when an error inheriting from Exception was
> raised
>      else:
>          pass # Runs when no error was raised
>      finally:
>          pass # Runs unconditionally, evaluates last
> ```

And why not just put the code that would go in the else at the end of the try block? Just like with this proposed else, the code would only run if the preceding code didn't throw any exceptions. This just seems like an attempt to make D more like python rather than to add anything useful.

- Jonathan M Davis

September 27, 2016
On Tuesday, 27 September 2016 at 09:48:42 UTC, Jonathan M Davis wrote:
> On Tuesday, September 27, 2016 09:30:10 Dicebot via Digitalmars-d wrote:
>> https://github.com/dlang/DIPs/blob/master/DIPs/DIP1002.md
>>
>> PR: https://github.com/dlang/DIPs/pull/43
>>
>> Abstract:
>>
>> In Python, the try/catch/finally syntax is augmented with an additional clause, termed else. It is a fantastically useful addition to the conventional syntax. It works like this:
>>
>> ```
>>      try:
>>          do_something()
>>      except Exception as e:
>>          pass # Runs when an error inheriting from Exception was
>> raised
>>      else:
>>          pass # Runs when no error was raised
>>      finally:
>>          pass # Runs unconditionally, evaluates last
>> ```
>
> And why not just put the code that would go in the else at the end of the try block? Just like with this proposed else, the code would only run if the preceding code didn't throw any exceptions. This just seems like an attempt to make D more like python rather than to add anything useful.
>
> - Jonathan M Davis

Exceptions thrown in the `else` clause are not caught in the catch/expect clauses. This gives you finer grained control:


    try {
        auto f1 = File("f1.txt");
    } catch (ErrnoException) {
        // f1.txt not found? no biggie...
    } else {
        // This won't happen if we can't open f1.txt

        // If we can't open f2 we don't want to catch the exception:
        auto f2 = File("f2.txt", "w");

        // Do stuff with f1 and f2
    }

    // This will still happen even if we can't open f1.txt


BTW, if this feature is ever implemented in D, it's important that the else clause will continue the try clause's scope.
September 27, 2016
On Tuesday, 27 September 2016 at 09:48:42 UTC, Jonathan M Davis wrote:
> And why not just put the code that would go in the else at the end of the try block? Just like with this proposed else, the code would only run if the preceding code didn't throw any exceptions. This just seems like an attempt to make D more like python rather than to add anything useful.
>
> - Jonathan M Davis

This is a commonly-used tool that makes code more readable and cuts down on programmer error.

It's far more concise and digestible than the functional equivalent, which is _not_ to put the code at the end of the `try` block, it's to put it in the `finally` block - refer to the DIP's example for how that works.

This is the most important difference between using `else` and doing what you described: Exceptions thrown by the code in the `else` block are not caught by the `catch` statements intended to handle errors by the operation in the `try` block, but not to handle errors resulting from attempting to handle a success state.
September 27, 2016
On Tuesday, 27 September 2016 at 10:05:20 UTC, Idan Arye wrote:
> BTW, if this feature is ever implemented in D, it's important that the else clause will continue the try clause's scope.

The catch and finally clauses do currently continue the scope, right? (If they don't, they probably should, too.)

September 27, 2016
On Tuesday, 27 September 2016 at 09:30:10 UTC, Dicebot wrote:
> https://github.com/dlang/DIPs/blob/master/DIPs/DIP1002.md
>
> PR: https://github.com/dlang/DIPs/pull/43
>
> Abstract:
>
> In Python, the try/catch/finally syntax is augmented with an additional clause, termed else. It is a fantastically useful addition to the conventional syntax. It works like this:
>
> ```
>     try:
>         do_something()
>     except Exception as e:
>         pass # Runs when an error inheriting from Exception was raised
>     else:
>         pass # Runs when no error was raised
>     finally:
>         pass # Runs unconditionally, evaluates last
> ```

What's annoying is that we already have finally,  which can be reproduced with other language features:

{
    /*finally*/ scope (exit) {}
    try {
        do_something();
    } catch (Exception e) {}
}

but we don't (yet) have catch else, which is harder to immitate. Options are:
A) the else clause is nothrow (in which case it can just go last inside the try)
or
B) store a flag and have to use immitation finally:

{
    /*finally*/ scope (exit) {}
    bool exceptionThrown = false;
    try {
        doSomething();
    } catch (Exception e) {
        exceptionThrown = true;
    }
    /*else*/ if (!exceptionThrown) {}
}
September 27, 2016
On 9/27/16 6:55 AM, John Colvin wrote:
>
> What's annoying is that we already have finally,  which can be
> reproduced with other language features:
>
> {
>     /*finally*/ scope (exit) {}
>     try {
>         do_something();
>     } catch (Exception e) {}
> }

Hm... I always thought scope(exit) is lowered to:

try
{
}
finally
{
   // scope exit code here
}

Which one is the building block? ;)

> but we don't (yet) have catch else, which is harder to immitate. Options
> are:
> A) the else clause is nothrow (in which case it can just go last inside
> the try)
> or
> B) store a flag and have to use immitation finally:
>
> {
>     /*finally*/ scope (exit) {}
>     bool exceptionThrown = false;
>     try {
>         doSomething();
>     } catch (Exception e) {
>         exceptionThrown = true;
>     }
>     /*else*/ if (!exceptionThrown) {}
> }

I tried a few things, including scope(success), but it doesn't seem doable without an extra piece of data.

Essentially, the else clause allows you to split your try block into catch-protected code, and non-catch-protected code.

Seems like a worthwhile addition, if easily implemented.

-Steve
September 27, 2016
On 9/27/2016 6:22 AM, Steven Schveighoffer wrote:
> Hm... I always thought scope(exit) is lowered to:
>
> try
> {
> }
> finally
> {
>    // scope exit code here
> }
>
> Which one is the building block? ;)

try/catch/finally is the building block, other constructs are lowered to that.

September 27, 2016
On 9/27/2016 2:30 AM, Dicebot wrote:
> https://github.com/dlang/DIPs/blob/master/DIPs/DIP1002.md
>
> PR: https://github.com/dlang/DIPs/pull/43
>
> Abstract:
>
> In Python, the try/catch/finally syntax is augmented with an additional clause,
> termed else. It is a fantastically useful addition to the conventional syntax.
> It works like this:
>
> ```
>     try:
>         do_something()
>     except Exception as e:
>         pass # Runs when an error inheriting from Exception was raised
>     else:
>         pass # Runs when no error was raised
>     finally:
>         pass # Runs unconditionally, evaluates last
> ```

The DIP says that a state variable is currently necessary, but that is incorrect:

try
{
    scope (exit)
    {
        Runs unconditionally, evaluates last
    }
    scope (success)
    {
        runs when no error was raised
    }
    do_something();
}
catch (Exception e)
{
    Runs when an error inheriting from Exception was raised
}

Implementation:

  The try/catch/else/finally could be 'lowered' into the above form.

These references should be included in the DIP:

  http://dlang.org/spec/statement.html#ScopeGuardStatement
  http://dlang.org/exception-safe.html

My opinion:

Due to the existence of the ScopeGuardStatement, I feel this new syntax is redundant and needs a much better justification.
September 28, 2016
On Wednesday, 28 September 2016 at 04:23:56 UTC, Walter Bright wrote:
> On 9/27/2016 2:30 AM, Dicebot wrote:
>> https://github.com/dlang/DIPs/blob/master/DIPs/DIP1002.md
>>
>> PR: https://github.com/dlang/DIPs/pull/43
>>
>> Abstract:
>>
>> In Python, the try/catch/finally syntax is augmented with an additional clause,
>> termed else. It is a fantastically useful addition to the conventional syntax.
>> It works like this:
>>
>> ```
>>     try:
>>         do_something()
>>     except Exception as e:
>>         pass # Runs when an error inheriting from Exception was raised
>>     else:
>>         pass # Runs when no error was raised
>>     finally:
>>         pass # Runs unconditionally, evaluates last
>> ```
>
> The DIP says that a state variable is currently necessary, but that is incorrect:
>
> try
> {
>     scope (exit)
>     {
>         Runs unconditionally, evaluates last
>     }
>     scope (success)
>     {
>         runs when no error was raised
>     }
>     do_something();
> }
> catch (Exception e)
> {
>     Runs when an error inheriting from Exception was raised
> }


That's not the same. Exceptions thrown in the success block can be caught by the catch.  That scope (success) block is equivalent to just putting its contents immediately after do_something().

« First   ‹ Prev
1 2 3 4 5 6