Constructors (starstruck noob from C++)

2011-01-20 Thread Luke J. West
Hi to all from a total noob.

first of all, I'd like to say how impressed I am with D. In fact, I keep
pinching myself. Have I *really* found a language worth leaving C++ for
after two decades? It's beginning to look that way. Obviously I'm
devouring the 2.0 documentation right now, but have not yet found out
how to create a new instance of an existing class object. What I mean
is, given...

auto a = new A;

how do I, in c++ speak, do the D for...

A  b(a); // or if you prefer...
A* b = new A(a);

I'm sure this must be trivial.

Many many thanks,

Luke


Re: Constructors (starstruck noob from C++)

2011-01-20 Thread Ellery Newcomer

Welcome!

On 01/20/2011 07:18 PM, Luke J. West wrote:


how do I, in c++ speak, do the D for...

A  b(a); // or if you prefer...
A* b = new A(a);


try

A b = new A(a);



I'm sure this must be trivial.

Many many thanks,

Luke




Re: Constructors (starstruck noob from C++)

2011-01-20 Thread Jonathan M Davis
On Thursday, January 20, 2011 17:18:48 Luke J. West wrote:
> Hi to all from a total noob.
> 
> first of all, I'd like to say how impressed I am with D. In fact, I keep
> pinching myself. Have I *really* found a language worth leaving C++ for
> after two decades? It's beginning to look that way. Obviously I'm
> devouring the 2.0 documentation right now, but have not yet found out
> how to create a new instance of an existing class object. What I mean
> is, given...
> 
> auto a = new A;
> 
> how do I, in c++ speak, do the D for...
> 
> A  b(a); // or if you prefer...
> A* b = new A(a);
> 
> I'm sure this must be trivial.
> 
> Many many thanks,

Well, you could create a constructor which is effectively a copy constructor. 
There has been talk of a general cloning mechanism which would give you a 
correct clone method essentially for free, but it hasn't been done yet (not 
sure 
why; I don't recall exactly where the last discussion on that went other than 
it 
was generally accepted that we wanted something like that). However, at the 
moment, I'm not aware of any general way to copy a class instance like you're 
trying to do.

Structs have postblit constructors:

this(this)
{
   //...
}

where a shallow copy of the struct is made prior to entering this(this), and 
then you do whatever you need to do inside it to make it a deep copy (or just 
don't have a postblit constructor if you don't need a deep copy). However, 
classes are reference types and don't have anything like that.

So, we need to add a means to generate clone methods for classes so that 
copying 
classes will be easy, but we haven't done it yet. I'm not sure what the current 
obstacles to doing it are.

- Jonathan M Davis


Re: Constructors (starstruck noob from C++)

2011-01-20 Thread Andrei Alexandrescu

On 1/20/11 7:18 PM, Luke J. West wrote:

Hi to all from a total noob.

first of all, I'd like to say how impressed I am with D. In fact, I keep
pinching myself. Have I *really* found a language worth leaving C++ for
after two decades? It's beginning to look that way. Obviously I'm
devouring the 2.0 documentation right now, but have not yet found out
how to create a new instance of an existing class object. What I mean
is, given...

auto a = new A;

how do I, in c++ speak, do the D for...

A  b(a); // or if you prefer...
A* b = new A(a);

I'm sure this must be trivial.

Many many thanks,

Luke


Hopefully this won't mark a demise of your newfound interest :o). If A 
were a struct, auto b = new A(*a) would do. For classes, D does not 
provide automatic copy constructors; you need to define and follow a 
sort of cloning protocol.


That being said, it's not difficult to define a generic function that 
copies fields over from one class object to another. Here's a start:


import std.stdio;

void copyMembers(A)(A src, A tgt) if (is(A == class)) {
foreach (e; __traits(allMembers, A)) {
static if (!is(typeof(__traits(getMember, src, e)) == function)
   && e != "Monitor")
{
__traits(getMember, tgt, e) = __traits(getMember, src, e);
}
}
}

class A {
int x = 42;
string y = "hello";
final void fun1() {}
void fun2() {}
static void fun3(){}
}

