February 04, 2016
On Thursday, 4 February 2016 at 01:26:55 UTC, Andrei Alexandrescu wrote:
> On 02/03/2016 07:48 PM, Matt Elkins wrote:
>> This [apparent] lack of clean move semantics
>
> I very much wish there was a quick summary. I figure you've seen std.algorithm.move. What's missing? -- Andrei

Apologies, should have summarized. The issue I've been focused on has been emulating C++'s std::unique_ptr for the purposes of handling system resources which need explicit cleanup and which are not copyable (or for which I want to disallow copying for whatever reason). I want to still be able to move around my handles to these resources, so long as the single-owner aspect is maintained, and I want the wrapper to have minimal overhead (so for example std.typecons.Unique is out, since it appears to require the heap one way or another); in essence, I want std::unique_ptr. It is quite possible that this is doable, but if so the solution eludes me. Here is what I have so far:

[code]
import std.algorithm;

struct ResourceHandle(T, alias Deleter, T Default = T.init)
{
    // Constructors/Destructor
    this(T handle) {m_handle = handle;}
    @disable this(this);
    ~this() {Deleter(m_handle);}

    // Operators
    @disable void opAssign(ref ResourceHandle lvalue);
    ref ResourceHandle opAssign(ResourceHandle rvalue) {swap(m_handle, rvalue.m_handle); return this;}

    // Methods
    @property inout(T) handle() inout {return m_handle;}
    @property T handle(T handle) {Deleter(m_handle); m_handle = handle; return m_handle;}
    T release() {T result = m_handle; m_handle = Default; return result;}

    private:
        T m_handle = Default;
}
[/code]

This seems to cover most of my bases, but I still can't do things like this:

[code]
unittest
{
    alias RH = ResourceHandle!(uint, (uint) {});
    RH[] handles;
    handles ~= RH(5); // Compile error: ResourceHandle is not copyable because it is annotated with @disable
}
[/code]

One person on the forums suggested that this might be a compiler bug (and referred me to a maybe-related bug report from 2011), but it also might not. This seems to have similar practical functionality to std::auto_ptr; works reasonably well for passing around individual instances, but gets iffy when you want to put it into a container. Incidentally, I -am- able to do this:

[code]
unittest
{
    alias RH = ResourceHandle!(uint, (uint) {});

    RH[] handles;
    ++handles.length;
    handles[$ - 1] = RH(5);
}
[/code]

This has become my effective workaround, but it isn't terribly clean and may not scale to other kinds of data structures (or it may, haven't thought it through). Of course, I'm a D newbie and could well just not be seeing the right way to define ResourceHandle.

Sorry for all the C++ allusions to explain my intent. Then again, I'm not terribly worried that the author of MC++D won't follow them :).
February 03, 2016
On 02/03/2016 09:01 PM, Matt Elkins wrote:
>
> [code]
> import std.algorithm;
>
> struct ResourceHandle(T, alias Deleter, T Default = T.init)
> {
>      // Constructors/Destructor
>      this(T handle) {m_handle = handle;}
>      @disable this(this);
>      ~this() {Deleter(m_handle);}
>
>      // Operators
>      @disable void opAssign(ref ResourceHandle lvalue);
>      ref ResourceHandle opAssign(ResourceHandle rvalue) {swap(m_handle,
> rvalue.m_handle); return this;}
>
>      // Methods
>      @property inout(T) handle() inout {return m_handle;}
>      @property T handle(T handle) {Deleter(m_handle); m_handle = handle;
> return m_handle;}
>      T release() {T result = m_handle; m_handle = Default; return result;}
>
>      private:
>          T m_handle = Default;
> }
> [/code]
>
> This seems to cover most of my bases, but I still can't do things like
> this:
>
> [code]
> unittest
> {
>      alias RH = ResourceHandle!(uint, (uint) {});
>      RH[] handles;
>      handles ~= RH(5); // Compile error: ResourceHandle is not copyable
> because it is annotated with @disable
> }
> [/code]

Got it, thanks. That's a bug in the implementation, no two ways about it. No copy should occur there, neither theoretically nor practically. Please report it to bugzilla at http://issues.dlang.org. Thanks very much! -- Andrei

February 04, 2016
On Thursday, 4 February 2016 at 01:26:55 UTC, Andrei Alexandrescu wrote:
> On 02/03/2016 07:48 PM, Matt Elkins wrote:
>> This [apparent] lack of clean move semantics
>
> I very much wish there was a quick summary. I figure you've seen std.algorithm.move. What's missing? -- Andrei

I am in a similar boat as Matt Elkins. The problem is not D's move semantics, but that Phobos does not support them at all.

I have already several things that are not copyable, one of them is "Unique". It feels incredibly restrictive to use those in D. You can not put them in Arrays, you can not put them in Tuples, you can not use writeln on them, you can basically not use them at all in Phobos because pretty much everything relies on copying.

I have currently written tons of stuff from scratch just to support a few non copyable types. This is probably my biggest complain about D so far.

