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