June 10, 2004
In article <caan2q$22ap$1@digitaldaemon.com>, Matthew says...
>
>It should have the same requirement as in C++, that one cannot leave the ctor body (once an x has been caught) via a return statement, but should require the coder to write a throw expression (even if it's only "throw;")

I agree completely.

>One thing I find important a lot in C++ is the ability to be able to write and call static methods in the initialiser list. I'd like to be able to do the same prior to calling super(), and I imagine that I probably can at the moment in D. Anyone know?

I would be shocked if this weren't allowed.  Some pertinent bits from the spec just to back up my guess:

"All member initializations must be determinable by the compiler at compile time, hence there is no order-of-evaluation dependency for member initializations, and it is not possible to read a value that has not been initialized."

"static this() is called by the startup code before main() is called. . .  A
current weakness of the static constructors is that the order in which they are
called is not defined."

So it looks like dependent singleton types may still have some issues but otherwise all should work as expected.


Sean


June 11, 2004
"Sean Kelly" <sean@f4.ca> wrote in message news:caaekv$1l7h$1@digitaldaemon.com...
> In article <caadke$1jmk$1@digitaldaemon.com>, Marcin says...

> Certainly.  D is a tad different from C++ in that it doesn't require superclasses to be initialized first.  This is fine so long as the user
isn't
> foolish enough to try your example above :)  And I should point out this
quote
> from the D docs:
>
> "If no call to constructors via this or super appear in a constructor, and
the
> base class has a constructor, a call to super() is inserted at the
beginning of
> the constructor."
>
> So assuming the user isn't deliberately foolish then everything will work
out
> fine.  There's really no reason to explicitly call a superclass
constructor with
> no parameters unless you want to catch any exceptions it throws.
>
>
> Sean

The example was contrived on purpose so that you can see my point. A lot of
times you write code and unknowingly it pretty much does what I just showed
you, except now you will be chasing an extremely obscure bug. It's like
programming in C, you always want your programs leak and bug free and you
never intend to write such programs, but they still happen more often that
you'd like to admit to. Having the language help you out is priceless. D
doesn't do that and therefore it invites a whole host of bugs.
Secondly, why would you not want base class portions initialized first?
Would you not start constructing any building with the foundations? All
other mature languages guarantee base parts are set up first because it just
makes sense from a design standpoint.


June 11, 2004
In article <ca8hdu$1jnl$1@digitaldaemon.com>, Marcin says...
>the call to super can be placed anywhere inside the constructor. That means you get to play around with the derived object before the base parts are set up, which can cause hell if contained member objects try to use the base portions. Why isn't this dealt with like in Java, where the call to super has to be the first call in the constructor, otherwise the default base ctor is called.

Probably because in Java, you end up with problems like not being able to do this (translated to D for the sake of the group):

class NamedObject
{
private char[] name;
this(char[] name)
{
this.name = name;
}
}

class NonNullNamedObject : NamedObject
{
this(char[] name)
{
if (name is null)
{
//...throw some exception...
}
super(name);
}
}

The workaround in this case is obviously to call super(name) first and then to check the value, but wouldn't it make more sense to check the value first before creating a useless object?

I figure statements before the super() should be permitted, but perhaps D could just prohibit non-static methods being called.

TX


June 11, 2004
In article <cabl7p$cm3$1@digitaldaemon.com>, Trejkaz Xaoza says...
>
>In article <ca8hdu$1jnl$1@digitaldaemon.com>, Marcin says...
>>the call to super can be placed anywhere inside the constructor. That means you get to play around with the derived object before the base parts are set up, which can cause hell if contained member objects try to use the base portions. Why isn't this dealt with like in Java, where the call to super has to be the first call in the constructor, otherwise the default base ctor is called.
>
>Probably because in Java, you end up with problems like not being able to do this (translated to D for the sake of the group):
>
>class NamedObject
>{
>private char[] name;
>this(char[] name)
>{
>this.name = name;
>}
>}
>
>class NonNullNamedObject : NamedObject
>{
>this(char[] name)
>{
>if (name is null)
>{
>//...throw some exception...
>}
>super(name);
>}
>}
>
>The workaround in this case is obviously to call super(name) first and then to check the value, but wouldn't it make more sense to check the value first before creating a useless object?

I would solve your example by having preconditions for super.this(), but I think that's a flaw in the example rather than the idea itself.  Suppose a derived class wants to choose which base class constructor to call depending on calculated data?

class Derived : Super
{
...this( int x )
...{
.......switch( calculateSomethingWith( x ) )
.......{
.......case 1: super(); break;
.......case 2: super( someValue ); break;
.......}
...}
}

In this case the superclass constructor is neither the first call in the derived constructor nor even the first function/method called in the derived constructor, yet the approach seems perfectly legitimate provided the programmer is careful.


