Jump to page: 1 24  
Page
Thread overview
DConf 2013 Day 1 Talk 2 (Copy and Move Semantics)
May 11, 2013
H. S. Teoh
May 11, 2013
Ali Çehreli
May 11, 2013
Walter Bright
May 11, 2013
Diggory
May 11, 2013
Ali Çehreli
May 11, 2013
deadalnix
May 11, 2013
Simen Kjaeraas
May 11, 2013
Diggory
May 11, 2013
Simen Kjaeraas
May 12, 2013
Diggory
May 12, 2013
Jonathan M Davis
May 12, 2013
Simen Kjaeraas
May 12, 2013
Diggory
May 12, 2013
Simen Kjaeraas
May 12, 2013
deadalnix
May 12, 2013
Simen Kjaeraas
May 12, 2013
Simen Kjaeraas
May 12, 2013
Thiez
May 12, 2013
Walter Bright
May 12, 2013
Dmitry Olshansky
May 12, 2013
Walter Bright
May 13, 2013
Dmitry Olshansky
May 13, 2013
Walter Bright
May 13, 2013
deadalnix
May 12, 2013
deadalnix
May 12, 2013
Simen Kjaeraas
May 11, 2013
Manu
May 11, 2013
Jonathan M Davis
May 11, 2013
Simen Kjaeraas
May 11, 2013
Woohoo, Ali's talk is up! Just finished watching it. I have to thank Ali for a most excellent presentation. Very informative and insightful, and I learned several really cool things about D that I wasn't even aware of before:

- to!string doesn't copy when the source is already a string 'cos it's
  immutable. Sweeeet!

- The bit about swapping of structs when assigning a function's return
  value. Makes a lot of sense semantically! Though it does bear looking
  into for further optimizations. What about in-place construction if a
  struct is known to be returned to the caller, so that even the move is
  elided?

- The bit about exception-safe ctors: awesome!! Yet another thing D gets
  right, that blows up in C++.

- Implicit casting to immutable from return value of pure functions --
  that is absolutely awesome, and as Walter said, yes we should
  definitely explore this more. Looks like we can have our cake and eat
  it too!

- The idiom of using this(S that) vs. this(ref const(S) that) for
  move/copy: another awesome idiom that should be documented in a
  prominent place so that more people are aware of it.


T

-- 
Questions are the beginning of intelligence, but the fear of God is the beginning of wisdom.
May 11, 2013
On 05/10/2013 10:03 PM, H. S. Teoh wrote:

> I have to thank Ali

Thank you, it's very kind of you.

> - The bit about swapping of structs when assigning a function's return
>    value. Makes a lot of sense semantically! Though it does bear looking
>    into for further optimizations.

deadalnix mentioned the same thing: Instead of bit-swapping, it is possible to destroy the old state first and then bit-move from the rvalue. I am pretty sure that is how it is done by the compiler. Still, I find it easier to think about in terms of bit-swapping.

> What about in-place construction if a
>    struct is known to be returned to the caller, so that even the move is
>    elided?

I think that is the RVO and the NRVO optimization, which is not possible in every case. For example, if I am not mistaken, it is not possible if the fonction returns one of two possible values conditionally (e.g. by the ternary operator).

> - The bit about exception-safe ctors: awesome!! Yet another thing D gets
>    right, that blows up in C++.

(Correction: exception-safe _assignment_).

As far as I know, I am one of the few who point out the glaring exception-unsafe behavior of the assignment operator of C++.

Every C++ programmer knows about "the rule of the big three" (ctor, dtor, assignment) but nobody talks about "the rule of the big one". (assignment) :) For strongly exception-safe assignment, one must always define the assignment operator. (Well, for types that have multiple members and that the ones after the first one may throw. (It is ok if the first one throws; then there would be no partial assignment.))

> - The idiom of using this(S that) vs. this(ref const(S) that) for
>    move/copy: another awesome idiom that should be documented in a
>    prominent place so that more people are aware of it.

Actually that one is well documented in TDPL.

Ali

May 11, 2013
On 5/10/2013 11:49 PM, Ali Çehreli wrote:
> As far as I know, I am one of the few who point out the glaring exception-unsafe
> behavior of the assignment operator of C++.

Since Andrei did the design (copy-swap), I'm sure he's well aware of it!

May 11, 2013
Just listened to this talk and it made me think about the various type qualifiers. Has there ever been any thought of introducing a new type qualifier/attribute, "unique"? I know it already exists as a standard library class but I think there are several advantages to having it as a language feature:

- "unique" objects can be moved into default, const, unique or immutable variables, but can never be copied.

- "new"/constructors always returns a "unique" object, which can then be moved into any type, completely eliminating the need for different types of constructors.

