equivariant functions

Andrei Alexandrescu SeeWebsiteForEmail at erdani.org
Sun Oct 12 13:21:46 PDT 2008


KennyTM~ wrote:
> Andrei Alexandrescu wrote:
>> Many functions return one of their parameters regardless of the way it 
>> was qualified.
>>
>> char[] stripl(char[] s);
>> const(char)[] stripl(const(char)[] s);
>> invariant(char)[] stripl(invariant(char)[] s);
>>
>> Stripl is not a particularly good example because it needs to work on 
>> wchar and dchar too, but let's ignore that aspect for now.
>>
>> There's been several proposals in this group on tackling that problem.
>>
>> In unrelated proposals and discussions, people mentioned the need for 
>> functions that return the exact type of this:
>>
>> class A { A clone(); }
>> class B : A { B clone(); }
>>
>> How can we declare A.clone such that all of its derived classes have 
>> it return their own type?
>>
>> It took me a while to realize they are really very related. This is 
>> easy to figure out if you think that invariant(char)[] and char[] are 
>> subtypes of const(char)[]!
>>
>> I discussed with Walter a variant that implements equivariant 
>> functions without actually adding an explicit feature to the language. 
>> Consider:
>>
>> typeof(s) stripl(const(char)[] s);
>>
>> This signature states that it returns the same type as an argument. I 
>> propose that that pattern means stripl can accept _any_ subtype of 
>> const(char)[] and return that exact type. Inside the function, 
>> however, the type of s is the type declared, thus restricting its use.
>>
>> I need to convince myself that function bodies of this type can be 
>> reliably typechecked, but first I wanted to run it by everyone to get 
>> a feel of it.
>>
>> Equivariant functions are not (necessarily) templates and can be used 
>> as virtual functions. Only one body is generated for one equivariant 
>> function, unless other template mechanisms are in vigor.
>>
>> Here are some examples:
>>
>> a) Simple equivariance
>>
>> typeof(s) stripl(const(char)[] s);
>>
>> b) Parameterized equivariance
>>
>> typeof(s) stripl(S)(S s) if (isSomeString!S);
>>
>> c) Equivariance of field:
>>
>> typeof(s.ptr) getpointer(const(char)[] s);
>>
>> d) Equivariance inside a class/struct declaration:
>>
>> class S
>> {
>>     typeof(this) clone();
>>     typeof(this.field) getfield();
>>     int field;
>> }
>>
>> What do you think? I'm almost afraid to post this.
>>
>>
>> Andrei
> 
> Sounds good.
> 
> -- 
> 
> Please resolve ambiguity when s is a global variable.
> 
> string s;
> 
> // currently compiles.
> typeof(s) f(int s) {
>   return typeof(return).init;
> }

Yes, incidentally there is a bug in the current compiler (I put it 
somewhere in bugzilla a while ago) that prevents it from using parameter 
names in a typeof expression.

Andrei



More information about the Digitalmars-d mailing list