December 20, 2013
2013/12/20 deadalnix <deadalnix@gmail.com>

> On Thursday, 19 December 2013 at 15:32:33 UTC, Kenji Hara wrote:
>
>> I think it is necessary small learning cost, to keep language semantics simple.
>>
>> Kenji Hara
>>
>
> If that is an extra learning cost, doesn't it make the semantic more complex, almost by definition ?
>

I say it is small but *necessary* cost. It's not extra cost.

I'm also against adding a new meaning to const, especially when its current
> meaning can make sense.
>

These DIPs does not add a new meaning to 'const' as the type qualifier and
method qualifier. They binds new meanings to "this(this) const" and
this(...) const".
You need to learn added meaning, so it's not free, but I'd also say it's
enough trivial.

Kenji Hara


December 20, 2013
On 2013-12-20 01:31:03 +0000, Kenji Hara <k.hara.pg@gmail.com> said:

> 
> 2013/12/20 Michel Fortin <michel.fortin@michelf.ca>
> 
>> On 2013-12-18 03:42:38 +0000, "Kenji Hara" <k.hara.pg@gmail.com> said:
>> 
>> 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
>>> 
>> 
>> I can't help but notice that if you want class-typed members to be
>> assignable in a "this(this) immutable" context you'll need to add
>> tail-constness for classes in the language.
> 
> 
> Sorry I can't understand what you saying. DIP49 does not touch class
> reference semantics. It's not a purpose of DIP49.

But what if your struct has a class-typed member:

	struct A {
		Object o;
		int* a;

		this(this) {
			a = new int;
			o = new Object;
		}

		this(this) immutable {
			a = new immutable(int);
			o = new immutable(Object); // will that work?
		}
	}

On the second postblit, the type of "a" has to be "immutable(int)*" to allow you to assign something else to the pointer while not being able to affect what's at the other end of the indirection.

So then, what is the type of "o"? Again, you need to be able to assign the variable while not affecting what is at the other end of the indirection. You need a tail-immutable object reference, which doesn't exist.


-- 
Michel Fortin
michel.fortin@michelf.ca
http://michelf.ca

December 20, 2013
On 2013-12-20 02:07:32 +0000, Michel Fortin <michel.fortin@michelf.ca> said:

> But what if your struct has a class-typed member:
> 
> 	struct A {
> 		Object o;
> 		int* a;
> 
> 		this(this) {
> 			a = new int;
> 			o = new Object;
> 		}
> 
> 		this(this) immutable {
> 			a = new immutable(int);
> 			o = new immutable(Object); // will that work?
> 		}
> 	}
> 
> On the second postblit, the type of "a" has to be "immutable(int)*" to allow you to assign something else to the pointer while not being able to affect what's at the other end of the indirection.
> 
> So then, what is the type of "o"? Again, you need to be able to assign the variable while not affecting what is at the other end of the indirection. You need a tail-immutable object reference, which doesn't exist.

I just want to add that this is not a criticism of the DIP in any way. I'm simply pointing out that it'll just make more visible an already embarrassing omission in the language.

-- 
Michel Fortin
michel.fortin@michelf.ca
http://michelf.ca

December 20, 2013
2013/12/20 Michel Fortin <michel.fortin@michelf.ca>

> But what if your struct has a class-typed member:
>
>         struct A {
>                 Object o;
>                 int* a;
>
>                 this(this) {
>                         a = new int;
>                         o = new Object;
>                 }
>
>                 this(this) immutable {
>                         a = new immutable(int);
>                         o = new immutable(Object); // will that work?
>                 }
>         }
>
> On the second postblit, the type of "a" has to be "immutable(int)*" to allow you to assign something else to the pointer while not being able to affect what's at the other end of the indirection.
>
> So then, what is the type of "o"? Again, you need to be able to assign the variable while not affecting what is at the other end of the indirection. You need a tail-immutable object reference, which doesn't exist.


That's already resolved "design issue" from 2.064, by fixing issue 9665. http://d.puremagic.com/issues/show_bug.cgi?id=9665

Inside constructor, first occured field assignment is automatically handled as the field initializing.

struct A {
    Object o;
    int* a;
    this(int) immutable {
        a = new immutable(int);
        // is exactly same as: immutable int* a = new immutable(int);

        o = new immutable(Object);
        // is exactly same as: immutable(Object) o = new immutable(Object);
    }

Inside postblit, the same rule should be applied.

    this(this) immutable {
        a = new immutable(int);
        // is exactly same as: immutable int* a = new immutable(int);

        o = new immutable(Object);
        // is exactly same as: immutable(Object) o = new immutable(Object);
    }

Unfortunately postblit case does not work. I can say it's definitely a
compiler bug.
http://d.puremagic.com/issues/show_bug.cgi?id=11292

However, I'm purposely delaying to fix the bug, because of DIP49.

Kenji Hara


December 20, 2013
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, versus introducing an extra keyword which is used _only_ in this context and which is not entirely intuitive.

I'd have said the second would be more complex and more likely to lead to practical misunderstanding.
December 20, 2013
Joseph Rushton Wakeling:

> As far as I can see, it's learning a small extra meaning of 'const' in a context where it's quite intuitive, versus introducing an extra keyword which is used _only_ in this context and which is not entirely intuitive.

A new keyword is a flag that you have found something different. It makes it simpler to learn.


> I'd have said the second would be more complex and more likely to lead to practical misunderstanding.

Giving different names to different ideas makes them less complex :-)

(We are bikeshedding a little.)

Bye,
bearophile
December 20, 2013
On Thursday, 19 December 2013 at 09:52:15 UTC, Joseph Rushton Wakeling wrote:
> Unless there's a good application of a specifically const-specific postblit/constructor, it seems to me that the conflation in the DIP is helpful, because it simplifies the process of writing, understanding and using code at the cost of something which probably wouldn't be practically very useful.

Yes, I think that REAL const-specific postblit/constructor can be useful, for example, for advanced dynamic typing.

For example, we can have reference-counting policy for some data object (for example, for manual memory management). So, we should create smart pointer with simple well-known rules: increase reference count if we create new smart pointer, decrease reference count if we destroy old smart pointer and destroy data object if reference count is equal zero.
Now assume that you need multithread support (it's also well-known problem). So, you must use synchronization (mutex and/or atomic operations) for every data object access because because another thread can modify data object.

Now assume that we have REAL const-specific postblit/constructor support. In this case we can separate `mutable` and `const` reference counts. If `mutable` reference count is equal 0 we can access data object witout any synchronization because nobody can't change data object (and it will be definetly faster because mutex and/or atomic operations is very slow).

So, REAL const-specific postblit/constructor can be really useful for advanced dynamic typing and optimization. Am I right?

Another question: for example, we will decide that we want to have REAL const-specific postblit/constructor support after 5-10 years (who knows what happens with D in future?). What should we do in this case: introduce new `realconst` keyword only for REAL const-specific postblit/constructor? Would you like to be responsible for this decision?
December 20, 2013
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.
December 20, 2013
On 12/20/13, Andrej Mitrovic <andrej.mitrovich@gmail.com> wrote:
> at least with
> asserts in the actual body I can add diagnostic messages)

Sorry that was wrong, "in" can be used for that of course. But I don't see the benefit of in blocks.
December 20, 2013
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.