- Functions which create new objects can also return a "unique" object solving the problem mentioned in this talk of whether or not to return immutable values.

- "assumeUnique" would actually return a "unique" type, but would be unnecessary in most cases.

- Strings can be efficiently built in "unique" character arrays and then safely returned as immutable without a cast.

- The compiler can actually provide strong guarantees about uniqueness compared to the rather weak guarantees possible in std.typecons.Unique.

- It can be extremely useful for optimisation if the compiler can know that there are no other references to an object. There are countless times when this knowledge would make otherwise unsafe optimisations safe.



May 11, 2013
On 05/11/2013 04:12 AM, Diggory wrote:

> Has there ever been any thought of introducing a new type
> qualifier/attribute, "unique"?

There has been discussions about this idea. Just two on the D.learn newsgroup that mention an experimental UniqueMutable idea:

  http://forum.dlang.org/thread/itr5o1$poi$1@digitalmars.com

  http://forum.dlang.org/thread/jd26ig$27qd$1@digitalmars.com?page=2

I am sure there are other on this newsgroup as well.

Ali

May 11, 2013
On Saturday, 11 May 2013 at 14:53:39 UTC, Ali Çehreli wrote:
> On 05/11/2013 04:12 AM, Diggory wrote:
>
> > Has there ever been any thought of introducing a new type
> > qualifier/attribute, "unique"?
>
> There has been discussions about this idea. Just two on the D.learn newsgroup that mention an experimental UniqueMutable idea:
>
>   http://forum.dlang.org/thread/itr5o1$poi$1@digitalmars.com
>
>   http://forum.dlang.org/thread/jd26ig$27qd$1@digitalmars.com?page=2
>
> I am sure there are other on this newsgroup as well.
>
> Ali

Microsft have a very good paper on the subject : http://research.microsoft.com/pubs/170528/msr-tr-2012-79.pdf

But I don't think this should be implemented before more deep issue are sorted out.
May 11, 2013
On 2013-05-11, 13:12, Diggory wrote:

> Just listened to this talk and it made me think about the various type qualifiers. Has there ever been any thought of introducing a new type qualifier/attribute, "unique"? I know it already exists as a standard library class but I think there are several advantages to having it as a language feature:
>
> - "unique" objects can be moved into default, const, unique or immutable variables, but can never be copied.
>
> - "new"/constructors always returns a "unique" object, which can then be moved into any type, completely eliminating the need for different types of constructors.
>
> - Functions which create new objects can also return a "unique" object solving the problem mentioned in this talk of whether or not to return immutable values.
>
> - "assumeUnique" would actually return a "unique" type, but would be unnecessary in most cases.
>
> - Strings can be efficiently built in "unique" character arrays and then safely returned as immutable without a cast.
>
> - The compiler can actually provide strong guarantees about uniqueness compared to the rather weak guarantees possible in std.typecons.Unique.
>
> - It can be extremely useful for optimisation if the compiler can know that there are no other references to an object. There are countless times when this knowledge would make otherwise unsafe optimisations safe.

unique is interesting, and holds many promises. However, its effects may
be wide-spanning and have many corner case.

In addition to mutability, unique applies to shared/unshared - a unique
value may safely be moved to another thread.

Pure functions whose parameters are all unique or value types will always
return a unique result. (Note that this is similar to how pure function
results are now implicitly castable to immutable, but unique is stricter)

For unique values not to lose unicity when passed to functions, there
must be ways to specify that the function will not create new aliases to
the passed value. scope might fit the bill here, otherwise something like
lent must be added.

-- 
Simen
May 11, 2013
>
> unique is interesting, and holds many promises. However, its effects may
> be wide-spanning and have many corner case.
>
> In addition to mutability, unique applies to shared/unshared - a unique
> value may safely be moved to another thread.
>
> Pure functions whose parameters are all unique or value types will always
> return a unique result. (Note that this is similar to how pure function
> results are now implicitly castable to immutable, but unique is stricter)
>
> For unique values not to lose unicity when passed to functions, there
> must be ways to specify that the function will not create new aliases to
> the passed value. scope might fit the bill here, otherwise something like
> lent must be added.

That's solved by the rule that "unique" values can only be moved not copied. To pass a "unique" parameter by value to a function the original must be invalidated in the process. The only other way would be to pass by reference, in which case the function argument must also be declared "unique".

The rule about pure functions returning "unique" is not in general true - if it returns a class which has a pointer to itself, or a pointer to another class which has a pointer to itself then the return value is not unique. The return value must specifically be declared unique.

