constancy and template parameters in D2.009+

Janice Caron caron800 at googlemail.com
Thu Dec 13 00:52:11 PST 2007


On 12/13/07, Walter Bright <newshound1 at digitalmars.com> wrote:
> Janice Caron wrote:
> > I certainly hope you will look at the thread "Constancy lost
> > when compiling template mixin", and respond in some way - even if only
> > to tell me I've made some obvious and stupid error - because the issue
> > raised there is one that I /do/ need solving.
>
> I wouldn't worry about that right now, as the const stuff is getting
> revised again.

Cool. I'll accept your word on that.

But one thing I would like you to think about is that templates need
the ability to determine the constancy of their parameters. That is,
Array!(int) sometimes (but not always) needs to be a different
instantiation from Array!(const(int)), because sometimes they need to
behave differently.

In D2.007, they were indeed different instantiations.

In D2.008, they resulted in the same instantiation, unless you
declared your template differently. That is, instead of writing

    class Array(T)

you now had to write

    class Array(T:T)

if you wanted int and const(int) to generate different instantiations.
This isn't immediately obvious - in fact, I'm not even sure how to
read it! ("T where T is a type of T", perhaps?). To make matters
worse, as I demonstrated in the thread "Constancy lost when compiling
template mixin", the (T:T) syntax doesn't actually work in all
circumstances. In D2.008, it fails in my example (where I use a
(T:T)-type template as a mixin). From your answer, I guess I have to
assume this is a compiler bug, and I trust that the bug will disappear
in D2.009.

A related problem is that of /removing/ constancy. Right now (in
D2.008), I use alias typeof to remove constancy. That is:

    class Array(T:T)
    {
        alias typeof(T) U;
        ...

yeilds a type U equivalent to T without the const - exactly as if I had declared

    class Array(U)
    {
        ...

Again, my complaint is that the syntax is not obvious. Why should
"alias typeof(T)" be the way to remove constness? Sure, it /works/,
but as a statement of intent, it's not obvious.

In all of this, there is a common theme - SYNTAX. In all of the
examples I have described, my complaint is that /the syntax is not
obvious/. It's not obvious that (T) should mean "don't regard head
constancy as significant"; it's not obvious that (T:T) should mean "do
regard head constancy as significant"; and it's not obvious that
typeof(T) should mean "remove constancy". (And in fact, I'm not even
sure whether it removes only head constancy or all constancy).

So, while you're still working on this, please may I suggest a simple
and obvious syntax refinement, which I believe will do exactly the
right thing in all circumstances, and be completely readable...


RULE ONE: Head constancy is not considered significant in template
instantiation.

Thus, (exactly as in D2.008), if "class A(T)" is instantiated with
"int" and "const(int)", it will result in exactly one instantiation,
with T being "int".


RULE TWO: Head constancy may be explicitly parameterised with an
/additional/ template parameter. For example:

    class Array(U, T=const(U))

The intent here is that, if instantiated with "int", U and T will both
be "int", but if instantiated with "const(int)", U will be "int" and T
will be "const(int)". Likewise, if instantiated with "invariant(int)",
U will be "int" and T will be "invariant(int)".


RULE THREE: There is no rule three. (Or, put another way...), get rid
of the silly typeof(U) syntax for removing constancy. It's really not
obvious what's going on anyway. In fact, I don't think typeof(U)
should even /parse/, if U is a type, not a value! In any case, the
point is that RULE TWO already creates two types - U without
constancy, and T with, and so the need to explicitly remove it from T
to generate U is now redundant.


Well, that's it - that's my suggestion for the day. I hope it helps.



More information about the Digitalmars-d mailing list