October 17, 2014
On Friday, 17 October 2014 at 15:20:50 UTC, ketmar via Digitalmars-d wrote:
> On Fri, 17 Oct 2014 14:41:36 +0000
> IgorStepanov via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
>
>> What happends if we will ignore const/immutable modifier for postblits? Is it create any holes?
> it will break "const promise". i.e. "const/immutable data is not really
> immutable now, it can be modified".

It's just common words=)
I meant that when postblit is called when new object is being creating and doesn't exists for user code.
E.g.
const S v1 = v2;
Ok, v1 _will_ be const when it will be _created_.
However postblit can think that object is mutable, because it called before the first accessing to the object from user code.
Thus I ask about case when postblit may mutate a const object, which created before postblitted object and may been accessed from user code before this postblitting.
October 17, 2014
On Friday, 17 October 2014 at 16:19:47 UTC, IgorStepanov wrote:
> It's just common words=)
> I meant that when postblit is called when new object is being creating and doesn't exists for user code.
> E.g.
> const S v1 = v2;
> Ok, v1 _will_ be const when it will be _created_.
> However postblit can think that object is mutable, because it called before the first accessing to the object from user code.
> Thus I ask about case when postblit may mutate a const object, which created before postblitted object and may been accessed from user code before this postblitting.

That's way too many words for a single sentence for me to understand ;)

But maybe this answers your question?

import std.stdio;

struct S
{
    int* p;
    this(this)
    {
        ++*p;
    }
}

void main()
{
    immutable i = 0;
    auto s1 = immutable(S)(&i);
    auto s2 = s1;
    assert(*&i == 0);
}
October 17, 2014
On Fri, 17 Oct 2014 16:19:46 +0000
IgorStepanov via Digitalmars-d <digitalmars-d@puremagic.com> wrote:

> On Friday, 17 October 2014 at 15:20:50 UTC, ketmar via Digitalmars-d wrote:
> > On Fri, 17 Oct 2014 14:41:36 +0000
> > IgorStepanov via Digitalmars-d <digitalmars-d@puremagic.com>
> > wrote:
> >
> >> What happends if we will ignore const/immutable modifier for postblits? Is it create any holes?
> > it will break "const promise". i.e. "const/immutable data is
> > not really
> > immutable now, it can be modified".
> 
> It's just common words=)
> I meant that when postblit is called when new object is being
> creating and doesn't exists for user code.
> E.g.
> const S v1 = v2;
> Ok, v1 _will_ be const when it will be _created_.
> However postblit can think that object is mutable, because it
> called before the first accessing to the object from user code.
> Thus I ask about case when postblit may mutate a const object,
> which created before postblitted object and may been accessed
> from user code before this postblitting.
what if compiler knows 'v2' value at compile time? compiler can put 'v1' in read-only section, and then postblitter will try to mutate 'v1'... ah, segfault. yet postblitter can do some other things, like, for example, registering 'v1' in some king of runtime storage, so it can't be optimized away.

and then the programmer changes postblitter to mutate some fields. it all compiles fine and segfaults.

const promises can't be dropped that easy. yes, the compiler doesn't do such things *now*, but it's ok for it to do it later and... kaboom! previously working code is not working anymore.


October 17, 2014
On Friday, 17 October 2014 at 17:25:47 UTC, monarch_dodra wrote:
> On Friday, 17 October 2014 at 16:19:47 UTC, IgorStepanov wrote:
>> It's just common words=)
>> I meant that when postblit is called when new object is being creating and doesn't exists for user code.
>> E.g.
>> const S v1 = v2;
>> Ok, v1 _will_ be const when it will be _created_.
>> However postblit can think that object is mutable, because it called before the first accessing to the object from user code.
>> Thus I ask about case when postblit may mutate a const object, which created before postblitted object and may been accessed from user code before this postblitting.
>
> That's way too many words for a single sentence for me to understand ;)

Yes, my english is so bad:)

> But maybe this answers your question?
Yes, I've understood.

TBH, I have got this error while I am working on new AA, and I want to fix it as posdible faster (one way or another).
I have the next code:
struct AssociativeArray(Key, Value)
{
...
   struct Entry
   {
      Key key;
      Value value;
      ...
   }
}
If key or value is a const struct with postblit I have got a error.
I don't need an any postblit in Entry.
Thus I suggest another solution:
Do not generate helper functions like __fieldPostBlit, if struct has a @disabled this(this);
Destroy it.
October 17, 2014
On Fri, 17 Oct 2014 19:39:39 +0000
IgorStepanov via Digitalmars-d <digitalmars-d@puremagic.com> wrote:

> Thus I suggest another solution:
> Do not generate helper functions like __fieldPostBlit, if struct
> has a @disabled this(this);
> Destroy it.
`@disable this (this);` means that struct can't be copied. it's irrelevant what code compiler generates behind our backs, it will not be executed anyway, 'cause compiler will complain: "Error: struct XXX is not copyable because it is annotated with @disable".


