December 11, 2020
On Friday, 11 December 2020 at 19:54:58 UTC, Jacob Carlborg wrote:
> On 2020-12-11 09:03, Guillaume Piolat wrote:
>> I'd be more excited about:
>> - throw-by-value exceptions
>> - a way to use exceptions in @nogc and even -betterC (There was a DIP for it, it was implemented, but doesn't work IIRC)
>> than improving error codes.
>
> I completely agree. Instead of this approach, the compiler could lower try/catch/finally/throw for a function to return tagged union of the success value and all the exceptions that can be thrown. Then one could easily throw any kind of types, not just classes inheriting from `Throwable`, including value types.

Feel free to submit a DIP. :)

My experience in the D community so far has been that large, ambitious projects tend to fail, but small, incremental improvements often succeed. If someone steps forward with a DIP and an implementation for throw-by-value exceptions (or some other improved error-handling mechanism), I'll be happy to support them, but I'm not going to be that person myself.
December 11, 2020
On Friday, 11 December 2020 at 03:54:53 UTC, NotSpooky wrote:
> What I usually do to avoid exceptions is using Nullable/Variant as the return type, as using it still needs checking.
> So, syntax sugar to return those seems like a nicer alternative with less changes to the compiler and less @s

The idea is that you will be able to mark your Nullable/Variant type as @nodiscard, and the compiler will warn you if you forget to check it.

Marking the type as @nodiscard also means you will not have to annotate the individual functions, so in practice the number of @s needed should be fairly small.
December 14, 2020
On Wednesday, 9 December 2020 at 10:10:40 UTC, Mike Parker wrote:
> This is the discussion thread for the first round of Community Review of DIP 1038, "@nodiscard":

This is a reply to Andrej Mitrovic's post in the Feedback Thread.
https://forum.dlang.org/post/gdjclwuwuoyqiftdercu@forum.dlang.org

> I think @nodiscard should not apply to void functions.
> (...)
> At least I can't think of use-cases for it having an effect on void functions.

There is a pattern that replaces `goto fail;` and `goto success;` style error handling with calls to (inner) functions in a return statement. It looks something like this:

```
struct Parser {
    S result;
    string error;

    void setError(string msg) {
        error = msg;
    }

    void parse(string s) {
        if (s.length == 0) {
            return setError("empty input");
        }
        if (!s.starsWith("MAGIC")) {
            return setError("wrong header");
        }
        // etc.
    }
}
```

This pattern is used in dmd:

https://github.com/dlang/dmd/blob/97aa2ae5ee19ce6a2979ca1627479df713f99252/src/dmd/expressionsem.d#L2524

https://github.com/dlang/dmd/blob/97aa2ae5ee19ce6a2979ca1627479df713f99252/src/dmd/expressionsem.d#L5383

Functions setError() yes() and no() should be called in a return statement, continuing afterwards could be considered a bug. One might want to apply @nodiscard to those functions so it will be caught by the compiler when you forget to prepend `return`.

For that to work however, @nodiscard should not have a special case for `void`.
December 16, 2020
On 2020-12-11 21:27, H. S. Teoh wrote:

> But I don't agree with this.
> 
> I used to write a lot of C++, where you can throw literally *anything*.
> It seems to be a good thing to allow maximum flexibility, but that
> actually hinders code interoperability: you cannot assume *anything*
> about something you caught, because it can literally be *any* type.  D's
> Throwable API is much better because it guarantees a minimal common
> interface that all catch blocks can depend on.  Having a standard .msg
> field that returns a string you can print to the user in the event you
> need to abort

Yeah, I've been thinking about how to best solve that. My vision extends a bit more than just a different implementation of exception handling. I want the error handling to be usable everywhere, including low level code. Ideally it should be usable without a runtime. As soon as you start requiring classes, that will impose limitations.

> e.g., is much more useful than an opaque type that you
> can't do anything with other than say "an error occurred, abort" -- what
> error? Don't know, can't know, the catch block in main() has no idea
> where it came from or what information might be encoded within.
> Knowledge about the error might only exist inside a 3rd party
> dependency.

In my vision it wouldn't be an opaque type. But it would be good to have a way to handle all errors in one place.

> Maximum flexibility isn't always a good thing.

I've been thinking about limiting the types to user defined types.

I should really try to write down my ideas regarding this.

-- 
/Jacob Carlborg
December 16, 2020
On Wed, Dec 16, 2020 at 08:49:41PM +0100, Jacob Carlborg via Digitalmars-d wrote:
> On 2020-12-11 21:27, H. S. Teoh wrote:
> 
> > But I don't agree with this.
> > 
> > I used to write a lot of C++, where you can throw literally *anything*.  It seems to be a good thing to allow maximum flexibility, but that actually hinders code interoperability: you cannot assume *anything* about something you caught, because it can literally be *any* type.  D's Throwable API is much better because it guarantees a minimal common interface that all catch blocks can depend on.  Having a standard .msg field that returns a string you can print to the user in the event you need to abort
> 
> Yeah, I've been thinking about how to best solve that. My vision extends a bit more than just a different implementation of exception handling. I want the error handling to be usable everywhere, including low level code.  Ideally it should be usable without a runtime. As soon as you start requiring classes, that will impose limitations.

Exceptions don't have to be classes, even though that's the most obvious way to implement it.  For example, it could be a runtime-defined struct that contains the most pertinent information, with an optional polymorphic reference to additional information that people might want to transmit along with their exceptions.


> > e.g., is much more useful than an opaque type that you can't do anything with other than say "an error occurred, abort" -- what error? Don't know, can't know, the catch block in main() has no idea where it came from or what information might be encoded within. Knowledge about the error might only exist inside a 3rd party dependency.
> 
> In my vision it wouldn't be an opaque type. But it would be good to have a way to handle all errors in one place.

It's not that the type itself is opaque, it's that since you can throw *any* arbitrary type, the catching code cannot predict in advance what the concrete type(s) the caught exception will be, and therefore it cannot make any assumptions about the type of the exception, including what operations are permitted on it.  It cannot assume there's a .msg field that contains an error message, for instance, since somebody could have thrown an int. Or any type without a .msg member, for that matter.


> > Maximum flexibility isn't always a good thing.
> 
> I've been thinking about limiting the types to user defined types.
[...]

Even so, if there is no standard API that exceptions must implement, then you cannot write top-level catch that does something useful (beyond just printing "Error" and aborting).  There must be some kind of minimum set of attributes that you can depend on, like a string .msg. Possibly also .file and .line.


T

-- 
Gone Chopin. Bach in a minuet.
January 08, 2021
On Wednesday, 9 December 2020 at 10:10:40 UTC, Mike Parker wrote:
> This is the discussion thread for the first round of Community Review of DIP 1038, "@nodiscard":
>
> [...]

Mike, it seems that this DIP is past its first community review. Should it not advance to the next round?
January 08, 2021
On Friday, 8 January 2021 at 10:50:39 UTC, RazvanN wrote:
> On Wednesday, 9 December 2020 at 10:10:40 UTC, Mike Parker wrote:
>> This is the discussion thread for the first round of Community Review of DIP 1038, "@nodiscard":
>>
>> [...]
>
> Mike, it seems that this DIP is past its first community review. Should it not advance to the next round?

Not yet. There are other DIPs ahead in the queue.
1 2
Next ›   Last »