void main() {
auto a = new A;
a.x = 43;
auto b = new A;
copyMembers(a, b);
assert(b.x == 43);
}

I think copyMembers belongs to the standard library. I wanted to define 
a family of functions like it but never got around to it.



Andrei


Re: Constructors (starstruck noob from C++)

2011-01-20 Thread Andrej Mitrovic
Be afraid.. be very afraid!

import std.algorithm;
import std.stdio;
import std.conv;

enum fields = [__traits(allMembers, Foo)];

string populateFields(string[] haystack)
{
string result;
while (haystack.length > 0)
{
switch (haystack[0])
{
case "__ctor":
case "__dtor":
haystack = haystack[1 .. $];  // skip ctors, dtors,
can't assign those..
continue;
default:
}

result ~= "this."
   ~ haystack[0]
   ~ " = foo."
   ~ haystack[0]
   ~ ";";

haystack = haystack[1 .. $];
}
return result;
}

class Foo
{
int x;
int y;
this(Foo foo)
{
mixin(populateFields(fields));
}

this()
{
}

~this()
{
}
}

void main()
{
auto foo = new Foo();
foo.x = 1;
foo.y = 2;

auto bar = new Foo(foo);

assert(foo !is bar);
assert(bar.x == 1);
assert(bar.y == 2);
}

There's a ton of nonsensical compile errors if I try to use
"[__traits(allMembers, Foo)]" inside the mixin call itself btw.

Okay, this really is just a silly example, but I like having fun with
string mixins. :-)


Re: Constructors (starstruck noob from C++)

2011-01-20 Thread Andrej Mitrovic
Ah, damnit, Andrei beat me to the punch!

Well, at least his methods make much more sense than my little hacks.


Re: Constructors (starstruck noob from C++)

2011-01-20 Thread Andrej Mitrovic
On 1/21/11, Andrei Alexandrescu  wrote:
> I think copyMembers belongs to the standard library. I wanted to define
> a family of functions like it but never got around to it.
>

It's a shame we can't use .dup. It would look really nice in code.


Re: Constructors (starstruck noob from C++)

2011-01-20 Thread Robert Jacques
On Thu, 20 Jan 2011 22:02:42 -0500, Andrei Alexandrescu  
 wrote:



On 1/20/11 7:18 PM, Luke J. West wrote:

Hi to all from a total noob.

first of all, I'd like to say how impressed I am with D. In fact, I keep
pinching myself. Have I *really* found a language worth leaving C++ for
after two decades? It's beginning to look that way. Obviously I'm
devouring the 2.0 documentation right now, but have not yet found out
how to create a new instance of an existing class object. What I mean
is, given...

auto a = new A;

how do I, in c++ speak, do the D for...

A  b(a); // or if you prefer...
A* b = new A(a);

I'm sure this must be trivial.

Many many thanks,

Luke


Hopefully this won't mark a demise of your newfound interest :o). If A  
were a struct, auto b = new A(*a) would do. For classes, D does not  
provide automatic copy constructors; you need to define and follow a  
sort of cloning protocol.


That being said, it's not difficult to define a generic function that  
copies fields over from one class object to another. Here's a start:


import std.stdio;

void copyMembers(A)(A src, A tgt) if (is(A == class)) {
 foreach (e; __traits(allMembers, A)) {
 static if (!is(typeof(__traits(getMember, src, e)) == function)
&& e != "Monitor")
 {
 __traits(getMember, tgt, e) = __traits(getMember, src, e);
 }
 }
}

class A {
 int x = 42;
 string y = "hello";
 final void fun1() {}
 void fun2() {}
 static void fun3(){}
}

void main() {
 auto a = new A;
 a.x = 43;
 auto b = new A;
 copyMembers(a, b);
 assert(b.x == 43);
}

I think copyMembers belongs to the standard library. I wanted to define  
a family of functions like it but never got around to it.



Andrei


