Implementing tail-const in D
Simen Kjærås
simen.kjaras at gmail.com
Tue Jan 23 14:55:39 UTC 2018
On Tuesday, 23 January 2018 at 14:17:26 UTC, Andrea Fontana wrote:
> On Tuesday, 23 January 2018 at 12:39:12 UTC, Simen Kjærås wrote:
>> On Tuesday, 23 January 2018 at 12:12:42 UTC, Nicholas Wilson
>> wrote:
>>> On Tuesday, 23 January 2018 at 09:36:03 UTC, Simen Kjærås
>>> wrote:
>>>> Questions: Is a DIP required for this?
>>>
>>> A DIP is required for language changes. So yes.
>>
>> No language changes are proposed - this is all library code.
>>
>> --
>> Simen
>
> It would be useful to have one or more short examples. Just to
> see what actually change in a common scenario.
>
> Andrea
Your wish is my command. For the most part, the changes will
require that instead of storing Unqual!Ts, use HeadMutable!Ts,
and when assigning to a HeadMutable!T, remember to assign
headMutable(rhs).
Here's a somewhat simplistic map function. As you can see, not a
whole lot is changed - map passes head-mutable versions of its
arguments to MapResult, and MapResult implements opHeadMutable(),
otherwise everything is exactly as you'd expect.
import std.range;
auto map(alias fn, R)(R r) if (isInputRange!(HeadMutable!R))
{
// Pass head-mutable versions to MapResult.
return MapResult!(fn, HeadMutable!R)(headMutable(r));
}
struct MapResult(alias fn, R) if (isInputRange!R)
{
R range;
this(R rng)
{
range = rng;
}
@property
auto front()
{
return fn(range.front);
}
void popFront()
{
range.popFront();
}
@property
bool empty()
{
return range.empty;
}
// The only change to MapResult:
auto opHeadMutable(this This)()
{
import std.traits : CopyTypeQualifiers;
return MapResult!(fn,
HeadMutable!(CopyTypeQualifiers!(This, R)))(range);
}
}
unittest
{
import std.algorithm : equal;
const a = [1,2,3,4].map!(v => v*2);
assert(!isInputRange!(typeof(a)));
// Here, std.algorithm.map gives up, since a const MapResult
is not
// an input range, and calling Unqual on it doesn't give a
sensible
// result.
// HeadMutable makes this work, since the type system now
knows how
// to make a head-mutable version of the type.
auto b = a.map!(v => v/2);
assert(equal([1,2,3,4], b));
}
--
Simen
More information about the Digitalmars-d
mailing list