equivariant functions

KennyTM~ kennytm at gmail.com
Sun Oct 12 13:30:42 PDT 2008


Andrei Alexandrescu wrote:
> 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

Oh this is a bug? o_O I though it is expected.

Anyway this suggestion seems better than taking the type of some global 
variable.



More information about the Digitalmars-d mailing list