Sean


June 12, 2004
In article <cacsum$23rb$1@digitaldaemon.com>, Sean Kelly says...
>I would solve
your example by having preconditions for super.this(), but I think
>that's a
flaw in the example rather than the idea itself.

The entire _point_ of
checking the value was to check the precondition.

Or is there another way?
Excluding the in and out blocks, of course, as those are compiled out for
release builds, and it's hardly acceptable for your program to work in all
cases except the release build.

TX



June 12, 2004
In article <cae121$mon$1@digitaldaemon.com>, Trejkaz Xaoza says...
>
>In article <cacsum$23rb$1@digitaldaemon.com>, Sean Kelly says...
>>I would solve
>your example by having preconditions for super.this(), but I think
>>that's a
>flaw in the example rather than the idea itself.
> 
>The entire _point_ of
>checking the value was to check the precondition.
> 
>Or is there another way?
>Excluding the in and out blocks, of course, as those are compiled out for
>release builds, and it's hardly acceptable for your program to work in all
>cases except the release build.

I had meant the in/out blocks.  Verifying pre and postconditions is what DBC is for, and in many cases debug testing is sufficient to insure acceptable program correctness.  Critical software, however, may actually ship with the in/out blocks still in place, as program failure is not an option.  If you're worried about performance then just make sure that the code in in/out is fairly efficient, or put in Internal and Production version blocks.

Sean


June 13, 2004
Trejkaz Xaoza wrote:

> Probably because in Java, you end up with problems like not being able to do
> this (translated to D for the sake of the group):

Which is silly, because you can just do this, if the superclass takes at least one parameter:

class NonNullNamedObject : NamedObject {
	this(char[] name) {
		super(preconstruct(name));
	}
	char[] preconstruct(char[] name) {
		if(name is null) {
			// whatever
		}
		return name;
	}
}

Just having the compiler add an assert that a superconstructor got called exactly once (only in debug mode of course) sounds like enough to me.

Sam
June 14, 2004
Naturally.  That code works in D because it doesn't have the restrictions of Java.  Java would have complained about code like that since you're calling a method before the object is instantiated.  I guess you can use a static method to avoid that, but then again that example I gave wasn't the exact case which I have encountered anyway, more a simulation. :-)

But anyway... since I have a preference towards developing library code as opposed to application code, I like being over-careful with what gets passed in. Having my own code go through debug testing a thousand times doesn't help, if someone linking to my library passes in a bad value (this is also why I don't like to rely on the in/out blocks, since I can't guarantee the application which includes my code will actually compile them in!  I guess if the specification said in/out blocks were always put in, it would be a different issue.)

Anyway, D's going the right way about it.  'Trust the developer' seems to be its philosophy and allowing the superconstructor call anywhere is adhering to that.

TX

In article <cahg14$2p7c$1@digitaldaemon.com>, Sam McCall says...
>
>Trejkaz Xaoza wrote:
>
>> Probably because in Java, you end up with problems like not being able to do this (translated to D for the sake of the group):
>
>Which is silly, because you can just do this, if the superclass takes at least one parameter:
>
>class NonNullNamedObject : NamedObject {
>	this(char[] name) {
>		super(preconstruct(name));
>	}
>	char[] preconstruct(char[] name) {
>		if(name is null) {
>			// whatever
>		}
>		return name;
>	}
>}
>
>Just having the compiler add an assert that a superconstructor got called exactly once (only in debug mode of course) sounds like enough to me.
>
>Sam


June 14, 2004
Trejkaz Xaoza wrote:

> Naturally.  That code works in D because it doesn't have the restrictions of
> Java.  Java would have complained about code like that since you're calling a
> method before the object is instantiated.  I guess you can use a static method
> to avoid that, but then again that example I gave wasn't the exact case which I
> have encountered anyway, more a simulation. :-)
Oops. I thought that code _would_ work with java, having used something like it before as a hack, but it was static before, which is a different kettle of fish.
Of course it works in D, in D you can put the code before the super() call ;-)

> Having my own code go through debug testing a thousand times doesn't help, if
> someone linking to my library passes in a bad value (this is also why I don't
> like to rely on the in/out blocks, since I can't guarantee the application which
> includes my code will actually compile them in!  I guess if the specification
> said in/out blocks were always put in, it would be a different issue.)
> 
> Anyway, D's going the right way about it.  'Trust the developer' seems to be its
> philosophy and allowing the superconstructor call anywhere is adhering to that.
Agreed. Maybe you should trust the developer more too - if they use your library incorrectly, never did a debug build, and released their program complete with resultant bugs then they were a lost cause anyway ;)

Sam
1 2 3
Next ›   Last »