#827 Constructor problems

DanielFath Thu 19 Nov 2009

I've been scouring through documentation, trying to determine how to extend Err. I've found the right way by looking at fwt (gfx) but it's a bit counter-intuitive.

const class ImproperBitFormatErr : Err
{
  new make(Str? msg := null, Err? cause := null) : super(msg,cause) //valid
  {
    //Err.super.make(msg,cause)  Invalid! 
  }

}

Is there any way to make constructor in a way that is a bit more Java like (and invalid)?

Also except through reflection, is there any way to change const fields? I heard something about with-blocks but I'm not sure I completely follow (I know it was there before but has anything been changed)?

helium Thu 19 Nov 2009

Being unlike Java but like C++ and C# is counter-intuitive?

const fields are constant. If you want them to be mutable don't mark them as const in the first place. You can only set them during construction (that includes with-blocks).

class Foo
{
   const Str text;
}

...

// with block
foo := Foo 
{
   text = "some text"
}

brian Thu 19 Nov 2009

The docs for constructor chaining are in the Methods chapter.

The description of how to use an it-block with your ctor to set const fields is described in the Fields chapter.

DanielFath Thu 19 Nov 2009

Being unlike Java but like C++ and C# is counter intuitive?

I didn't meant to put Java on any pedestal. I meant as in Java-like.

The problem of having : super is that you have one syntax for accessing methods and fields and another for accessing constructors (which are methods). It just seems redundant and inelegant so I thought there must be an alternate way to get to constructors like ImproperBitFormatErr->super->make(msg,cause) or ((Err)ImproperBitFormat).super(msg,cause) without using constructor chaining.

const fields are constant. If you want them to be mutable don't mark them as const in the first place.

I have no desire to change const fields but I do want to know under what circumstances they could become volatile.

tactics Thu 19 Nov 2009

The expression Err.super.make(msg, cause) doesn't make a ton of sense, because Err has no slot named super.

Constructors are more than just methods. They are tied in tightly with the type system and are generally kind of weird. Calling a constructor results in the creation of a new object, but that isn't your intent here. Chaining a constructor and calling a constructor are different, yes? It isn't inelegant that they would have different syntaxes.

DanielFath Thu 19 Nov 2009

I know Err.super.make doesn't make a lot of sense, but I typed that only because super.make and super() didn't pass and I was in a rush.

Yeah I found an article about brian deciding about this. I still think Java's handling of super is far more clearer to C++/C#, because it treats Ctor like regular slot from super that by convention is written in the first.

I guess they wanted to leave out writing super(..) so they get cleaner API.

helium Thu 19 Nov 2009

I expect a call of an constructor to create a new object like it does everywhere. If calling a constructor behaved differently inside another constructor I would be seriously surprised. So if anything a call to super() should create a new instance of the base type.

class Foo
{ }

class Bar : Foo
{
   new make()
   {
      aFooInstance := super()    // I'd expect this to behave like ...
      otherFooInstance := Foo()  // ...this
   }
}

brian Thu 19 Nov 2009

I think that old post Daniel dug up sums out why we went with C++/C# syntax instead of Java. Because Fan treats ctors/factories at the call site with the same syntax, it would have been confusing to call them in a method body like a normal method. Using C++ syntax makes it clear exactly what is happening. At this late stage, I don't think that bit of syntax is up for debate. I think what we have works well.

Login or Signup to reply.