Generic Property Implementation

Simen Kjærås simen.kjaras at gmail.com
Sat Mar 10 17:43:06 UTC 2018


On Friday, 9 March 2018 at 23:34:56 UTC, Mike Franklin wrote:
> On Friday, 9 March 2018 at 14:46:04 UTC, Simen Kjærås wrote:
>> 1) Wrong return type:
>> unittest {
>>     S s;
>>     auto a = s.field;
>>     // Fails - typeof(a) is Property!((get) => this.n, (set) 
>> => this.n = set)
>>     assert(is(typeof(a) == int));
>> }
>
> This looks like a related issue:  
> https://issues.dlang.org/show_bug.cgi?id=16657.  That's is a 
> deal-breaker for me, but I think it could be fixed.

This has nothing to do with alias this, opCmp, or opEquals. It's 
simply that instead of returning an int, like the original 
property did, s.field returns a wrapper type. There's no real way 
around this.

Actually, there may be a more interesting way to implement the 
DIP I mentioned - what if named mixin templates could have 
overloaded operators and alias this? What if this worked:

struct S {
     int n;
     mixin property!(get => n, set => n = set) field;
}

template property(fns...) {
     alias getter = findGetter!fns;
     alias setter = findSetter!fns;

     auto get() { return getter(DummyType.init); }
     alias get this;
     alias setter opAssign;

     auto opOpAssign(string op, T)(T value) { /* ... */ }
     // other overloads
}

unittest {
     S s;
     auto a = s.field; // Not a type, so alias this is used.
     assert(is(typeof(a) == int));
     // overloaded operators
     s.field += 4;
     ++s.field;
}

 From what I can see, the only necessary change would be that 
alias this and operator overloads be looked for in named mixin 
templates. Sounds doable. This would both enable 
auto-decaying/rvalue types, and allow for a bunch of interesting 
stuff with operator overloads.

...but there's an issue with this compared to real rvalue types - 
you can't return them from a function. One use case for rvalue 
types is short-circuiting when (a op1 b op2 c) can be done faster 
than ((a op1 b) op2 c), for instance when a, b, and c are 
BigInts, and op1 = ^^, op2 = %. Named mixin templates with 
overloaded operators cannot do this.

>> 2) Noisy syntax:
>> If I had my druthers, mixin templates would be mixin'd 
>> automatically, and eponymous mixin templates would be a thing.
>
> Yes, this would be nice, but I don't think it's a deal-breaker.

Agreed. I filed an issue on the eponymous mixin templates:
https://issues.dlang.org/show_bug.cgi?id=18586


>> 3) Stringy functions:
>> The string literal functions are an eyesore, but would require 
>> some compiler work to fix.
>
> Yeah, that's quite unfortunate; writing code in strings stinks.
>  I actually prefer the DIP for this issue alone.

I'm not sure how fixable this is, but I am sure that there's 
plenty of benefit to being able to write code like this:

struct S {
     int n, m;
     SomeType!(() => n + m) a;
}

over this:

struct S {
     int n, m;
     auto a() { return SomeType!(() => n + m)(); }
}

Anyways, I filed a bug for it:
https://issues.dlang.org/show_bug.cgi?id=18587


> If all of the issues you've identified were addressed, you'd 
> end up with something like this (formatted in a C# way).
>
> struct S {
>     int n;
>     property!
>     (
>         get =>
>         {
>             n
>         },
>         set =>
>         {
>             n = set
>         }
>     ) field;
> }
>
> That's actually pretty darn good.  It makes me wonder if I 
> should work on fixing those issues or continue with the DIP.

The real benefit to doing it outside the DIP is that the features 
can be used in other contexts. Rvalue types definitely have some 
more uses, the 'this.n' issue is simply a bug, eponymous mixin 
templates seem useful to me, and being able to use delegates as 
template parameters outside of member functions would make many 
things clearer.


> If you don't have any objections I'd like to incorporate this 
> implementation and your analysis into the DIP.

Of course.


> Thank you again for doing this; you've saved me a awful lot of 
> time, and have done more than I probably could have.

Pleasure. I've been spending some time on this myself, so it's 
not the first time I've tried to make a palatable implementation.

--
   Simen


More information about the Digitalmars-d-learn mailing list