digitalmars.D - Auto constructor [Was: Archetype language]
- bearophile (33/33) Mar 20 2011 Among the things I've listed about Archetype there's one interesting thi...
- Adam D. Ruppe (2/2) Mar 20 2011 Have you tried doing this with a string mixin? It looks like
- bearophile (4/6) Mar 20 2011 It's probably trivial with a string mixin, but no thanks. I don't like t...
- Daniel Gibson (17/38) Mar 20 2011 You'd have to know the order in that the members are defined in the
- Don (7/66) Mar 21 2011 I agree. But unfortunately, the idea is a relatively complicated feature...
- Daniel Gibson (26/92) Mar 21 2011 Isn't it guaranteed that function arguments (and I guess it's the same f...
- KennyTM~ (18/84) Mar 21 2011 'int f(int x, int x) {}' is a syntax error. So should 'this(this.x,
- Daniel Gibson (2/9) Mar 21 2011 and probably this(this.x, x){}
- Don (7/15) Mar 21 2011 Exactly. That's why it's messier than it first appears.
- bearophile (4/6) Mar 21 2011 If this is true, then this is amazing :-) Considering that pure is proba...
- KennyTM~ (13/22) Mar 21 2011 Yes. This is handled by the AST transform (lowering) too.
- spir (21/52) Mar 21 2011 I definitely want some feature like that in D.
- Don (4/58) Mar 21 2011 It's not that it's complicated, it's that for structs, the ordering of
Among the things I've listed about Archetype there's one interesting thing. Class instances aren't PODs, but sometimes I prefer reference semantics and to populate fields in a plain way, expecially for simple classes. Time ago I and other people have suggested a syntax like (this also to avoid a class of bugs http://d.puremagic.com/issues/show_bug.cgi?id=3878 ): class Foo { string x; int y = 1; this(this.x, this.y) {} } void main() { Foo f3 = new Foo("hello", 10); } A simpler solution are classes with automatic constructors: class Foo { string x; int y = 1; } void main() { Foo f1 = new Foo(); // Good Foo f2 = new Foo("hello"); // Good Foo f3 = new Foo("hello", 10); // Good } What kind of problems are caused by this? :-) Currently that syntax is supported for structs created as values, but not for structs created by pointer: struct Foo { string x; int y = 1; } void main() { Foo* f1 = new Foo(); // OK Foo* f2 = new Foo("hello"); // Error: no constructor for Foo Foo* f3 = new Foo("hello", 10); // Error: no constructor for Foo } Bye, bearophile
Mar 20 2011
Have you tried doing this with a string mixin? It looks like it'd be trivial.
Mar 20 2011
Adam D. Ruppe:Have you tried doing this with a string mixin? It looks like it'd be trivial.It's probably trivial with a string mixin, but no thanks. I don't like them a lot. Bye, bearophile
Mar 20 2011
Am 21.03.2011 00:55, schrieb bearophile:Among the things I've listed about Archetype there's one interesting thing. Class instances aren't PODs, but sometimes I prefer reference semantics and to populate fields in a plain way, expecially for simple classes. Time ago I and other people have suggested a syntax like (this also to avoid a class of bugs http://d.puremagic.com/issues/show_bug.cgi?id=3878 ): class Foo { string x; int y = 1; this(this.x, this.y) {} } void main() { Foo f3 = new Foo("hello", 10); }Yeah, I still like that idea ;)A simpler solution are classes with automatic constructors: class Foo { string x; int y = 1; } void main() { Foo f1 = new Foo(); // Good Foo f2 = new Foo("hello"); // Good Foo f3 = new Foo("hello", 10); // Good } What kind of problems are caused by this? :-)You'd have to know the order in that the members are defined in the class (and you may not change the order). Just imagine class Foo { int bla; int baz; } new Foo(42, 3); // what is bla, what is baz? and then you decide "uh I'd prefer to have my class members ordered alphabetically" and *bamm* all you code silently breaks. having a this(this.bla, this.baz) {} would clearly document which argument in the constructor belongs to which class member and the class members ordering wouldn't matter. Cheers, - Daniel
Mar 20 2011
Daniel Gibson wrote:Am 21.03.2011 00:55, schrieb bearophile:I agree. But unfortunately, the idea is a relatively complicated feature with a lot of special cases. For example, this(this.bla, this.bla){} and what if the class contains a union and you set multiple members of it? The whole thing is actually quite messy. It's not _terrible_, but it's far from trivial, and it's more complicated than some far more powerful and useful language features.Among the things I've listed about Archetype there's one interesting thing. Class instances aren't PODs, but sometimes I prefer reference semantics and to populate fields in a plain way, expecially for simple classes. Time ago I and other people have suggested a syntax like (this also to avoid a class of bugs http://d.puremagic.com/issues/show_bug.cgi?id=3878 ): class Foo { string x; int y = 1; this(this.x, this.y) {} } void main() { Foo f3 = new Foo("hello", 10); }Yeah, I still like that idea ;)A simpler solution are classes with automatic constructors: class Foo { string x; int y = 1; } void main() { Foo f1 = new Foo(); // Good Foo f2 = new Foo("hello"); // Good Foo f3 = new Foo("hello", 10); // Good } What kind of problems are caused by this? :-)You'd have to know the order in that the members are defined in the class (and you may not change the order). Just imagine class Foo { int bla; int baz; } new Foo(42, 3); // what is bla, what is baz? and then you decide "uh I'd prefer to have my class members ordered alphabetically" and *bamm* all you code silently breaks. having a this(this.bla, this.baz) {} would clearly document which argument in the constructor belongs to which class member and the class members ordering wouldn't matter. Cheers, - Daniel
Mar 21 2011
Am 21.03.2011 09:17, schrieb Don:Daniel Gibson wrote:Isn't it guaranteed that function arguments (and I guess it's the same for constructors) are evaluated from left to right [1]? So if somebody is stupid enough to supply multiple arguments for a union the rightmost argument "wins" (he'd have the same problem with conventional constructors, only that the last assignment in the body would win). The same could be applied for this(this.bla, this.bla){} - the righ this.bla wins. But in this case a check that enforces that each class member may only occur *once* doesn't sound that hard to me - but I don't know anything about DMDs internals ;) Also I don't know if there are other special cases. Cheers, - Daniel [1] hmm I can't find anything about that right now, but I seem to remember it has been mentioned. Also it seems to be true in simple tests like: import std.stdio; int tf(int x) { writefln("testfun was called with %s", x); return x; } void myfun(int a, int b, int c) { writefln("a: %s b: %s c: %s", a, b, c); } void main() { myfun(tf(1), tf(3), tf(2)); }Am 21.03.2011 00:55, schrieb bearophile:I agree. But unfortunately, the idea is a relatively complicated feature with a lot of special cases. For example, this(this.bla, this.bla){} and what if the class contains a union and you set multiple members of it? The whole thing is actually quite messy. It's not _terrible_, but it's far from trivial, and it's more complicated than some far more powerful and useful language features.Among the things I've listed about Archetype there's one interesting thing. Class instances aren't PODs, but sometimes I prefer reference semantics and to populate fields in a plain way, expecially for simple classes. Time ago I and other people have suggested a syntax like (this also to avoid a class of bugs http://d.puremagic.com/issues/show_bug.cgi?id=3878 ): class Foo { string x; int y = 1; this(this.x, this.y) {} } void main() { Foo f3 = new Foo("hello", 10); }Yeah, I still like that idea ;)A simpler solution are classes with automatic constructors: class Foo { string x; int y = 1; } void main() { Foo f1 = new Foo(); // Good Foo f2 = new Foo("hello"); // Good Foo f3 = new Foo("hello", 10); // Good } What kind of problems are caused by this? :-)You'd have to know the order in that the members are defined in the class (and you may not change the order). Just imagine class Foo { int bla; int baz; } new Foo(42, 3); // what is bla, what is baz? and then you decide "uh I'd prefer to have my class members ordered alphabetically" and *bamm* all you code silently breaks. having a this(this.bla, this.baz) {} would clearly document which argument in the constructor belongs to which class member and the class members ordering wouldn't matter. Cheers, - Daniel
Mar 21 2011
On Mar 21, 11 16:17, Don wrote:Daniel Gibson wrote:'int f(int x, int x) {}' is a syntax error. So should 'this(this.x, this.x){}'.Am 21.03.2011 00:55, schrieb bearophile:I agree. But unfortunately, the idea is a relatively complicated feature with a lot of special cases. For example, this(this.bla, this.bla){}Among the things I've listed about Archetype there's one interesting thing. Class instances aren't PODs, but sometimes I prefer reference semantics and to populate fields in a plain way, expecially for simple classes. Time ago I and other people have suggested a syntax like (this also to avoid a class of bugs http://d.puremagic.com/issues/show_bug.cgi?id=3878 ): class Foo { string x; int y = 1; this(this.x, this.y) {} } void main() { Foo f3 = new Foo("hello", 10); }Yeah, I still like that idea ;)A simpler solution are classes with automatic constructors: class Foo { string x; int y = 1; } void main() { Foo f1 = new Foo(); // Good Foo f2 = new Foo("hello"); // Good Foo f3 = new Foo("hello", 10); // Good } What kind of problems are caused by this? :-)You'd have to know the order in that the members are defined in the class (and you may not change the order). Just imagine class Foo { int bla; int baz; } new Foo(42, 3); // what is bla, what is baz? and then you decide "uh I'd prefer to have my class members ordered alphabetically" and *bamm* all you code silently breaks. having a this(this.bla, this.baz) {} would clearly document which argument in the constructor belongs to which class member and the class members ordering wouldn't matter. Cheers, - Danieland what if the class contains a union and you set multiple members of it? The whole thing is actually quite messy. It's not _terrible_, but it's far from trivial, and it's more complicated than some far more powerful and useful language features.The syntax this(args, this.x.y.z, args, this.p.q.r = s, arg = t) { statements; } could just lower to this(args, typeof(this.x.y.z) z, args, typeof(this.p.q.r) r = s, arg = t) { this.x.y.z = z; this.p.q.r = r; statements; } Would this be too complicated? (Not that I like this idea... But I think it is not really that messy)
Mar 21 2011
Am 21.03.2011 11:09, schrieb KennyTM~:On Mar 21, 11 16:17, Don wrote:and probably this(this.x, x){}I agree. But unfortunately, the idea is a relatively complicated feature with a lot of special cases. For example, this(this.bla, this.bla){}'int f(int x, int x) {}' is a syntax error. So should 'this(this.x, this.x){}'.
Mar 21 2011
Daniel Gibson wrote:Am 21.03.2011 11:09, schrieb KennyTM~:Exactly. That's why it's messier than it first appears. My point is -- people tend to think things like this are trivial features because they are not very powerful; and conversely, they think that powerful features must be complicated. But that's really misleading. 'pure', for example, is roughly the same level of implementation complexity as this feature.On Mar 21, 11 16:17, Don wrote:and probably this(this.x, x){}I agree. But unfortunately, the idea is a relatively complicated feature with a lot of special cases. For example, this(this.bla, this.bla){}'int f(int x, int x) {}' is a syntax error. So should 'this(this.x, this.x){}'.
Mar 21 2011
Don:'pure', for example, is roughly the same level of implementation complexity as this feature.If this is true, then this is amazing :-) Considering that pure is probably about 60-70% implemented in D (no way to perform conditional purity, no good management of special cases, your last patch for lazy arguments, etc). Bye, bearophile
Mar 21 2011
On Mar 21, 11 18:26, Daniel Gibson wrote:Am 21.03.2011 11:09, schrieb KennyTM~:Yes. This is handled by the AST transform (lowering) too. this(this.x, int x) { statements; } becomes this(typeof(this.x) x, int x) { this.x = x; statements; } which will complain Error: constructor x.Foo.this parameter this.x is already defined as expected.On Mar 21, 11 16:17, Don wrote:and probably this(this.x, x){}I agree. But unfortunately, the idea is a relatively complicated feature with a lot of special cases. For example, this(this.bla, this.bla){}'int f(int x, int x) {}' is a syntax error. So should 'this(this.x, this.x){}'.
Mar 21 2011
On 03/21/2011 12:55 AM, bearophile wrote:Among the things I've listed about Archetype there's one interesting thing. Class instances aren't PODs, but sometimes I prefer reference semantics and to populate fields in a plain way, expecially for simple classes. Time ago I and other people have suggested a syntax like (this also to avoid a class of bugs http://d.puremagic.com/issues/show_bug.cgi?id=3878 ): class Foo { string x; int y = 1; this(this.x, this.y) {} } void main() { Foo f3 = new Foo("hello", 10); } A simpler solution are classes with automatic constructors: class Foo { string x; int y = 1; } void main() { Foo f1 = new Foo(); // Good Foo f2 = new Foo("hello"); // Good Foo f3 = new Foo("hello", 10); // Good } What kind of problems are caused by this? :-) Currently that syntax is supported for structs created as values, but not for structs created by pointer: struct Foo { string x; int y = 1; } void main() { Foo* f1 = new Foo(); // OK Foo* f2 = new Foo("hello"); // Error: no constructor for Foo Foo* f3 = new Foo("hello", 10); // Error: no constructor for Foo }I definitely want some feature like that in D. Have no idea why a default seems complicated for classes while structs have it. On the other hand, the syntax using "this.p" constructor parameter names is more general since it allows custom constructors: class Point { float x,y; float dist; this(this.x, this.y) { this.dist = square(x*x + y*y); } } Ideally, I would like this feature without "this." parameters, but it requires named arguments...: auto p = new Point(x=1, y=2); --> auto assign to members by name, then perform additional constructor tasks. Denis -- _________________ vita es estrany spir.wikidot.com
Mar 21 2011
spir wrote:On 03/21/2011 12:55 AM, bearophile wrote:It's not that it's complicated, it's that for structs, the ordering of their members is part of the public interface. For classes, the members are not public.Among the things I've listed about Archetype there's one interesting thing. Class instances aren't PODs, but sometimes I prefer reference semantics and to populate fields in a plain way, expecially for simple classes. Time ago I and other people have suggested a syntax like (this also to avoid a class of bugs http://d.puremagic.com/issues/show_bug.cgi?id=3878 ): class Foo { string x; int y = 1; this(this.x, this.y) {} } void main() { Foo f3 = new Foo("hello", 10); } A simpler solution are classes with automatic constructors: class Foo { string x; int y = 1; } void main() { Foo f1 = new Foo(); // Good Foo f2 = new Foo("hello"); // Good Foo f3 = new Foo("hello", 10); // Good } What kind of problems are caused by this? :-) Currently that syntax is supported for structs created as values, but not for structs created by pointer: struct Foo { string x; int y = 1; } void main() { Foo* f1 = new Foo(); // OK Foo* f2 = new Foo("hello"); // Error: no constructor for Foo Foo* f3 = new Foo("hello", 10); // Error: no constructor for Foo }I definitely want some feature like that in D. Have no idea why a default seems complicated for classes while structs have it.
Mar 21 2011