www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - (this T) versus (const K), TransferConst!, etc.

reply "Janice Caron" <caron800 googlemail.com> writes:
I have a small difficulty with the (this T) template specification. If
the function returns void - /great/!

    class C
    {
        void f(this T)() { ... }
    }

becomes equivalent to

    class C
    {
        void f() { ... }
        const void f() { ... }
        invariant void f() { ... }
    }

If the function returns another C, /also/ great!

    class C
    {
        T g(this T)() { ... }
    }

gets you

    class C
    {
        C g() { ... }
        const const(C) g() { ... }
        invariant invariant(C) g() { ... }
    }

The problem is, I don't grok how to return a type whose constancy
depends on the constancy of this, but isn't actually T.

I've heard rumors of a TransferConst!() template, but I can't find it
documented, and don't know how to use it. I have a horrible suspicion
it's not documented at all, because I Googled "TransferConst!", and
the only hits Google found were previous discussions of it in the
newsgroup archives. It found none in the actual digitalmars website
itself.

Without the ability to take the constancy of one thing and apply it to
another, (this T) is really very limited.

The irony is that if we went with my (const K) idea, instead of (this
T), it would all be so much simpler! Instead of

    class C
    {
        void f(this T)() { ... }
    }

we'd write

    class C
    {
        K void f(const K)() { ... }
    }

which again would expand to

    class C
    {
        void f() { ... }
        const void f() { ... }
        invariant void f() { ... }
    }

and instead of

    class C
    {
        T g(this T)() { ... }
    }

we'd write

    class C
    {
        K K(C) g(const K)() { ... }
    }

which again would expand to

    class C
    {
        C g() { ... }
        const const(C) g() { ... }
        invariant invariant(C) g() { ... }
    }

But we'd also have an added bonus. Because we have K (a placeholder
for one of the keywords "auto", "const" or "invariant") readily to
hand, we can do all sorts of other cool stuff with it, without all
that mucking about with TransferConst!(). Even ignoring the fact that
TransferConst! is poorly documented, (const K) gives you readily
comprehensible code.

Any chance we could ditch (this T) and TransferConst!() in favor of (const K)?
Mar 23 2008
parent Christopher Wright <dhasenan gmail.com> writes:
Janice Caron wrote:
 The problem is, I don't grok how to return a type whose constancy
 depends on the constancy of this, but isn't actually T.

template ThisConst(TConst, TBase) { static if (is (TConst == const)) { alias const(TBase) ThisConst; } else static if (is (TConst == invariant)) { alias invariant(TBase) ThisConst; } else { alias TBase ThisConst; } } class C { ThisConst!(T) foo(this T)() { ... } } Completely untested, since I don't use dmd2 anymore.
 But we'd also have an added bonus. Because we have K (a placeholder
 for one of the keywords "auto", "const" or "invariant") readily to
 hand, we can do all sorts of other cool stuff with it, without all
 that mucking about with TransferConst!(). Even ignoring the fact that
 TransferConst! is poorly documented, (const K) gives you readily
 comprehensible code.
 
 Any chance we could ditch (this T) and TransferConst!() in favor of (const K)?

That is certainly a cleaner solution.
Mar 23 2008