September 29, 2016
On Wednesday, 28 September 2016 at 21:00:00 UTC, Steven Schveighoffer wrote:
>> Moreover, Idan's suggestions about scope sharing make sense to me and I
>> don't think his line of thinking would be compatible with doing it the
>> way you suggest.
>
> Declaring variables that you need in the right scopes is pretty straightforward. Having scopes magically continue around other separate scopes (catch scopes) doesn't look correct. I get why it's desired, but it doesn't look clean at all.

Assuming for a minute that we want some form of DIP1002, we might be able to extend the `try` scope in an interesting way:

try {
    auto f = foo();
}
catch (Exception) {
    ...
}
finally (bool ok) { // true if no exception
    bar();
    __guard (ok) f.baz();
    f.baz(); // error: f not in scope
}

Here the guard statement is a runtime check of `ok`, but it has the compile-time effect of enabling the `try` scope to be extended. Obviously this is a bit extreme if it was the only use of the guard statement, but the guard statement could be useful in other situations too (e.g. non-null code checked at compile-time).

Note that finally(bool) is more flexible than finally/else as you can interleave code arbitrarily. __guard makes it clearer something special is happening rather than just implicitly extending `try` scope in the `else` clause. Also, 'else' is not clear enough IMO.
September 29, 2016
On Thursday, 29 September 2016 at 10:51:01 UTC, Nick Treleaven wrote:
> Note that finally(bool) is more flexible than finally/else as you can interleave code arbitrarily. __guard makes it clearer something special is happening rather than just implicitly extending `try` scope in the `else` clause. Also, 'else' is not clear enough IMO.

