December 20, 2013
On Friday, 20 December 2013 at 09:18:07 UTC, Joseph Rushton Wakeling wrote:
> On 20/12/13 10:10, ilya-stromberg wrote:
>> Would you like to be responsible for this decision?
>
> I hope it's clear that what I'm trying to do is understand your reasoning, because you have ideas and knowledge that are different from mine.

Yes, I know. The main question was: "is this example with advanced dynamic typing good enough and do you agree that REAL const-specific postblit/constructor can be useful?".
December 20, 2013
Andrej Mitrovic:

> It also steals a valid symbol name.

Someone has suggested to prefix it with a @.


> E.g. there's tons of C code that
> uses the symbol name "body", but I can't use this symbol because it's
> used in DBC. It's a keyword that's used in literally just one feature, and it's annoying.

In the case discussed here I think the @unique will find another usage.


> Plus DBC code just looks ugly to me (at least with
> asserts in the actual body I can add diagnostic messages), so I don't see how "body" has made DBC better.

"body" seems not needed in DBC, I suggested to remove it.
But the little failure with body is not the same situation as the one discussed here.

Bye,
bearophile
December 20, 2013
On 12/20/2013 10:13 AM, Andrej Mitrovic wrote:
> On 12/20/13, bearophile <bearophileHUGS@lycos.com> wrote:
>> A new keyword is a flag that you have found something different.
>> It makes it simpler to learn.
>
> It also steals a valid symbol name. E.g. there's tons of C code that
> uses the symbol name "body", but I can't use this symbol because it's
> used in DBC. It's a keyword that's used in literally just one feature,
> and it's annoying. Plus DBC code just looks ugly to me (at least with
> asserts in the actual body I can add diagnostic messages), so I don't
> see how "body" has made DBC better.
>

We could get rid of the keyword easily without changing the syntax of contracts.
December 20, 2013
On 12/20/2013 12:32 PM, Timon Gehr wrote:
> On 12/20/2013 10:13 AM, Andrej Mitrovic wrote:
>> On 12/20/13, bearophile <bearophileHUGS@lycos.com> wrote:
>>> A new keyword is a flag that you have found something different.
>>> It makes it simpler to learn.
>>
>> It also steals a valid symbol name. E.g. there's tons of C code that
>> uses the symbol name "body", but I can't use this symbol because it's
>> used in DBC. It's a keyword that's used in literally just one feature,
>> and it's annoying. Plus DBC code just looks ugly to me (at least with
>> asserts in the actual body I can add diagnostic messages), so I don't
>> see how "body" has made DBC better.
>>
>
> We could get rid of the keyword easily without changing the syntax of
> contracts.

(But then it would be possible to get into funny situations like

struct body{...}

class C{
    abstract void foo()in{...}out{...}
    body b; // syntax error
})
December 20, 2013
On Thursday, 19 December 2013 at 11:22:59 UTC, Maxim Fomin wrote:
> On Thursday, 19 December 2013 at 07:31:28 UTC, ilya-stromberg wrote:
>> What should we do if we decide that we need REAL `const` postblit/constructor? I mean postblit/constructor that creates only `const` object that can't be implicitly converted to the `mutable` or `immutable`.
>
> D is not C/C++. Objects are either mutable or immutable. Sometimes you can view any of them through const. There are no const objects per se.

Yes, I know. The `const` type means that I don't know at compile time real object type: it can be `mutable` or `immutable` type.
I can use `const` postblit/constructor to mark object. It lets me know the real object type at the run time and provide additional optimisations. So, it's a kind of dynamic typing.
See also example here:
http://forum.dlang.org/thread/oijzbufgajagkonenmxp@forum.dlang.org?page=5#post-pakelxyollnwvewuxajo:40forum.dlang.org
December 20, 2013
On 20/12/13 09:42, bearophile wrote:
> A new keyword is a flag that you have found something different. It makes it
> simpler to learn.
>
> [... ]
>
> Giving different names to different ideas makes them less complex :-)

Seems to me there's something of a sweet spot to be found between minimizing the total number of keywords in use, adequately expressing the diversity of ideas, and taking advantage of overlapping (not identical) concepts to simplify language usability.  But ...