First, why not use tupleof? b.tupleof = a.tupleof; works perfectly fine,  
simpler and ahem, actually works. __traits(getMember, ...) has to obey  
scoping rules, so using it with a class that defines private variables  
results in a message like class hello.A member x is not accessible.  
Furthermore, you need to filter allMembers by a lot more than just  
function and "Monitor" as it also includes enum constants, etc. Having  
tried using it for serialization, I know it's non-trivial to use  
correctly, if you only want the actual data fields.


i.e.

void copyMembers(A)(A src, A tgt) if (is(A == class)) { tgt.tupleof =  
src.tupleof; }


Re: Constructors (starstruck noob from C++)

2011-01-21 Thread Jacob Carlborg

On 2011-01-21 04:02, Andrei Alexandrescu wrote:

On 1/20/11 7:18 PM, Luke J. West wrote:

Hi to all from a total noob.

first of all, I'd like to say how impressed I am with D. In fact, I keep
pinching myself. Have I *really* found a language worth leaving C++ for
after two decades? It's beginning to look that way. Obviously I'm
devouring the 2.0 documentation right now, but have not yet found out
how to create a new instance of an existing class object. What I mean
is, given...

auto a = new A;

how do I, in c++ speak, do the D for...

A b(a); // or if you prefer...
A* b = new A(a);

I'm sure this must be trivial.

Many many thanks,

Luke


Hopefully this won't mark a demise of your newfound interest :o). If A
were a struct, auto b = new A(*a) would do. For classes, D does not
provide automatic copy constructors; you need to define and follow a
sort of cloning protocol.

That being said, it's not difficult to define a generic function that
copies fields over from one class object to another. Here's a start:

import std.stdio;

void copyMembers(A)(A src, A tgt) if (is(A == class)) {
foreach (e; __traits(allMembers, A)) {
static if (!is(typeof(__traits(getMember, src, e)) == function)
&& e != "Monitor")
{
__traits(getMember, tgt, e) = __traits(getMember, src, e);
}
}
}

class A {
int x = 42;
string y = "hello";
final void fun1() {}
void fun2() {}
static void fun3(){}
}

void main() {
auto a = new A;
a.x = 43;
auto b = new A;
copyMembers(a, b);
assert(b.x == 43);
}

I think copyMembers belongs to the standard library. I wanted to define
a family of functions like it but never got around to it.


Andrei


Or you can use a serialization library, serialize the struct, then 
deserialize it and you have a deep copy. For example using Orange: 
http://dsource.org/projects/orange/ . Although it would not be very 
efficient to use XML as an intermediate format.


--
/Jacob Carlborg


Re: Constructors (starstruck noob from C++)

2011-01-21 Thread Andrei Alexandrescu

On 1/20/11 11:28 PM, Robert Jacques wrote:

On Thu, 20 Jan 2011 22:02:42 -0500, Andrei Alexandrescu
 wrote:
First, why not use tupleof? b.tupleof = a.tupleof; works perfectly fine,
simpler and ahem, actually works. __traits(getMember, ...) has to obey
scoping rules, so using it with a class that defines private variables
results in a message like class hello.A member x is not accessible.
Furthermore, you need to filter allMembers by a lot more than just
function and "Monitor" as it also includes enum constants, etc. Having
tried using it for serialization, I know it's non-trivial to use
correctly, if you only want the actual data fields.

i.e.

void copyMembers(A)(A src, A tgt) if (is(A == class)) { tgt.tupleof =
src.tupleof; }


Indeed, that's the canonical solution. Thanks for the reminder.

Andrei


Re: Constructors (starstruck noob from C++)

2011-01-21 Thread spir

On 01/21/2011 04:48 AM, Andrej Mitrovic wrote:

On 1/21/11, Andrei Alexandrescu  wrote:

I think copyMembers belongs to the standard library. I wanted to define
a family of functions like it but never got around to it.



It's a shame we can't use .dup. It would look really nice in code.


+++

Denis
_
vita es estrany
spir.wikidot.com



Re: Constructors (starstruck noob from C++)

2011-01-21 Thread bearophile
spir:

> > It's a shame we can't use .dup. It would look really nice in code.
> 
> +++

Copying classes is not a so common need in D. As an example, I need a byPair() 
method for AAs more than dup for classes :-)

Bye,
bearophile


