Persistent list

Steven Schveighoffer via Digitalmars-d digitalmars-d at puremagic.com
Mon Nov 16 14:30:48 PST 2015


On 11/16/15 5:02 PM, Jonathan M Davis wrote:
> On Monday, 16 November 2015 at 21:47:07 UTC, Andrei Alexandrescu wrote:
>> On 11/16/2015 04:18 PM, Jonathan M Davis wrote:
>>> When you can templatize the function on the type that would otherwise be
>>> inout, then there really isn't any reason to use inout. But what do you
>>> do when you're dealing with a member function - especially on a class? I
>>> don't know of any way to templatize a member function on the type of the
>>> this pointer/reference, but maybe there's a template feature with which
>>> I'm not familiar enough. But even if there _is_ such a feature, it won't
>>> work for virtual functions.
>>
>> It does. Write one-liners that forward to the template function, as
>> shown in http://dpaste.dzfl.pl/52a3013efe34 (search the page for
>> QList). -- Andrei
>
> Well, that does reduce the code duplication, but you're still forced to
> have up to three separate functions to get each of the different return
> types (even if they are then simply wrapper functions). And compare that
> with simply declaring the same function once with its implementation
> internal to itself. It's just that you use inout instead of const. How
> is that worse?

I'll reiterate what I said elsewhere: inout is better, safer, and easier 
to maintain than the template solution.

Example:

static QList cons(QList)(T head, auto ref QList lst)
     if (is(Unqual!QList == List))

Tell me how cons guarantees not to modify lst? Is it convention or 
compiler guarantees? find the bug:

static QList cons(QList)(T head, auto ref QList lst)
     if (is(Unqual!QList == List))
{
List result;
result._allocator = either(lst.allocator, theAllocator);
import std.conv : emplace;
void[] buf = result.allocator.allocate(Node.sizeof);
auto n = emplace!(const Node)(buf, head, lst.root, 1);
incRef(lst.root);
result.root = n;
static if(!is(QList == const)) lst.root = lst.root.next;
return result;
}

The point of const is to provide a mechanism to those reading the 
signature to say "this function will NOT change the parameter, and the 
compiler guarantees it." The point of inout is the same, but allows 
returning a portion of the parameters without resorting to casts or 
wrappers.

-Steve


More information about the Digitalmars-d mailing list