equivariant functions
Michel Fortin
michel.fortin at michelf.com
Mon Oct 13 05:08:47 PDT 2008
On 2008-10-12 15:34:05 -0400, Andrei Alexandrescu
<SeeWebsiteForEmail at erdani.org> said:
> 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.
I'm not sure why one would one add another syntax feature for this. I
mean: we have templates which are capable of this. Sure, templates are
instanciated only when needed and that's not what we want, but I think
we'd better reuse the syntax we have, adding a modifier and if
necessary for forcing one instanciation at the definition site when
possible.
I'm not sure if this is valid in D2 (I don't have a D2 compiler in
front of me right now), but let's say that this makes C any subtype of
const(char):
C strip1(C : const(char))(C[] s);
This template does what you want, except that it's instanciated only at
the call site, making it unusable in some situations. What we need is
to make this specific template work like C# and Java's generics: only
one instanciation dealing with multiple parametrized types. So let's
extend the template syntax a little:
C strip1(equivariant C : const(char))(C[] s);
Hum, what did that change? Well, the new "equivariant" keyword I added
imposes new restrictions to the template argument, such as you cannot
know the exact type beyond the type restriction in the parameter
definition. These restrictions are designed to enable only one
instanciation of the template to cover them all. For instance:
C strip1(equivariant C : const(char))(C[] s)
{
C[] s1 = s; // okay, s1 is of the same type.
C[] s2 = "abc"; // error, "abc" is invariant(char)[],
// incompatible with base type const(char)[]
C[] s2 = new C[5]; // can allocate since we know we deal with "char",
// whatever constness it has, it'll always be of
the same size.
return s; // okay, same type.
}
Reusing the template syntax would avoid adding yet another different
but similar syntax for generic functions. Perhaps you find the template
syntax overly verbose for this (I do), but then I'd say it's the
template syntax that ought to be rethought instead reinventing it in
another more limited form for equivariant functions.
(Of course we could start from an equivalent function syntax and then
extend it to templates later, so I'm not really against what you're
exposing here. I only wish we can reach some syntax consistency in the
end.)
--
Michel Fortin
michel.fortin at michelf.com
http://michelf.com/
More information about the Digitalmars-d
mailing list