www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - [OT] Is there a real alternative to exceptions ?

reply Basile B. <b2.temp gmx.com> writes:
I have the feeling that things like

```
a.map!(mapperFun).reduce!(reducerFun).array;
```

is only possible thanks to an exception system. A similar 
expressivity looks impossible for example with the idom of result 
tuple `(error_code, actuallResult)`.

that problem is currently something rather serious, in the sense 
that, let's say you want to make a standard library, you really 
need to have a well defined way of handling errors.

I'll be interested to read your thoughts on that topic.
Jan 16
next sibling parent reply monkyyy <crazymonkyyy gmail.com> writes:
On Thursday, 16 January 2025 at 19:02:05 UTC, Basile B. wrote:
 I have the feeling that things like

 ```
 a.map!(mapperFun).reduce!(reducerFun).array;
 ```

 is only possible thanks to an exception system. A similar 
 expressivity looks impossible for example with the idom of 
 result tuple `(error_code, actuallResult)`.

 that problem is currently something rather serious, in the 
 sense that, let's say you want to make a standard library, you 
 really need to have a well defined way of handling errors.

 I'll be interested to read your thoughts on that topic.
1) add a error code system to the range api 2) damn the consequences have fail safe functions(1/0==int.max) 3) store errors and extra control flow in my `innate` pattern 4) nullable everywhere, range functions can react to nullable elements 5) preallocate some space for exceptions, cap the size of exception objects(assuming this is about betterc)
Jan 16
parent reply Basile B. <b2.temp gmx.com> writes:
On Thursday, 16 January 2025 at 19:13:38 UTC, monkyyy wrote:
 On Thursday, 16 January 2025 at 19:02:05 UTC, Basile B. wrote:
 [...]
1) add a error code system to the range api 2) damn the consequences have fail safe functions(1/0==int.max) 3) store errors and extra control flow in my `innate` pattern 4) nullable everywhere, range functions can react to nullable elements 5) preallocate some space for exceptions, cap the size of exception objects(assuming this is about betterc)
I dont see how that helps to abort when an error happens "in between the chain" let's say.
Jan 16
next sibling parent monkyyy <crazymonkyyy gmail.com> writes:
On Thursday, 16 January 2025 at 19:37:36 UTC, Basile B. wrote:
 On Thursday, 16 January 2025 at 19:13:38 UTC, monkyyy wrote:
 On Thursday, 16 January 2025 at 19:02:05 UTC, Basile B. wrote:
 [...]
1) add a error code system to the range api 2) damn the consequences have fail safe functions(1/0==int.max) 3) store errors and extra control flow in my `innate` pattern 4) nullable everywhere, range functions can react to nullable elements 5) preallocate some space for exceptions, cap the size of exception objects(assuming this is about betterc)
I dont see how that helps to abort when an error happens "in between the chain" let's say.
aborts are bad; hottake; nullables are far far better pattern But 3 and 5 could be the same "bad goto" as exceptions with compiler help or some truly awful raw asm 3 could also abort on error with lib design, but that would be very ugly --- ``` nullable!int inverse(int i){ if(i==0){return null;} return 100/i; } [2,0,5,4].map!inverse.sort==[null,20,25,50]; ``` Could just exist, theres one of them eagerness vs lazyness tradeoffs here between eager exceptions and lazy nullables; Im very much in favor of the later and never use exceptions as intended(when phoboes throws, make an hack to make it go away)
Jan 16
prev sibling parent reply Kagamin <spam here.lot> writes:
On Thursday, 16 January 2025 at 19:37:36 UTC, Basile B. wrote:
 I dont see how that helps to abort when an error happens "in 
 between the chain" let's say.
Turn all operations into monadic combinators, example for Nullable: https://dlang.org/phobos/std_typecons.html#apply
Jan 17
next sibling parent Basile B. <b2.temp gmx.com> writes:
On Friday, 17 January 2025 at 08:43:00 UTC, Kagamin wrote:
 On Thursday, 16 January 2025 at 19:37:36 UTC, Basile B. wrote:
 I dont see how that helps to abort when an error happens "in 
 between the chain" let's say.