The only problem I can see is with the "this" pointer:
- If we have unique and non-unique functions it means duplicating everything, or at least remembering to add the "unique" attribute.
- Unique would then be both a type modifier and a function attribute
- It's not immediately obvious what operations can be performed by a "unique" member function.
- It is not simply equivalent to marking the "this" parameter as unique because that would mean erasing the argument passed in for that parameter, ie. invalidating the object!

But I think that can also be solved satisfactorily:
- Make the unique-ness of a member function something which is implicitly determined by the compiler based on its content.
- Any function which only dereferences the "this" pointer can safely be marked "unique" internally, and therefore can be called on a unique variable. If it copies the "this" pointer (auto x = this) then it is not "unique".
May 11, 2013
On 2013-05-11, 23:40, Diggory wrote:

>>
>> unique is interesting, and holds many promises. However, its effects may
>> be wide-spanning and have many corner case.
>>
>> In addition to mutability, unique applies to shared/unshared - a unique
>> value may safely be moved to another thread.
>>
>> Pure functions whose parameters are all unique or value types will always
>> return a unique result. (Note that this is similar to how pure function
>> results are now implicitly castable to immutable, but unique is stricter)
>>
>> For unique values not to lose unicity when passed to functions, there
>> must be ways to specify that the function will not create new aliases to
>> the passed value. scope might fit the bill here, otherwise something like
>> lent must be added.
>
> That's solved by the rule that "unique" values can only be moved not copied.

What is? The last part?


> To pass a "unique" parameter by value to a function the original must be invalidated in the process. The only other way would be to pass by reference, in which case the function argument must also be declared "unique".

In which case we end up with duplicates of all functions to support both
unique and non-unique parameters. Hence we'd need scope or lent.


> The rule about pure functions returning "unique" is not in general true - if it returns a class which has a pointer to itself, or a pointer to another class which has a pointer to itself then the return value is not unique. The return value must specifically be declared unique.

I'm not convinced. unique, like const or immutable, is transitive. If foo
is unique, then so is foo.bar.


> The only problem I can see is with the "this" pointer:
> - If we have unique and non-unique functions it means duplicating everything, or at least remembering to add the "unique" attribute.
> - Unique would then be both a type modifier and a function attribute
> - It's not immediately obvious what operations can be performed by a "unique" member function.
> - It is not simply equivalent to marking the "this" parameter as unique because that would mean erasing the argument passed in for that parameter, ie. invalidating the object!

Look above again. With 'lent', the function guarantees not to create new,
escaping aliases. Thus, a unique value may be passed by ref (e.g. the
'this' pointer) without erasing the value.

The syntax would thus be:

class A {
    void forble() lent {
        globalValue = this; // Compile-time error.
    }
}


> But I think that can also be solved satisfactorily:
> - Make the unique-ness of a member function something which is implicitly determined by the compiler based on its content.

Won't work. The function body is not always available.


> - Any function which only dereferences the "this" pointer can safely be marked "unique" internally, and therefore can be called on a unique variable. If it copies the "this" pointer (auto x = this) then it is not "unique".

Temporary copies are fine. Only those that escape the function are
problematic.

-- 
Simen
May 11, 2013
On 11 May 2013 21:12, Diggory <diggsey@googlemail.com> wrote:

> Just listened to this talk and it made me think about the various type qualifiers. Has there ever been any thought of introducing a new type qualifier/attribute, "unique"? I know it already exists as a standard library class but I think there are several advantages to having it as a language feature:
>
> - "unique" objects can be moved into default, const, unique or immutable variables, but can never be copied.
>
> - "new"/constructors always returns a "unique" object, which can then be moved into any type, completely eliminating the need for different types of constructors.
>
> - Functions which create new objects can also return a "unique" object solving the problem mentioned in this talk of whether or not to return immutable values.
>
> - "assumeUnique" would actually return a "unique" type, but would be unnecessary in most cases.
>
> - Strings can be efficiently built in "unique" character arrays and then safely returned as immutable without a cast.
>
> - The compiler can actually provide strong guarantees about uniqueness compared to the rather weak guarantees possible in std.typecons.Unique.
>
> - It can be extremely useful for optimisation if the compiler can know that there are no other references to an object. There are countless times when this knowledge would make otherwise unsafe optimisations safe.
>

This is a very interesting idea.
It would also be a massive advantage when passing ownership between
threads, which is a long-standing problem that's not solves at all.
There currently exists no good way to say "I now give ownership to you",
which is what you basically always do when putting a job on a queue to be
picked up by some foreign thread.
Using shared is cumbersome, and feels very inelegant, casts everywhere, and
once the casts appear, any safety is immediately lost.

Can you detail the process involved in assignment from one unique to another unique? Would the original unique be destroyed? Leaving only the 'copy' remaining?


« First   ‹ Prev
1 2 3 4