Goofy code means opportunities in language design
Jacob Carlborg
doob at me.com
Fri Sep 18 14:15:18 UTC 2020
On 2020-09-17 16:10, Andrei Alexandrescu wrote:
> 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;
>
Isn't all this easily solved with opDispatch or `alias this`?
--
/Jacob Carlborg
More information about the Digitalmars-d
mailing list