equivariant functions
Andrei Alexandrescu
SeeWebsiteForEmail at erdani.org
Sun Oct 12 12:34:05 PDT 2008
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
More information about the Digitalmars-d
mailing list