Re: Constructors (starstruck noob from C++)

2011-01-21 Thread spir

On 01/21/2011 06:28 AM, Robert Jacques wrote:

void copyMembers(A)(A src, A tgt) if (is(A == class)) { tgt.tupleof =
src.tupleof; }


What about this feature in Object under name "copy" or "dup"? Sure, it's 
not to be used evereday; but it's typcally the kind of routine that, 
when needed, we're very happy to find. And as shown by this thread the 
solution is clearly non-obvious (lol).


By the way, why "dup" in D, instead of most common "copy" or "clone"? Is 
it also a legacy name? (Don't tell me we got this one from stack-based 
languages like Forth ;-) Anyway the semantics are totally different (*)).


Denis

(*) for very curious people: concatenative languages: 
http://concatenative.org/wiki/view/Concatenative%20language

_
vita es estrany
spir.wikidot.com



Re: Constructors (starstruck noob from C++)

2011-01-21 Thread spir

On 01/21/2011 01:29 PM, bearophile wrote:
> spir:
>
>>> It's a shame we can't use .dup. It would look really nice in code.
>>
>> +++
>
> Copying classes is not a so common need in D. As an example, I need a 
byPair() method for AAs more than dup for classes :-)

>
> Bye,
> bearophile

Sure, but when you need it, you very pleased to find it. And as already 
noted, this thread shows how non-obviously it is to define.


By the way, I like & support you request for byPair; but then, let's 
have it for all arrays (keys beeing indices). (D Lua-isation ;-)


Denis
_
vita es estrany
spir.wikidot.com




Re: Constructors (starstruck noob from C++)

2011-01-21 Thread Andrej Mitrovic
Theorizing: Would it be a bad idea if .dup for classes did the same
thing as normal assignment did for structs with postblit constructors?

Essentially I was thinking that code like this would do the trick:

import std.stdio;

class Widget
{
int integral;  // field-by-field assignment
int[] array;   // this needs a postblit
this(uint length)
{
array = new int[length];
}

this(this)
{
array = array.dup;
}
}

void main()
{
auto w1 = new Widget(10);
auto w2 = w1.dup;
assert(w1.array !is w2.array);
}

I like uniformity in a language, it's much easier to get the rules
right this way. But I'm speculating whether this would even work
right..


Re: Constructors (starstruck noob from C++)

2011-01-21 Thread Robert Jacques

On Fri, 21 Jan 2011 08:16:24 -0500, spir  wrote:


On 01/21/2011 06:28 AM, Robert Jacques wrote:

void copyMembers(A)(A src, A tgt) if (is(A == class)) { tgt.tupleof =
src.tupleof; }


What about this feature in Object under name "copy" or "dup"? Sure, it's  
not to be used evereday; but it's typcally the kind of routine that,  
when needed, we're very happy to find. And as shown by this thread the  
solution is clearly non-obvious (lol).


By the way, why "dup" in D, instead of most common "copy" or "clone"? Is  
it also a legacy name? (Don't tell me we got this one from stack-based  
languages like Forth ;-) Anyway the semantics are totally different (*)).


Denis

(*) for very curious people: concatenative languages:  
http://concatenative.org/wiki/view/Concatenative%20language

_
vita es estrany
spir.wikidot.com



".dup" comes from arrays, which already have a ".dup" property which  
copies/clones them.


Re: Constructors (starstruck noob from C++)

2011-01-21 Thread spir

On 01/21/2011 05:27 PM, Robert Jacques wrote:

On Fri, 21 Jan 2011 08:16:24 -0500, spir  wrote:


On 01/21/2011 06:28 AM, Robert Jacques wrote:

void copyMembers(A)(A src, A tgt) if (is(A == class)) { tgt.tupleof =
src.tupleof; }


What about this feature in Object under name "copy" or "dup"? Sure,
it's not to be used evereday; but it's typcally the kind of routine
that, when needed, we're very happy to find. And as shown by this
thread the solution is clearly non-obvious (lol).

By the way, why "dup" in D, instead of most common "copy" or "clone"?
Is it also a legacy name? (Don't tell me we got this one from
stack-based languages like Forth ;-) Anyway the semantics are totally
different (*)).