> (We are bikeshedding a little.)

... yes :-)  So I'll bow out here.

December 20, 2013
On 12/20/2013 08:43 AM, Joseph Rushton Wakeling wrote:
> On 20/12/13 01:41, deadalnix wrote:
>> If that is an extra learning cost, doesn't it make the semantic more
>> complex,
>> almost by definition ?
>
> Compared to ... ?
>
> As far as I can see, it's learning a small extra meaning of 'const' in a
> context where it's quite intuitive,  ...

It is not only adding an extra meaning of const, but also removing an old one in some specific context. Why is the following 'intuitive'?

const(int*) g = ...;

struct S{
    int* a, b;
    this(immutable(int)* a, immutable(int)* b)immutable{
        this.a=a; // ok
        this.b=b; // ok
    }
    this(const(int)* a, const(int)* b)const{
        this.a=a; // error
        this.b=b; // error
    }
    // if we want to initialize a and b with pointers
    // with different qualifiers, we can do the following
    this(inout(int)* a, inout(int)* b)inout{
        this.a=a; // ok
        this.b=b; // ok
    }
    // but in general, initializing a field with a
    // 'const' reference is not fair game in such
    // a constructor
    this(inout(int)* a)inout{
        this.a=a;
        this.b=g; // error
    }
}

Why is it 'intuitive' that in this context 'inout' is not a wildcard for the other type qualifiers?

struct S{
    int* a, b;
    this(inout(int)* a, inout(int)* b)inout{
        this.a=a;
        this.b=b;
    }
    // no go:
    // this(const(int)* a, const(int)* b)const{this.a=a; this.b=b; }
}
// ...
// but:
int* a = ...;
immutable(int)* b=...;
auto s = S(a,b); // ok!
static assert(is(typeof(s)==const(S)));

The DIP breaks some existing, perfectly valid code without any clear way to fix it.

const(int)* foo(...){ ... }

class C{
    int* a;
    this()const{
        a = foo(...); // error
    }
}


Again, what is so 'intuitive' about this?

December 20, 2013
On 12/20/2013 03:04 PM, Timon Gehr wrote:
>
> The DIP breaks some existing, perfectly valid code without any clear way
> to fix it.
>
> const(int)* foo(...){ ... }
>
> class C{
>      int* a;
>      this()const{
>          a = foo(...); // error
>      }
> }

The actual workaround will be:

class C{
    int* a;
    private this(inout(int)* foo_result)inout{
        a = foo_result;
    }
}

const(C) constructC(){ return new C(foo(...)); }
// or 'new const(C)' ? If so, how to add a const constructor
// without breaking the workaround?
December 20, 2013
On Friday, 20 December 2013 at 08:42:29 UTC, bearophile wrote:
> (We are bikeshedding a little.)

A lot actually, I just hope this gets implemented, whatever keyword will be used.

December 20, 2013
On 12/18/2013 04:42 AM, Kenji Hara wrote:
> http://wiki.dlang.org/DIP53
> Redesign currently implemented qualified constructor concept.
> ...

Roughly speaking, this DIP just removes a language feature and changes the syntax of another feature to something less descriptive. I think implementing this is a net loss.

> http://wiki.dlang.org/DIP49
> Improved points from version 1:
> - Swap meanings of 'this(this) inout' and 'this(this) const'
> - Inout postblit now covers all cheap (== not rebind indirections)
> copies between same qualifiers
>
> Kenji Hara

What about just mentioning the qualifiers of source and target of the copy explicitly?

this(this){ ... } // mutable source, mutable target
this(immutable this){ ... } // immutable source mutable target
this(const this)immutable{ ... } // const source, immutable target
this(const this)const{ ... } // const source, const target
// ...
this(inout this)inout{ ... } // source and target have the same qualifier
// ...
this(this)inout{ ... } // mutable source, arbitrary target
// ...
this(const this)inout{ ... } // const source, arbitrary target

Whenever source and target are (potentially) incompatible, the postblit ensures that all fields with incompatible types in source and target are reinitialized.

Only unique expressions convert to 'inout' anyway, hence the last signature above would correspond to unique postblit in the current proposal.

This would be more explicit, strictly more expressive and require less special casing in the compiler implementation.