Goofy code means opportunities in language design
Andrei Alexandrescu
SeeWebsiteForEmail at erdani.org
Thu Sep 17 14:10:58 UTC 2020
Making a pass through Phobos code is very instructive. I find all kinds
of goofy code that really means the language doesn't allow people to do
what they want to do. So they need to write all sorts of oddities.
Consider this (from std.algorithm.iteration.cache):
private struct _Cache(R, bool bidir)
{
...
private R source;
static if (isInfinite!R)
enum empty = false;
else
bool empty() @property
{
return source.empty;
}
...
}
These lines appear over and over in Phobos in ranges that simply want to
"expose source.empty to clients of this type". There should be a
mechanism for that, such as:
alias empty = source.empty;
So then whatever source.empty implements would be automatically present
in _Cache.
Now look at this beauty:
static if (hasSlicing!R)
{
enum hasEndSlicing = is(typeof(source[size_t.max .. $]));
static if (hasEndSlicing)
{
private static struct DollarToken{}
enum opDollar = DollarToken.init;
auto opSlice(size_t low, DollarToken)
{
return typeof(this)(source[low .. $]);
}
}
static if (!isInfinite!R)
{
typeof(this) opSlice(size_t low, size_t high)
{
return typeof(this)(source[low .. high]);
}
}
else static if (hasEndSlicing)
{
auto opSlice(size_t low, size_t high)
in
{
assert(low <= high, "Bounds error when slicing cache.");
}
do
{
import std.range : takeExactly;
return this[low .. $].takeExactly(high - low);
}
}
}
Oh boy. That's a really awkward way to say, "do slicing exactly like
source does". Should be something like:
static if (hasSlicing!R)
{
static if (hasMember!(R, "opDollar"))
alias opDollar = source.opDollar;
alias opSlice = source.opSlice;
}
Even better, as it seems common to say "forward if this other guy
implements it:
try alias opDollar = source.opDollar;
try alias opSlice = source.opSlice;
More information about the Digitalmars-d
mailing list