Denis

(*) for very curious people: concatenative languages:
http://concatenative.org/wiki/view/Concatenative%20language
_
vita es estrany
spir.wikidot.com



".dup" comes from arrays, which already have a ".dup" property which
copies/clones them.


Yes. I was in fact (unclearly) wondering where .dup for arrays comes 
from. I mean, the obvious term --and short enough to not even look for 
an abbreviation possibly making it obscure-- is "copy", isn't it? (*)


Denis
_
vita es estrany
spir.wikidot.com

(*)
Or do people really speak like:
<< Would you please make a duplicate of the guest list? >>
in the US?


Re: Constructors (starstruck noob from C++)

2011-01-21 Thread Steven Schveighoffer

On Fri, 21 Jan 2011 14:54:53 -0500, spir  wrote:


On 01/21/2011 05:27 PM, Robert Jacques wrote:

On Fri, 21 Jan 2011 08:16:24 -0500, spir  wrote:


On 01/21/2011 06:28 AM, Robert Jacques wrote:

void copyMembers(A)(A src, A tgt) if (is(A == class)) { tgt.tupleof =
src.tupleof; }


What about this feature in Object under name "copy" or "dup"? Sure,
it's not to be used evereday; but it's typcally the kind of routine
that, when needed, we're very happy to find. And as shown by this
thread the solution is clearly non-obvious (lol).

By the way, why "dup" in D, instead of most common "copy" or "clone"?
Is it also a legacy name? (Don't tell me we got this one from
stack-based languages like Forth ;-) Anyway the semantics are totally
different (*)).

Denis

(*) for very curious people: concatenative languages:
http://concatenative.org/wiki/view/Concatenative%20language
_
vita es estrany
spir.wikidot.com



".dup" comes from arrays, which already have a ".dup" property which
copies/clones them.


Yes. I was in fact (unclearly) wondering where .dup for arrays comes  
from. I mean, the obvious term --and short enough to not even look for  
an abbreviation possibly making it obscure-- is "copy", isn't it? (*)


Not sure where it comes from, but dup also is a system call in Linux:

 dup, dup2, dup3 - duplicate a file descriptor

The terminology isn't really important as long as its relevant.  Perhaps  
dup was chosen to avoid confusion with STL's std::copy (which copies data  
into an already-allocated area)?  The difference is subtle.


In any case, dup is clearly here to stay as the way to copy arrays, I'd  
agree that it makes sense to re-use it as the way to duplicate objects as  
well.  I use it in dcollections.



(*)
Or do people really speak like:
<< Would you please make a duplicate of the guest list? >>
in the US?


They might, it doesn't sound that odd to me, though copy sounds more  
common.


-Steve


Re: Constructors (starstruck noob from C++)

2011-01-21 Thread Jonathan M Davis
On Friday, January 21, 2011 12:10:26 Steven Schveighoffer wrote:
> On Fri, 21 Jan 2011 14:54:53 -0500, spir  wrote:
> > (*)
> > Or do people really speak like:
> > << Would you please make a duplicate of the guest list? >>
> > in the US?
> 
> They might, it doesn't sound that odd to me, though copy sounds more
> common.

I'd find that a bit odd, personally. It's perfectly understandable but a bit 
odd. 
I think that part of the problem though is that you're talking about a 
document, 
and you don't typically talk about duplicating documents.

Actually, if you want to get really technical, I think that duplicate is most 
typically used when talking about someone doing the same thing as someone else 
rather than taking the original and copying it. So, instead of taking the guest 
list and copying it, if you're duplicating it, then that often would imply that 
you're recreating it yourself rather than copying the one that exists - though, 
it is a bit odd to talk that way about a document. More typically, you'd talk 
about a technological device or whatnot. It's like how you'd say that you 
duplicated effort, but you'd never say that you copied effort.

That's not to say that the use of either copy or duplicate is entirely 
consistent however. Language is a rather maleable thing, and common usage has a 
large effect, regardless of what is technically correct based on the 
definitions 
of the words.

- Jonathan M Davis