October 17, 2014
On Friday, 17 October 2014 at 19:45:43 UTC, ketmar via Digitalmars-d wrote:
> On Fri, 17 Oct 2014 19:39:39 +0000
> IgorStepanov via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
>
>> Thus I suggest another solution:
>> Do not generate helper functions like __fieldPostBlit, if struct has a @disabled this(this);
>> Destroy it.
> `@disable this (this);` means that struct can't be copied. it's
> irrelevant what code compiler generates behind our backs, it will not
> be executed anyway, 'cause compiler will complain: "Error: struct XXX is
> not copyable because it is annotated with @disable".

This error will be raised if I try to copy the my struct. But I don't want to do it. Now the error raised when I define the struct.
October 18, 2014
Am Fri, 17 Oct 2014 17:25:46 +0000
schrieb "monarch_dodra" <monarchdodra@gmail.com>:

> But maybe this answers your question?
> 
> import std.stdio;
> 
> struct S
> {
>      int* p;
>      this(this)
>      {
>          ++*p;
>      }
> }
> 
> void main()
> {
>      immutable i = 0;
>      auto s1 = immutable(S)(&i);
>      auto s2 = s1;
>      assert(*&i == 0);
> }

Consider that when passing a variable you can always remove
top level const-ness because a copy is made. This holds for
returns, parameters, assignments, ...
Post-blit is no different. The issue as I see it, is that D
doesn't have strong support for this notion of head-mutable or
else it would work with this type during post-blit:

struct S
{
     immutable(int)* p;
     this(this)
     {
         ++*p;
     }
}

-- 
Marco
October 18, 2014
On Saturday, 18 October 2014 at 06:43:28 UTC, Marco Leise wrote:
> Am Fri, 17 Oct 2014 17:25:46 +0000
> schrieb "monarch_dodra" <monarchdodra@gmail.com>:
>
>> But maybe this answers your question?
>> 
>> import std.stdio;
>> 
>> struct S
>> {
>>      int* p;
>>      this(this)
>>      {
>>          ++*p;
>>      }
>> }
>> 
>> void main()
>> {
>>      immutable i = 0;
>>      auto s1 = immutable(S)(&i);
>>      auto s2 = s1;
>>      assert(*&i == 0);
>> }
>
> Consider that when passing a variable you can always remove
> top level const-ness because a copy is made. This holds for
> returns, parameters, assignments, ...
> Post-blit is no different. The issue as I see it, is that D
> doesn't have strong support for this notion of head-mutable or

D has it for primitives, such as pointers, slices...

> else it would work with this type during post-blit:
>
> struct S
> {
>      immutable(int)* p;
>      this(this)
>      {
>          ++*p;
>      }
> }

Unsure how that's relevant? This code looks wrong to me no matter how you look at it?
October 18, 2014
Am Sat, 18 Oct 2014 08:28:40 +0000
schrieb "monarch_dodra" <monarchdodra@gmail.com>:

> > Consider that when passing a variable you can always remove
> > top level const-ness because a copy is made. This holds for
> > returns, parameters, assignments, ...
> > Post-blit is no different. The issue as I see it, is that D
> > doesn't have strong support for this notion of head-mutable or
> 
> D has it for primitives, such as pointers, slices...
> 
> > else it would work with this type during post-blit:
> >
> > struct S
> > {
> >      immutable(int)* p;
> >      this(this)
> >      {
> >          ++*p;
> >      }
> > }
> 
> Unsure how that's relevant? This code looks wrong to me no matter how you look at it?

This is the only relevant point to discuss. The act of blitting is a shallow copy. Hence while the copy is created there is no risk in modifying its bits. Hence the proposal to make make it mutable.

But then you added deepness in form of a pointer to the structure that a shallow copy doesn't cover.

So I concluded that the issue with making postblit mutable is
that it removes immutable transitively through pointers,
while for a shallow copy it must be shallow, too. That's just a
basic observation. The imaginary struct I showed is the result
of that. It only removes the top level immutable from the
struct and would error out as you try modify the dereferenced
immutable(int) while reassignment would work.

-- 
Marco

October 19, 2014
17-Oct-2014 18:18, monarch_dodra пишет:
> On Friday, 17 October 2014 at 00:55:25 UTC, ketmar via Digitalmars-d wrote:
>> On Fri, 17 Oct 2014 00:42:24 +0000
>> IgorStepanov via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
>>
>>> Can someone comment this code? Should I think that it's a bug.
>> it's just an anomaly. const postblit can do alot of things besides
>> adjusting struct fields, and it's logical that compiler cannot call
>> non-const methods for const objects.
>>
>> yet it's still on of those "unforseen consequences" that arises from
>> conjunction of different features.
>>
>> i don't think that it's a bug, but i think that this must be discussed
>> anyway, and then documented.
>
> AFAIK, Kenji has submitted a DIP, and has begun working on "fixing" the
> const/immutable/inout posblit issue.
>
> However, there are some very subtle corner cases, so (afaik) work is slow.
>
> To be honest, I think people use "const" way too much in D. It's *not*
> the C++ head const you can use anywhere.

s/can/need to/

Which in case of const T& is a just a kind of mnemonic to accept both l-value and r-value.

Anyhow I think we can probably extend final to mean single-assignment field (a-la Java). But the gain to semantic load factor is too small IMHO.


-- 
Dmitry Olshansky