On Saturday, 29 February 2020 at 12:50:59 UTC, Adnan wrote:
I have a struct that has to arrays. Each of those must have the
same sizes.
So while constructing the array, if you pass two arrays of
different sizes the constructor must return nothing.
In Rust I could easily use Option<T>. D has no answer to
Optional types as far as I am concerned. Is throwing exceptions
the only idiomatic way?
---
What I already considered:
* Using Nullable!T: Okay but Nullable!T has all the overloads
for regular T which makes the API even more unpredictable.
In Rust you don't just add a Some(44) and 34; No overloads for
Some<T> and i32 are allowed (purposefully).
* Option!T from the optional package: Has even worse problem
IMO. Not only it allows None + int but also it returns a `[]`.
This API is not to my liking. You could say well Haskell has
fmap for Optional etc, and I am aware of that, so does Rust
with map etc. But I am talking about basic things: like `+`.
* Value-based error handling like Go and C: well, that works
but the error checking is opt-in. There's no such thing as
[[nodiscard]] in D too so the user of the API might as well
forget to check for error value.
* if specialization: Clever workaround but sometimes the struct
may fail for complex reasons, not only for a single condition.
There's no idiomatic way since D lang is based on exceptions...
However I'd use one of those system:
1. return error, write result in ref parameter.
alias CheckedValueProto(RT, P...) = bool function(ref RT, P
params);
2. the same using a special struct and no more ref param. So more
like Nullable/Optional but with a dedicated generic type that
contain a single opover used to indicate if there's been an error
or not.
struct CheckedValue(T) {
bool noError;
T t;
B opCast(B : bool)() inout pure nothrow @safe {
return noError;
}
}
and you make your functions to return CheckedValues...
CheckedValue!int strToInt(string input);
....
if (const CheckedValue!int = strToInt("a") {} else {}
Although
- both still require self-discpline or a specialized linter to
detect unchecked calls ;
- the whole standard library is incompatible ;
I have a personal preference for 2. even if it causes problems
when T is of same size as a pointer. Now the question is also
what's the more costly ? try/catch or this non atomic return ?