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