Optional and orElse: design feedback/critique?

Johannes Loher johannes.loher at fg4f.de
Sat Jul 27 16:58:51 UTC 2019


Am 27.07.19 um 18:26 schrieb aliak:
> 
> A lot of the java stuff is covered with std.algorithm and orElse
> 
> auto a = some(3);
> auto gotValue = a.orElse(7); // orElseGet
> a.each!(a => writeln(a)); // ifPresent

I still think it might be valuable to have separate names for these
things. As mentioned in my other answer, I think that orElse is
overloaded too much. And while sometimes it is really nice to think of
an optional as a range, it is not always straight forwards and in that
case using something like "each" is a bit awkward. It has the benefit of
working in combination with other range algorithms though, so maybe we
should implement "ifPresent" etc. to also work in ranges (in the same
way you did for "orElse", i.e. only using the first element). Another
utility that would be very nice is ifPresentOrElse. It is very similar
to match, but does never return anything and for that reason, the two
template parameters do not need to have the same return type:

```
int x = 0;

void foo(ref int value)
{
    value = -1;
}

some(1).match!(
    value => x += value,
    () => foo(x) // won't compile because the return types differ
);
```

The solution is to make the return types the same, but this prevents us
from using the error notation for lambdas, which is kind of annoying:

```
int x = 0;

void foo(ref int value)
{
    value = -1;
}

some(1).match!(
    (value) {x += value;},
    () => foo(x) // won't compile because the return types differ
);
```

ifPresentOrElse would basically do this for us:

```
void ifPresentOrElse(alias fun1, alias fun2, T)(inout auto ref
Optional!T opt)
{
	opt.match!(
    		(value) { fun1(value); },
    		() { fun2(); }
	);
}

int x = 0;

void foo(ref int value)
{
    value = -1;
}

some(1).ifPresentOrElse!(
    value => x += value,
    () => foo(x) // everything fine now :)
);
```


More information about the Digitalmars-d mailing list