Turn all operations into monadic combinators, example for Nullable: https://dlang.org/phobos/std_typecons.html#apply
Yeah that's also what's described in the talked pointed by Meta.
Jan 17
prev sibling parent reply Kagamin <spam here.lot> writes:
Nullable having range interface, maybe you can just add error to 
the range contract?
```
V op(Range)(Range r)
{
	if(r.hasError)return r.error;
	...
}
```
Jan 17
parent Kagamin <spam here.lot> writes:
Or an error subrange?
```
V op(Range)(Range r)
{
	if(!r.error.empty)return r.error;
	...
}
```
Jan 17
prev sibling next sibling parent reply Derek Fawcus <dfawcus+dlang employees.org> writes:
On Thursday, 16 January 2025 at 19:02:05 UTC, Basile B. wrote:
 I have the feeling that things like

 ```
 a.map!(mapperFun).reduce!(reducerFun).array;
 ```

 is only possible thanks to an exception system. A similar 
 expressivity looks impossible for example with the idom of 
 result tuple `(error_code, actuallResult)`.

 that problem is currently something rather serious, in the 
 sense that, let's say you want to make a standard library, you 
 really need to have a well defined way of handling errors.

 I'll be interested to read your thoughts on that topic.
Sum types?
Jan 16
parent Basile B. <b2.temp gmx.com> writes:
On Thursday, 16 January 2025 at 19:38:45 UTC, Derek Fawcus wrote:
 On Thursday, 16 January 2025 at 19:02:05 UTC, Basile B. wrote:
 I have the feeling that things like

 ```
 a.map!(mapperFun).reduce!(reducerFun).array;
 ```

 is only possible thanks to an exception system. A similar 
 expressivity looks impossible for example with the idom of 
 result tuple `(error_code, actuallResult)`.

 that problem is currently something rather serious, in the 
 sense that, let's say you want to make a standard library, you 
 really need to have a well defined way of handling errors.

 I'll be interested to read your thoughts on that topic.
Sum types?
That's not the problem. remember the example ``` a.map!(mapperFun).reduce!(reducerFun).array; ``` the problem is about keeping the same expressivity but eventually using another error handling system.For example imagine an error happens during the mapping, then what has to do the reducer ?
Jan 16
prev sibling next sibling parent reply Dom DiSc <dominikus scherkl.de> writes:
On Thursday, 16 January 2025 at 19:02:05 UTC, Basile B. wrote:
 I have the feeling that things like

 ```
 a.map!(mapperFun).reduce!(reducerFun).array;
 ```

 is only possible thanks to an exception system.
So, why don't keep using exceptions? If you're concerned about GC, try -preview=dip1008 For me this works like a charm.
Jan 16
parent Basile B. <b2.temp gmx.com> writes:
On Thursday, 16 January 2025 at 23:04:20 UTC, Dom DiSc wrote:
 On Thursday, 16 January 2025 at 19:02:05 UTC, Basile B. wrote:
 I have the feeling that things like

 ```
 a.map!(mapperFun).reduce!(reducerFun).array;
 ```

 is only possible thanks to an exception system.
So, why don't keep using exceptions? If you're concerned about GC, try -preview=dip1008 For me this works like a charm.
I should have said it earlier but the context is another programming language than D. At the moment it has no builtin error handling system.
Jan 17
prev sibling next sibling parent Dennis <dkorpel gmail.com> writes:
On Thursday, 16 January 2025 at 19:02:05 UTC, Basile B. wrote:
 I'll be interested to read your thoughts on that topic.
[The Easiest Way To Handle Errors Is To Not Have Them](https://www.rfleury.com/p/the-easiest-way-to-handle-errors?utm_source=publication-search) I don't have a general solution for your abstract formulation of the problem, but if you give examples of concrete mapper functions that you think have to throw an exception, I can give you my take on how to avoid it.
Jan 16
prev sibling next sibling parent reply Meta <jared771 gmail.com> writes:
On Thursday, 16 January 2025 at 19:02:05 UTC, Basile B. wrote:
 I have the feeling that things like

 ```
 a.map!(mapperFun).reduce!(reducerFun).array;
 ```

 is only possible thanks to an exception system. A similar 
 expressivity looks impossible for example with the idom of 
 result tuple `(error_code, actuallResult)`.
It's very easily doable, arguably with even better ergonomics than with exceptions: https://fsharpforfunandprofit.com/rop/ C/C++ programmers are just stuck in the 80s 😛
Jan 16
next sibling parent Basile B. <b2.temp gmx.com> writes:
On Friday, 17 January 2025 at 00:21:35 UTC, Meta wrote:
 On Thursday, 16 January 2025 at 19:02:05 UTC, Basile B. wrote:
 I have the feeling that things like

 ```
 a.map!(mapperFun).reduce!(reducerFun).array;
 ```

 is only possible thanks to an exception system. A similar 
 expressivity looks impossible for example with the idom of 
 result tuple `(error_code, actuallResult)`.
It's very easily doable, arguably with even better ergonomics than with exceptions: https://fsharpforfunandprofit.com/rop/ C/C++ programmers are just stuck in the 80s 😛
Nice, thanks for the link, so finally it seems that the problem would be solved since 2014.
Jan 17
prev sibling parent Paulo Pinto <pjmlp progtools.org> writes:
On Friday, 17 January 2025 at 00:21:35 UTC, Meta wrote:
 On Thursday, 16 January 2025 at 19:02:05 UTC, Basile B. wrote:
 I have the feeling that things like

 ```
 a.map!(mapperFun).reduce!(reducerFun).array;
 ```

 is only possible thanks to an exception system. A similar 
 expressivity looks impossible for example with the idom of 
 result tuple `(error_code, actuallResult)`.
It's very easily doable, arguably with even better ergonomics than with exceptions: https://fsharpforfunandprofit.com/rop/ C/C++ programmers are just stuck in the 80s 😛
Some may be, others go with the times, courtesy of C++23. https://en.cppreference.com/w/cpp/utility/expected https://en.cppreference.com/w/cpp/utility/optional https://en.cppreference.com/w/cpp/ranges
Jan 17
prev sibling next sibling parent reply Paolo Invernizzi <paolo.invernizzi gmail.com> writes:
On Thursday, 16 January 2025 at 19:02:05 UTC, Basile B. wrote:
 I have the feeling that things like

 ```
 a.map!(mapperFun).reduce!(reducerFun).array;
 ```

 is only possible thanks to an exception system. A similar 
 expressivity looks impossible for example with the idom of 
 result tuple `(error_code, actuallResult)`.

 that problem is currently something rather serious, in the 
 sense that, let's say you want to make a standard library, you 
 really need to have a well defined way of handling errors.

 I'll be interested to read your thoughts on that topic.
I suggest to you to have a look how pure functional programming languages are handling such kind of constructs. As a soft start I suggest Elm.
Jan 17
parent monkyyy <crazymonkyyy gmail.com> writes:
On Friday, 17 January 2025 at 09:35:03 UTC, Paolo Invernizzi 
wrote:
 On Thursday, 16 January 2025 at 19:02:05 UTC, Basile B. wrote:
 I have the feeling that things like

 ```
 a.map!(mapperFun).reduce!(reducerFun).array;
 ```

 is only possible thanks to an exception system. A similar 
 expressivity looks impossible for example with the idom of 
 result tuple `(error_code, actuallResult)`.

 that problem is currently something rather serious, in the 
 sense that, let's say you want to make a standard library, you 
 really need to have a well defined way of handling errors.

 I'll be interested to read your thoughts on that topic.
I suggest to you to have a look how pure functional programming languages are handling such kind of constructs. As a soft start I suggest Elm.
While they should be part of the convrsation; purity is holding back ranges and we dont have the compiler tool set of haskell.
Jan 17
prev sibling parent Mensikovk <mensikovk817 gmail.com> writes:
On Thursday, 16 January 2025 at 19:02:05 UTC, Basile B. wrote:
 I have the feeling that things like

 ```
 a.map!(mapperFun).reduce!(reducerFun).array;
 ```

 is only possible thanks to an exception system. A similar 
 expressivity looks impossible for example with the idom of 
 result tuple `(error_code, actuallResult)`.

 that problem is currently something rather serious, in the 
 sense that, let's say you want to make a standard library, you 
 really need to have a well defined way of handling errors.

 I'll be interested to read your thoughts on that topic.
Koka programming language has cool effect system. Its powerful as monads, but pretty simple. In D there is already the beginning of this system: pure, safe, nogc, nothrow. But in koka they are polymorphic. Also, these koka effects allow you to implicitly configure modules with the necessary callbacks. These effects also allow you to implement async/await, exceptions, generators, and some programs with complex flow control at the program level without having to change the compiler. https://koka-lang.github.io/koka/doc/book.html#sec-effect-types . If you add them to D, then you can transfer many D features to the runtime library altogether.
Feb 03