Constructors (starstruck noob from C++)
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++)
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++)
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++)
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++)
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++)
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++)
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++)
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++)
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++)
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++)
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++)
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++)
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++)
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++)
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++)
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++)
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++)
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++)
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