Auto constructor [Was: Archetype language]

Daniel Gibson metalcaedes at gmail.com
Mon Mar 21 01:46:24 PDT 2011


Am 21.03.2011 09:17, schrieb Don:
> Daniel Gibson wrote:
>> 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
> 
> 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.
> 

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));
}


More information about the Digitalmars-d mailing list