Re: Constructors?

Byron Foster <[email protected]> Sun, 10 Oct 2004 05:47:39 -0700
Newsgroups gmane.comp.lang.nice.general
Message-ID <[email protected]>
Daniel Bonniot wrote:
> OK, thanks for the research. So C# has an additional restriction that 
> ensures that field initialization does not fail, but that does not solve 
> the general problem. I adapted the example to C#, and it fails in the 
> same way:
> 
 > ... C# code removed ...
> 
> I tried it with mono, and that gives:
> 
> Instance created: Parent
> 
> Unhandled Exception: System.NullReferenceException: Object reference not 
> set to an instance of an object
> in <0x00019> Child:ToString ()
> in <0x0004f> System.String:Concat (object,object)
> in <0x0001a> Parent:.ctor ()
> in <0x0000a> Child:.ctor (string)
> in <0x0003f> Child:Main (string[])
> 
> 
> So C# has made some progress, but it still has holes. 

I tried this scenario also with Python and Ruby which both suffer from 
the same problem.

> The equivalent program in Nice works without problem:
 >
> ... Nice code removed ...
> 
> This illustrates why code that makes use of 'this' cannot be allowed to 
> run until all the constructors have executed (which guarantees all 
> fields are set as wanted). Hence the distinction between two phases: 
> creation and initialization.
> 
> 
>>> I see two things that could be improved to make Nice's approach
>>> easier to use:
>>>
>>> 1) In the special case of a class without any fields, the call to 
>>> 'this()' should not be necessary. That would solve the problem you 
>>> initially reported.
>>
>> Or classes without any non-initialized fields.
> 
> Right.

Perfect.

>>> 2) Instead of requiring a call to this(x: valueX, y: valueY), we
>>> could also allow constructor bodies that definitely assign a value to
>>> this.x and this.y, while still not allowing using the 'this' value.
>>> This would provide a more familiare syntax, with exactly the same
>>> safety properties.
>>
>> I'm not sure I follow, so the following would be legal:
>>
>> class A
>> {
>>   int x;
>>   new A()  // I know this syntax does not exist, YET! :)
>>   {
>>     x = 5;
>>   }
>> }
> 
> Yes.

I like that, and this will certainly be more comfortable to people 
familiar with other languages that allow 'this' access in constructors. 
  However, the compiler will need to be smart though, for example:

class A {int x;}
new A(int y) {if (y != 0) x = 1;}

Of course the compiler would have to consider x uninitialized, but this 
seems consistent with Nice's approach where the compiler works hard for you!

I guess that the following would be illegal:

new A() {x = 1; println (x);}

Just as this is illegal:

new A() {this(x:1); println (x);}

It seems that after the autoconstructor is called, that 'this' is safe 
to use.. but maybe this gets messy.

One aspect I like about this approach is that constructors are 
inherited.  I've seen allot of sub classes that simply override a few 
methods, but require all the constructors of the base class to be re 
wrapped, in both Java and C++.

Something peculiar also.  If I have the following:

class A {int x}
new A(int x) {...do something...; this(x:x);}

your get the following error:
Ambiguity for symbol this. Possibilities are :
foo.C <init>(int count)
foo.C <init>(int count)

Which is directly related to my original issue.  How do I override an 
existing autoconstructor?





-------------------------------------------------------
This SF.net email is sponsored by: IT Product Guide on ITManagersJournal
Use IT products in your business? Tell us what you think of them. Give us
Your Opinions, Get Free ThinkGeek Gift Certificates! Click to find out more
http://productguide.itmanagersjournal.com/guidepromo.tmpl