While I think finally(bool) is a decent approach, the languages that currently integrate this concept into their error handling - Python and Ruby to my knowledge - all use `else`. Clarity is not a good argument, because those who are already proficient in languages other than D will expect the syntax to be consistent with other languages. It would be like some language using foolishly using `elsif instead of `else if`. (Dammit, Perl.)

September 29, 2016
On Wednesday, 28 September 2016 at 22:12:27 UTC, Idan Arye wrote:
>     Foo foo;
>     try {
>         foo = Foo();
>     } catch (FooCreationException) {
>         // ...
>     } else {
>         foo.doSomethingWithFoo();
>     }
>     // foo exists here - it could be initialized, it could be not...

And `Foo` could have `@disabled this()`, so you simply _can't_ declare it without initializing it (or use the dirty `Foo foo = Foo.init` workaround). But of course, that's a corner case...
September 29, 2016
On 09/29/2016 03:49 AM, John Colvin wrote:
> On Wednesday, 28 September 2016 at 23:44:19 UTC, Andrei Alexandrescu wrote:
>> On 9/28/16 7:40 PM, Andrei Alexandrescu wrote:
>>>
>>> // With scope
>>> void assertNot(string s)
>>> {
>>>     try { scope(success) assert(0, s); decode(s,DecodeMode.STRICT); }
>>>     catch (DecodeException e) {}
>>> }
>>
>> Sorry, this is not semantically equivalent. Replace with:
>>
>> // With scope
>> void assertNot(string s)
>> {
>>     try { decode(s,DecodeMode.STRICT); }
>>     catch (DecodeException e) { return; }
>>     assert(0, s);
>> }
>>
>>
>> Andrei
>
> Aren't those the same, as assert won't ever throw a DecodeException?
>
> Simplest implementation:
>
> try {
>     decode(s,DecodeMode.STRICT);
>     assert(0, s);
> } catch (DecodeException e) {}

Correct, thanks. -- Andrei
September 29, 2016
On 9/28/16 6:50 AM, Jack Stouffer wrote:
> On Wednesday, 28 September 2016 at 10:45:11 UTC, Andrei Alexandrescu wrote:
>> Assertions such as "makes the code cleaner" are likely to add value
>> only if backed up by evidence (case studies, realistic examples).
>
> This is based on my anecdotal experience. I also posted an example in
> the original thread which was included in the DIP.
>
>> Porting motivating arguments from other languages is helpful only if
>> put in the context of D, e.g. Python does not have "scope" statements,
>> which makes matters different across the two languages.
>
> It was already shown in this thread how scope statements do not achieve
> the same effect as the try/else statement; the point still stands.

Thanks, Jack. Here I'm solely focused on making DIP1002 stronger so I've sent a number of suggestions that I believe would improve the proposal. Although you are free to argue here that in fact the proposal already is strong enough, this is not a "minimal requirements" setup in which a DIP is good to go as long as it passes a checklist. The demand here is elastic; the stronger the DIP, the better. Once submitted, if rejected, the only way to propose a similar feature is by authoring a new proposal with a completely novel perspective. So official review is an important milestone with a high bar. -- Andrei

September 29, 2016
On Thursday, 29 September 2016 at 12:24:31 UTC, Andrei Alexandrescu wrote:
> Once submitted, if rejected, the only way to propose a similar feature is by authoring a new proposal with a completely novel perspective. So official review is an important milestone with a high bar. -- Andrei

Ok, I see where you're coming from, you want DIPs to be arguments in and of themselves. I was looking at them from a community prospective, where the DIP is argued on the forms like with module proposals.
September 29, 2016
On Thursday, 29 September 2016 at 11:45:42 UTC, Marc Schütz wrote:
> On Wednesday, 28 September 2016 at 22:12:27 UTC, Idan Arye wrote:
>>     Foo foo;
>>     try {
>>         foo = Foo();
>>     } catch (FooCreationException) {
>>         // ...
>>     } else {
>>         foo.doSomethingWithFoo();
>>     }
>>     // foo exists here - it could be initialized, it could be not...
>
> And `Foo` could have `@disabled this()`, so you simply _can't_ declare it without initializing it (or use the dirty `Foo foo = Foo.init` workaround). But of course, that's a corner case...

This is actually 100% of why I think scope sharing between `try`, `catch`, `finally`, and `else` statements deserves consideration. `Foo` should not have to be mutable or rebindable in order to handle its success or error state in the other statements.

On Thursday, 29 September 2016 at 12:24:31 UTC, Andrei Alexandrescu wrote:
> Thanks, Jack. Here I'm solely focused on making DIP1002 stronger so I've sent a number of suggestions that I believe would improve the proposal. Although you are free to argue here that in fact the proposal already is strong enough, this is not a "minimal requirements" setup in which a DIP is good to go as long as it passes a checklist. The demand here is elastic; the stronger the DIP, the better. Once submitted, if rejected, the only way to propose a similar feature is by authoring a new proposal with a completely novel perspective. So official review is an important milestone with a high bar. -- Andrei

I do appreciate the feedback, by the way, which is why I submitted the recent PR.

One thing I'd point out: You rewrote my rewritten examples without using `else`, but as was stated immediately before I listed those examples:

> The best examples of code that can be more elegantly written using this
>`else` clause occur in application logic, such as the example described
> above where a values were read from sensors and saved to a server. However,
> there are a few places in Phobos that could be more readable and not
> require success flags if this new syntax were employed.


September 29, 2016
On 9/28/16 6:12 PM, Idan Arye wrote:
> On Wednesday, 28 September 2016 at 21:00:00 UTC, Steven Schveighoffer
> wrote:
>> Declaring variables that you need in the right scopes is pretty
>> straightforward. Having scopes magically continue around other
>> separate scopes (catch scopes) doesn't look correct. I get why it's
>> desired, but it doesn't look clean at all.
>
> Consider this:
>
>     try {
>         auto foo = Foo();
>     } catch (FooCreationException) {
>         // ...
>     } else {
>         foo.doSomethingWithFoo();
>     }
>     // foo does not exist here
>
> versus this:
>
>     Foo foo;
>     try {
>         foo = Foo();
>     } catch (FooCreationException) {
>         // ...
>     } else {
>         foo.doSomethingWithFoo();
>     }
>     // foo exists here - it could be initialized, it could be not...


This is what I meant:

{
    Foo foo;
    try {
        foo = Foo();
    } catch (FooCreationException) {
        // ...
    } else {
        foo.doSomethingWithFoo();
    }
    // foo exists here, but may or may not be correct. Don't use it.
    // in fact, don't write any code here.
}
// foo doesn't exist here, just like in other example.

-Steve
September 29, 2016
On 9/29/16 7:02 AM, pineapple wrote:
> On Thursday, 29 September 2016 at 10:51:01 UTC, Nick Treleaven wrote:
>> Note that finally(bool) is more flexible than finally/else as you can
>> interleave code arbitrarily. __guard makes it clearer something
>> special is happening rather than just implicitly extending `try` scope
>> in the `else` clause. Also, 'else' is not clear enough IMO.
>
> While I think finally(bool) is a decent approach, the languages that
> currently integrate this concept into their error handling - Python and
> Ruby to my knowledge - all use `else`. Clarity is not a good argument,
> because those who are already proficient in languages other than D will
> expect the syntax to be consistent with other languages. It would be
> like some language using foolishly using `elsif instead of `else if`.
> (Dammit, Perl.)

In fact, finally(bool) can be extended to:

enum ExceptionStatus
{
   success = 0,
   caughtException = 1,
   uncaughtException = 2
}

finally(ExceptionStatus)

Which has also been requested in the past.

-Steve
September 29, 2016
On 09/29/2016 09:00 AM, pineapple wrote:
> One thing I'd point out: You rewrote my rewritten examples without using
> `else`, but as was stated immediately before I listed those examples:
>
>> The best examples of code that can be more elegantly written using this
>> `else` clause occur in application logic, such as the example described
>> above where a values were read from sensors and saved to a server.
>> However,
>> there are a few places in Phobos that could be more readable and not
>> require success flags if this new syntax were employed.

In order to make this kind of argument work, you need evidence. The sensor example is weak because (a) it comes with a rich context that is only vaguely explained; (b) it is not shown translated in current D; (c) it comes from private correspondence - at best it should be from a visible project. As of right now, the argument about application code being more helped than library code is purely speculative.

That's why I also suggest looking at dub and github, which contain a good amount of D application code. You'd make a solid point if you showed how a few of those projects can be improved by the use of the proposed feature.


Andrei