Multiple alias this, what's the hold up?

Jonathan Marler johnnymarler at gmail.com
Sun Jun 16 06:40:41 UTC 2019


On Sunday, 16 June 2019 at 06:08:54 UTC, Walter Bright wrote:
> On 6/15/2019 6:21 PM, Timon Gehr wrote:
>> In terms of lookup, the issues with multiple alias this are 
>> the same as the issues with multiple import declarations. 
>> Implicit conversions could use the same lookup rules, but 
>> there would need to be a way to disambiguate. The code in the 
>> compiler that implements import declarations is unlikely to be 
>> easily reusable.
>
> Multiple alias this is multiple inheritance. Generally, if you 
> find yourself wanting multiple inheritance, it's likely time to 
> rethink the data structures.

There's not many cases where I've really needed/wanted multiple 
alias this.  I do have one case where I thought it would be nice 
which I'll share for anyone interested.

It was when I created the SentinelArray/SentinelPtr types.  They 
represent arrays and pointers that are ended with a sentinel 
value.

https://github.com/dragon-lang/mar/blob/master/src/mar/sentinel.d

For example, a cstring would be a SentinelPtr!char. The reason 
for creating these types is to allow the type system to know 
whether or not a pointer already has a sentinel value. This is 
most useful when interfacing with C functions that take C 
strings. Declaring the string pointer as a SentinelPtr allows the 
type-system to both verify that all strings are null-terminated 
and allows the application to control when conversions from 
D-Strings to C-Strings occur rather than performing a conversion 
every time the function is called.

To make these Sentinel types play well with the type system, I 
also supported using type modifiers like 'const' and 'immutable':

SentinelPtr!char
SentinelPtr!(const char)
SentinelPtr!(immutable char)

The reason for "alias this" would be to have them be implicitly 
convertible to both raw pointers for the mutable/immutable 
variants to be implicitly convertible to the const variant.  So 
you could do things like:

//
// Implicitly convertible to raw pointer
//
void takesRawPointer(char* ptr);

SentinelPtr!char p = ...;
takesRawPointer(p);

//
// Mutable/Immutable implicitly convertible to const
//
void takeConstSentinelPtr(SentinelPtr!(const char) filename);

SentinelPtr!char filename1 = ...;
takeConstSentinelPtr(filename1);
SentinelPtr!(immutable char) filename2 = ...;
takeConstSentinelPtr(filename2);

Since multiple alias this only supports one member I couldn't 
have both.  So I chose to use alias this to convert 
mutable/immutable to const and raw pointer conversions requires 
an explicit member access (i.e. `mySentinelPtr.raw`).  Having to 
call a member is not horrible, but having multiple alias this 
seems like it would be nicer.

Anyway, thought it might be helpful to see a real use case.

Of course, if anyone knows of a better solution to this problem 
I'm all ears :)


More information about the Digitalmars-d mailing list