Thread overview | ||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
May 11, 2013 DConf 2013 Day 1 Talk 2 (Copy and Move Semantics) | ||||
---|---|---|---|---|
| ||||
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 Re: DConf 2013 Day 1 Talk 2 (Copy and Move Semantics) | ||||
---|---|---|---|---|
| ||||
Posted in reply to H. S. Teoh | 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 Re: DConf 2013 Day 1 Talk 2 (Copy and Move Semantics) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | 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 Re: DConf 2013 Day 1 Talk 2 (Copy and Move Semantics) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | 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 Re: DConf 2013 Day 1 Talk 2 (Copy and Move Semantics) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Diggory | 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 Re: DConf 2013 Day 1 Talk 2 (Copy and Move Semantics) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | 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 Re: DConf 2013 Day 1 Talk 2 (Copy and Move Semantics) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Diggory | 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 Re: DConf 2013 Day 1 Talk 2 (Copy and Move Semantics) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Simen Kjaeraas | >
> 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 Re: DConf 2013 Day 1 Talk 2 (Copy and Move Semantics) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Diggory | 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 Re: DConf 2013 Day 1 Talk 2 (Copy and Move Semantics) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Diggory Attachments:
| 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?
|
Copyright © 1999-2021 by the D Language Foundation