It might still be the case that I am missing something obvious here.
February 04, 2016
On Thursday, 4 February 2016 at 03:45:57 UTC, maik klein wrote:
> On Thursday, 4 February 2016 at 01:26:55 UTC, Andrei Alexandrescu wrote:
>> [...]
>
> I am in a similar boat as Matt Elkins. The problem is not D's move semantics, but that Phobos does not support them at all.
>
> I have already several things that are not copyable, one of them is "Unique". It feels incredibly restrictive to use those in D. You can not put them in Arrays, you can not put them in Tuples, you can not use writeln on them, you can basically not use them at all in Phobos because pretty much everything relies on copying.
>
> I have currently written tons of stuff from scratch just to support a few non copyable types. This is probably my biggest complain about D so far.
>
> It might still be the case that I am missing something obvious here.

Those are intended not to be copied, they must be explicitly moved with std.algorithm's move
February 04, 2016
On Thursday, 4 February 2016 at 02:33:06 UTC, Andrei Alexandrescu wrote:
> On 02/03/2016 09:01 PM, Matt Elkins wrote:
>> [...]
>
> Got it, thanks. That's a bug in the implementation, no two ways about it. No copy should occur there, neither theoretically nor practically. Please report it to bugzilla at http://issues.dlang.org. Thanks very much! -- Andrei

possibly related
https://issues.dlang.org/show_bug.cgi?id=7579
February 03, 2016
On 02/03/2016 10:45 PM, maik klein wrote:
> It might still be the case that I am missing something obvious here.

You're not. The situation with noncopyable types is similar to that in C++ pre-11: people could define them, but the stdlib implementation wasn't supporting them in all places possible.

This is not difficult - all we need is to figure which library primitives should support noncopyable types and change implementations accordingly.


Andrei
February 04, 2016
On Thursday, 4 February 2016 at 03:52:23 UTC, rsw0x wrote:
> On Thursday, 4 February 2016 at 03:45:57 UTC, maik klein wrote:
>> On Thursday, 4 February 2016 at 01:26:55 UTC, Andrei Alexandrescu wrote:
>>> [...]
>>
>> I am in a similar boat as Matt Elkins. The problem is not D's move semantics, but that Phobos does not support them at all.
>>
>> I have already several things that are not copyable, one of them is "Unique". It feels incredibly restrictive to use those in D. You can not put them in Arrays, you can not put them in Tuples, you can not use writeln on them, you can basically not use them at all in Phobos because pretty much everything relies on copying.
>>
>> I have currently written tons of stuff from scratch just to support a few non copyable types. This is probably my biggest complain about D so far.
>>
>> It might still be the case that I am missing something obvious here.
>
> Those are intended not to be copied, they must be explicitly moved with std.algorithm's move

I don't understand what you are saying. Are you saying that I can use them with Arrays, Tuples etc and I just have to use move somehow? If that is the case please show me because I have already wasted a lot of time into recreating Array, Tuple etc.

Or are you saying that I they are not compatible with Phobos?
February 04, 2016
On Thursday, 4 February 2016 at 03:57:18 UTC, maik klein wrote:
> On Thursday, 4 February 2016 at 03:52:23 UTC, rsw0x wrote:
>> On Thursday, 4 February 2016 at 03:45:57 UTC, maik klein wrote:
>>> [...]
>>
>> Those are intended not to be copied, they must be explicitly moved with std.algorithm's move
>
> I don't understand what you are saying. Are you saying that I can use them with Arrays, Tuples etc and I just have to use move somehow? If that is the case please show me because I have already wasted a lot of time into recreating Array, Tuple etc.
>
> Or are you saying that I they are not compatible with Phobos?

Can you show me an example of the issue you're having? You might be hitting the same bug as already seen in this thread.
Theoretically they should be workable with move.
...Theoretically : )
February 04, 2016
On Thursday, 4 February 2016 at 02:33:06 UTC, Andrei Alexandrescu wrote:
> Got it, thanks. That's a bug in the implementation, no two ways about it. No copy should occur there, neither theoretically nor practically. Please report it to bugzilla at http://issues.dlang.org. Thanks very much! -- Andrei

I don't see how that point can be argued.

The language reference states:
«
a op= b
are semantically equivalent to:
a = cast(typeof(a))(a op b)
»

Therefore:

«a ~= b» should be semantically equivalent to « a =  cast(typeof(a))(a ~ b)»

So if the language reference is correct you need copy semantics?

I hope you guys will make sure that the language reference is in sync with the implementation.

February 04, 2016
On Thursday, 4 February 2016 at 02:33:06 UTC, Andrei Alexandrescu wrote:
> On 02/03/2016 09:01 PM, Matt Elkins wrote:
>> [code]
>> unittest
>> {
>>      alias RH = ResourceHandle!(uint, (uint) {});
>>      RH[] handles;
>>      handles ~= RH(5); // Compile error: ResourceHandle is not copyable
>> because it is annotated with @disable
>> }
>> [/code]
>
> Got it, thanks. That's a bug in the implementation, no two ways about it. No copy should occur there, neither theoretically nor practically. Please report it to bugzilla at http://issues.dlang.org. Thanks very much! -- Andrei

 Something like a week ago i sorta was awaiting confirmation of a bug VERY similar to this one, from this thread posting:

 http://forum.dlang.org/post/iahbnmcbtsdolczaqkta@forum.dlang.org

 The related bug reported (not a exact match, but close enough) is also present

 https://issues.dlang.org/show_bug.cgi?id=7032