#1812 Any shorthand for filling in my const class?

dobesv Tue 6 Mar 2012

Consider:

const class Point
{
  new make(Int x, Int y) { this.x = x; this.y = y }
  const Int x
  const Int y
}

Don't the assignments to copy the parameters to the object seem a bit redundant?

In Scala they have a syntax like this to get the same effect:

// fields and construtor already defined in one go ... 
const class Point(Int x, Int y)

Anyway, not sure if there's any plans to look into this a bit more but I was really pleased (in Scala) not to have to write the variable name 4 times and the type twice for each simple class I create. It would be nice if Fantom had a shortcut for this too.

brian Tue 6 Mar 2012

I agree and there is been a ton of discussion on the topic. But no real obvious proposal has emerged yet.

DanielFath Tue 6 Mar 2012

I think this might be a territory of a "magic" facet. Either that or a very peculiar DSL.

Ideally I'd want:

@Auto
const class Point
{
   const Int x
   const Int y
}

that rolls into:

const class Point
{
  new make(Int x, Int y) { this.x = x; this.y = y }
  const Int x
  const Int y
}

Either that or:

Auto <|const class Point(Int x, Int y)|>

Optionally @Auto facet would create a |This| constructor and reflected equals and hash if you define it e.g. @Auto(["with-ctor","hash", "eq"]).

Scala's way is nifty but I'm already dizzy from all the ways you can do a single thing in Fantom, without adding unneeded complexity. What I would like to "borrow" from Scala is to be able to make commands in scripts without a declaring class. I think it'd be best to aim at go for the (iirc) Python maxim "always do one thing same way". It helps a lot with readability.

dobesv Wed 7 Mar 2012

One option, "implicit constructor": Fantom could generate a constructor for the const class that initialized all the const fields in order, if no make constructor is defined.

const class Point { const Int x; const Int y } // ctor defined implicitly

Could be that you need to have an annotation to enable this, like:

@Simple const class Point { const Int x; const Int y } // ctor defined implicitly

Perhaps add a keyword to constructor parameters indicating that the same-name field should automatically be set:

const class Point 
{
  new make(set Int x, set Int y) {} // set keyword triggers assignment
  const Int x
  const Int y
}

Or a shorter version that eliminates the need to retype the field types:

const class Point 
{
  new make(&x,&y) {} // & syntax infers type, triggers assignment
  const Int x
  const Int y
}

I think the first one, with the implicit constructor for const classes, is probably the best choice. Some people might scratch their head the first time they encounter it (where's the constructor?) but I think they could only reach one conclusion about it, even without reading the docs. I think probably most of the const classes I create have a constructor that could have been implicit using this method.

qualidafial Wed 7 Mar 2012

const class Point
{
  Int x
  Int y
  new make(|This| f) { f(this) }
}

dobesv Wed 7 Mar 2012

@qualidafial: Would that result in a case where calling Point(1,2) creates a Point object?

qualidafial Wed 7 Mar 2012

For my example the usage would be Point { x=1; y=2 }

dobesv Wed 7 Mar 2012

Ah that is kind of cool. You can do this with Fantom right now or does it require changes to the compiler?

brian Wed 7 Mar 2012

Ah that is kind of cool. You can do this with Fantom right now or does it require changes to the compiler?

Yes, in fact this is probably best convention to create a constructor that takes an it-block.

qualidafial Wed 7 Mar 2012

It is available right now but creating all those Functions just to build another objects carries performance implications. So if you expect to be making thousands of these per second, take some time to write the constructor both ways and measure the performance difference.

Login or Signup to reply.