This page is no longer maintained — Please continue to the home page at www.scala-lang.org

alternate constructors

6 replies
Russ P.
Joined: 2009-01-31,
User offline. Last seen 1 year 26 weeks ago.
I am implementing a class to represent aircraft velocity. The main constructor takes groundspeed, course angle, and altitude rate as parameters. These are the standard polar coordinates of velocity. I would like to also have a constructor that takes a vector of cartesian coordinates. I tried something like this:

class Velocity(val gspeed: Double=0, val course: Double=0,
    val altrate: Double=0) {

    def this(vec: Vector) {

        val gspeed = hypot(vec(0), vec(1))
        val course = atan2(vec(0), vec(1))
        val altrate = vec(2)

        this(gspeed, course, altrate)
        }

However, the compiler complained:

'this' expected but 'val' found.
[error]         val gspeed = hypot(vec(0), vec(1))
[error]         ^

I realize that I could simply omit the intermediate values and plug the necessary expressions directly into the constructor, but that does not seem as elegant or readable to me. Shouldn't I be able to do some preliminary calculations before I plug into the "this"? Thanks.

Russ P.

--
http://RussP.us
Sciss
Joined: 2008-12-17,
User offline. Last seen 28 weeks 5 days ago.
Re: alternate constructors

yes, i think you must call "this" first in alternative constructors, unfortunately, so you need to use expressions in the argument list

Am 11.02.2010 um 21:43 schrieb Russ Paielli:

> I am implementing a class to represent aircraft velocity. The main constructor takes groundspeed, course angle, and altitude rate as parameters. These are the standard polar coordinates of velocity. I would like to also have a constructor that takes a vector of cartesian coordinates. I tried something like this:
>
> class Velocity(val gspeed: Double=0, val course: Double=0,
> val altrate: Double=0) {
>
> def this(vec: Vector) {
>
> val gspeed = hypot(vec(0), vec(1))
> val course = atan2(vec(0), vec(1))
> val altrate = vec(2)
>
> this(gspeed, course, altrate)
> }
>
> However, the compiler complained:
>
> 'this' expected but 'val' found.
> [error] val gspeed = hypot(vec(0), vec(1))
> [error] ^
>
> I realize that I could simply omit the intermediate values and plug the necessary expressions directly into the constructor, but that does not seem as elegant or readable to me. Shouldn't I be able to do some preliminary calculations before I plug into the "this"? Thanks.
>
> Russ P.
>

Russ P.
Joined: 2009-01-31,
User offline. Last seen 1 year 26 weeks ago.
Re: alternate constructors
On Thu, Feb 11, 2010 at 1:48 PM, Sciss <contact@sciss.de> wrote:
yes, i think you must call "this" first in alternative constructors, unfortunately, so you need to use expressions in the argument list

Yes, I got that impression from the compiler error message. I am just wondering if there is a good reason that "this" must be called first. If not, then relaxing that requirement would allow for more readable constructors in some cases.

Russ P.
 

Am 11.02.2010 um 21:43 schrieb Russ Paielli:

> I am implementing a class to represent aircraft velocity. The main constructor takes groundspeed, course angle, and altitude rate as parameters. These are the standard polar coordinates of velocity. I would like to also have a constructor that takes a vector of cartesian coordinates. I tried something like this:
>
> class Velocity(val gspeed: Double=0, val course: Double=0,
>     val altrate: Double=0) {
>
>     def this(vec: Vector) {
>
>         val gspeed = hypot(vec(0), vec(1))
>         val course = atan2(vec(0), vec(1))
>         val altrate = vec(2)
>
>         this(gspeed, course, altrate)
>         }
>
> However, the compiler complained:
>
> 'this' expected but 'val' found.
> [error]         val gspeed = hypot(vec(0), vec(1))
> [error]         ^
>
> I realize that I could simply omit the intermediate values and plug the necessary expressions directly into the constructor, but that does not seem as elegant or readable to me. Shouldn't I be able to do some preliminary calculations before I plug into the "this"? Thanks.
>
> Russ P.
>
> --
> http://RussP.us




--
http://RussP.us
Mark Harrah
Joined: 2008-12-18,
User offline. Last seen 35 weeks 3 days ago.
Re: alternate constructors

On Thursday 11 February 2010 05:03:31 pm Russ Paielli wrote:
> On Thu, Feb 11, 2010 at 1:48 PM, Sciss wrote:
> > yes, i think you must call "this" first in alternative constructors,
> > unfortunately, so you need to use expressions in the argument list
>
> Yes, I got that impression from the compiler error message. I am just
> wondering if there is a good reason that "this" must be called first. If
> not, then relaxing that requirement would allow for more readable
> constructors in some cases.

The spec says this is to prevent cycles. In any case, instead of auxiliary
constructors, consider defining an apply method on the companion object:

object Velocity {
def apply(vec: Vector): Velocity = {
val gspeed = ...
val course = ...
val altrate = ...
new Velocity(gspeed, course, altrate)
}
}

Invoke as
Velocity(vec)
instead of
new Velocity(vec)

-Mark

>
> > Am 11.02.2010 um 21:43 schrieb Russ Paielli:
> > > I am implementing a class to represent aircraft velocity. The main
> >
> > constructor takes groundspeed, course angle, and altitude rate as
> > parameters. These are the standard polar coordinates of velocity. I would
> > like to also have a constructor that takes a vector of cartesian
> >
> > coordinates. I tried something like this:
> > > class Velocity(val gspeed: Double=0, val course: Double=0,
> > > val altrate: Double=0) {
> > >
> > > def this(vec: Vector) {
> > >
> > > val gspeed = hypot(vec(0), vec(1))
> > > val course = atan2(vec(0), vec(1))
> > > val altrate = vec(2)
> > >
> > > this(gspeed, course, altrate)
> > > }
> > >
> > > However, the compiler complained:
> > >
> > > 'this' expected but 'val' found.
> > > [error] val gspeed = hypot(vec(0), vec(1))
> > > [error] ^
> > >
> > > I realize that I could simply omit the intermediate values and plug the
> >
> > necessary expressions directly into the constructor, but that does not
> > seem as elegant or readable to me. Shouldn't I be able to do some
> > preliminary calculations before I plug into the "this"? Thanks.
> >
> > > Russ P.
> > >
> > > --
> > > http://RussP.us

Joshua.Suereth
Joined: 2008-09-02,
User offline. Last seen 32 weeks 5 days ago.
Re: alternate constructors
+1 on this


In general, you should try to avoid multiple constructors and provide "factories" instead.

On Thu, Feb 11, 2010 at 5:15 PM, Mark Harrah <harrah@bu.edu> wrote:
On Thursday 11 February 2010 05:03:31 pm Russ Paielli wrote:
> On Thu, Feb 11, 2010 at 1:48 PM, Sciss <contact@sciss.de> wrote:
> > yes, i think you must call "this" first in alternative constructors,
> > unfortunately, so you need to use expressions in the argument list
>
> Yes, I got that impression from the compiler error message. I am just
> wondering if there is a good reason that "this" must be called first. If
> not, then relaxing that requirement would allow for more readable
> constructors in some cases.

The spec says this is to prevent cycles.  In any case, instead of auxiliary
constructors, consider defining an apply method on the companion object:

object Velocity {
 def apply(vec: Vector): Velocity = {
   val gspeed = ...
   val course = ...
   val altrate = ...
   new Velocity(gspeed, course, altrate)
 }
}

Invoke as
 Velocity(vec)
instead of
 new Velocity(vec)

-Mark

>
> > Am 11.02.2010 um 21:43 schrieb Russ Paielli:
> > > I am implementing a class to represent aircraft velocity. The main
> >
> > constructor takes groundspeed, course angle, and altitude rate as
> > parameters. These are the standard polar coordinates of velocity. I would
> > like to also have a constructor that takes a vector of cartesian
> >
> > coordinates. I tried something like this:
> > > class Velocity(val gspeed: Double=0, val course: Double=0,
> > >     val altrate: Double=0) {
> > >
> > >     def this(vec: Vector) {
> > >
> > >         val gspeed = hypot(vec(0), vec(1))
> > >         val course = atan2(vec(0), vec(1))
> > >         val altrate = vec(2)
> > >
> > >         this(gspeed, course, altrate)
> > >         }
> > >
> > > However, the compiler complained:
> > >
> > > 'this' expected but 'val' found.
> > > [error]         val gspeed = hypot(vec(0), vec(1))
> > > [error]         ^
> > >
> > > I realize that I could simply omit the intermediate values and plug the
> >
> > necessary expressions directly into the constructor, but that does not
> > seem as elegant or readable to me. Shouldn't I be able to do some
> > preliminary calculations before I plug into the "this"? Thanks.
> >
> > > Russ P.
> > >
> > > --
> > > http://RussP.us


Henry Ware
Joined: 2009-03-07,
User offline. Last seen 42 years 45 weeks ago.
Re: alternate constructors

There is a downside to companion factory methods: no mix-ins. Often
that is too high a cost to pay.

On Thu, Feb 11, 2010 at 5:15 PM, Mark Harrah wrote:
> On Thursday 11 February 2010 05:03:31 pm Russ Paielli wrote:
>> On Thu, Feb 11, 2010 at 1:48 PM, Sciss wrote:
>> > yes, i think you must call "this" first in alternative constructors,
>> > unfortunately, so you need to use expressions in the argument list
>>
>> Yes, I got that impression from the compiler error message. I am just
>> wondering if there is a good reason that "this" must be called first. If
>> not, then relaxing that requirement would allow for more readable
>> constructors in some cases.
>
> The spec says this is to prevent cycles.  In any case, instead of auxiliary
> constructors, consider defining an apply method on the companion object:
>
> object Velocity {
>  def apply(vec: Vector): Velocity = {
>    val gspeed = ...
>    val course = ...
>    val altrate = ...
>    new Velocity(gspeed, course, altrate)
>  }
> }
>
> Invoke as
>  Velocity(vec)
> instead of
>  new Velocity(vec)
>
> -Mark
>
>>
>> > Am 11.02.2010 um 21:43 schrieb Russ Paielli:
>> > > I am implementing a class to represent aircraft velocity. The main
>> >
>> > constructor takes groundspeed, course angle, and altitude rate as
>> > parameters. These are the standard polar coordinates of velocity. I would
>> > like to also have a constructor that takes a vector of cartesian
>> >
>> > coordinates. I tried something like this:
>> > > class Velocity(val gspeed: Double=0, val course: Double=0,
>> > >     val altrate: Double=0) {
>> > >
>> > >     def this(vec: Vector) {
>> > >
>> > >         val gspeed = hypot(vec(0), vec(1))
>> > >         val course = atan2(vec(0), vec(1))
>> > >         val altrate = vec(2)
>> > >
>> > >         this(gspeed, course, altrate)
>> > >         }
>> > >
>> > > However, the compiler complained:
>> > >
>> > > 'this' expected but 'val' found.
>> > > [error]         val gspeed = hypot(vec(0), vec(1))
>> > > [error]         ^
>> > >
>> > > I realize that I could simply omit the intermediate values and plug the
>> >
>> > necessary expressions directly into the constructor, but that does not
>> > seem as elegant or readable to me. Shouldn't I be able to do some
>> > preliminary calculations before I plug into the "this"? Thanks.
>> >
>> > > Russ P.
>> > >
>> > > --
>> > > http://RussP.us
>
>

Joshua.Suereth
Joined: 2008-09-02,
User offline. Last seen 32 weeks 5 days ago.
Re: alternate constructors
That's also something I'd love to remedy with enough free time.

On Thu, Feb 11, 2010 at 8:37 PM, Henry Ware <henryware@gmail.com> wrote:
There is a downside to companion factory methods: no mix-ins.  Often
that is too high a cost to pay.

On Thu, Feb 11, 2010 at 5:15 PM, Mark Harrah <harrah@bu.edu> wrote:
> On Thursday 11 February 2010 05:03:31 pm Russ Paielli wrote:
>> On Thu, Feb 11, 2010 at 1:48 PM, Sciss <contact@sciss.de> wrote:
>> > yes, i think you must call "this" first in alternative constructors,
>> > unfortunately, so you need to use expressions in the argument list
>>
>> Yes, I got that impression from the compiler error message. I am just
>> wondering if there is a good reason that "this" must be called first. If
>> not, then relaxing that requirement would allow for more readable
>> constructors in some cases.
>
> The spec says this is to prevent cycles.  In any case, instead of auxiliary
> constructors, consider defining an apply method on the companion object:
>
> object Velocity {
>  def apply(vec: Vector): Velocity = {
>    val gspeed = ...
>    val course = ...
>    val altrate = ...
>    new Velocity(gspeed, course, altrate)
>  }
> }
>
> Invoke as
>  Velocity(vec)
> instead of
>  new Velocity(vec)
>
> -Mark
>
>>
>> > Am 11.02.2010 um 21:43 schrieb Russ Paielli:
>> > > I am implementing a class to represent aircraft velocity. The main
>> >
>> > constructor takes groundspeed, course angle, and altitude rate as
>> > parameters. These are the standard polar coordinates of velocity. I would
>> > like to also have a constructor that takes a vector of cartesian
>> >
>> > coordinates. I tried something like this:
>> > > class Velocity(val gspeed: Double=0, val course: Double=0,
>> > >     val altrate: Double=0) {
>> > >
>> > >     def this(vec: Vector) {
>> > >
>> > >         val gspeed = hypot(vec(0), vec(1))
>> > >         val course = atan2(vec(0), vec(1))
>> > >         val altrate = vec(2)
>> > >
>> > >         this(gspeed, course, altrate)
>> > >         }
>> > >
>> > > However, the compiler complained:
>> > >
>> > > 'this' expected but 'val' found.
>> > > [error]         val gspeed = hypot(vec(0), vec(1))
>> > > [error]         ^
>> > >
>> > > I realize that I could simply omit the intermediate values and plug the
>> >
>> > necessary expressions directly into the constructor, but that does not
>> > seem as elegant or readable to me. Shouldn't I be able to do some
>> > preliminary calculations before I plug into the "this"? Thanks.
>> >
>> > > Russ P.
>> > >
>> > > --
>> > > http://RussP.us
>
>

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland