Re: Flagging special conditions on return from a function call

2020-06-23 Thread Denis via Digitalmars-d-learn

On Tuesday, 23 June 2020 at 21:34:25 UTC, Paul Backus wrote:


If you're open to using Dub packages [...]


Because this is going to be used in almost every program I write, 
I need to eliminate outside dependencies as an option. 
Nonetheless, thanks for this suggestion.


[2] 
https://pbackus.github.io/blog/beating-stdvisit-without-really-trying.html


I did read your blog post: that's an impressive result. Good to 
know that well-written D code can be competitive with C.


Denis


Re: Flagging special conditions on return from a function call

2020-06-23 Thread Paul Backus via Digitalmars-d-learn

On Tuesday, 23 June 2020 at 16:14:20 UTC, Denis wrote:
by presenting an interface that only compiles when both cases 
are covered, like fun().match((T t) => t, () => Error()).


A complete solution wrapped in a tidy package -- I like it.

Thanks for sharing.


If you're open to using Dub packages, I'd recommend sumtype [1] 
as an alternative to the standard-library Algebraic. It has much 
better compatibility with things like function attributes (@safe, 
nothrow, etc), mutability qualifiers, CTFE, and betterC, and also 
produces substantially more efficient code [2].


[1] https://code.dlang.org/packages/sumtype
[2] 
https://pbackus.github.io/blog/beating-stdvisit-without-really-trying.html


Re: Flagging special conditions on return from a function call

2020-06-23 Thread Denis via Digitalmars-d-learn
Perhaps this thread would have been better titled "Returning a 
value and a status", and the question phrased as "What are your 
preferred techniques?".


I'm planning to port some of my programs to D, so I'd like to 
standardize on one or two techniques for handling this very 
common situation, in a way that suits the language. I'd 
appreciate hearing from others about what you do.


---

On Tuesday, 23 June 2020 at 06:52:29 UTC, Simen Kjærås wrote:

On Tuesday, 23 June 2020 at 04:01:45 UTC, Denis wrote:


[...]

(4) Set the function return value normally, and put the flag 
in an "out" variable passed as an argument to the function
(5) Return the flag, and put the value in an "out" variable 
passed to the function (i.e. the reverse of #4)


Both of these happen. I don't know which is more common. In C# 
these are probably the most common way (except for exceptions) 
to signal these cases.


Good to know. Both of these techniques (or something similar) are 
used in Perl too. The choice seemed to depend on which one the 
author thought would be more useful as the return.


[...]

by presenting an interface that only compiles when both cases 
are covered, like fun().match((T t) => t, () => Error()).


A complete solution wrapped in a tidy package -- I like it.

Thanks for sharing.


Re: Flagging special conditions on return from a function call

2020-06-23 Thread Simen Kjærås via Digitalmars-d-learn

On Tuesday, 23 June 2020 at 04:01:45 UTC, Denis wrote:
(1) Assign an unused value for the flag (e.g. -1 when the 
function returns an int), and return the combined value/flag.


This happens in some Phobos algorithms, and might be the most 
common on this list.




(2) Return a tuple with the value and the flag
(3) Return a struct or tuple with named value and flag members


Would certainly work, but I don't think it's common in D.


(4) Set the function return value normally, and put the flag in 
an "out" variable passed as an argument to the function
(5) Return the flag, and put the value in an "out" variable 
passed to the function (i.e. the reverse of #4)


Both of these happen. I don't know which is more common. In C# 
these are probably the most common way (except for exceptions) to 
signal these cases.



(6) Use two separate functions, one that returns the value, and 
another that can be called afterwards to check the flag (like 
eof(), for example)




(7) Use a side effect and set a designated global variable


Global variables are frowned upon, so probably not this. :p


One thing I feel is missing here (perhaps because 
std.variant.Algebraic is egregious):


(8) Return a Maybe!T or Algebraic!(T, ErrorCode)

It's what I personally would prefer, but I have only rarely seen 
it in D code. Given a properly written Maybe, this could enforce 
proper handling of the error case, either by throwing on trying 
to get at Maybe!T.getValue when it's holding None, or by 
presenting an interface that only compiles when both cases are 
covered, like fun().match((T t) => t, () => Error()).


--
  Simen


Flagging special conditions on return from a function call

2020-06-22 Thread Denis via Digitalmars-d-learn
Is there a preferred idiom in D for flagging special conditions 
when returning from a function call? Here "special conditions" 
refers to expected situations (e.g. reaching the end of 
something, like EOF) rather than outright errors (so 
exception-try-catch is inappropriate).


I've come across many ways for a function to return both a value 
and flag, including:


(1) Assign an unused value for the flag (e.g. -1 when the 
function returns an int), and return the combined value/flag.

(2) Return a tuple with the value and the flag
(3) Return a struct or tuple with named value and flag members
(4) Set the function return value normally, and put the flag in 
an "out" variable passed as an argument to the function
(5) Return the flag, and put the value in an "out" variable 
passed to the function (i.e. the reverse of #4)
(6) Use two separate functions, one that returns the value, and 
another that can be called afterwards to check the flag (like 
eof(), for example)

(7) Use a side effect and set a designated global variable

I'm sure there are others.

* Is there a preferred approach?
* Which ones are discouraged?
* General recommendations or guidelines?

If there is a best practice, I'd rather learn it sooner than many 
lines of code later.


(In the interest of brevity, I'll limit my own comments in this 
post to the following: In the past, I've tried to adhere to KISS. 
This means that I would generally prefer #1. But often it isn't 
possible to combine the value and flag that way, in which case 
one of the other methods must be used.)