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

default parameter values and constructors

13 replies
Viktor Klang
Joined: 2008-12-17,
User offline. Last seen 1 year 27 weeks ago.
Hey guys,

I'm facing a bit of a bummer when it comes to generating sensible immutable builders that works great with both Java and Scala:
object B {
  val defaultA = ...
  val defaultBoo = ...
  val defaultCow = ...
}

case class B(a: A = B.defaultA, b: Boo = B.defaultBoo, c: Cow = B.defaultCow)


Now, this works great in scala, and if I want to share the same "root" B, I can add the following to object B:

val defaultB = new B()
def apply(): B = defaultB

So all calls to B() will reuse the same instance.

Up until now life was good.

Then we need some sensible builder API:

B().copy(a = new A) <--- works well, but perhaps a bit sterile.

so we add the following methods to class B:

def withA(_a: A) = copy(a = _a)
def withBoo(_b: Boo) = copy(b = _b)
def withCow(_c: Cow) = copy(c = _c)

So now we can do:

B().withA(someA).withBoo(someBooFromTehInternetz())

and also: new B(a = someA, b = someBooFromTehInternetz())

Now we need this to work with Java.

so:

new B() <--- doesn't work, only constructor generated is this(a, b, c)
B$.MODULE$.apply() <-- not very nice now is it

So, I understand why we can't have named parameters in Java, but why dear God, isn't the appropriate permutation of constructors generated?

def this() = this(B.defaultA, B.defaultBoo, B.defaultCow)
def this(a: A) = this(a, B.defaultBoo, B.defaultCow)
def this(a: A, b: Boo) = this(a, b, B.defaultCow)
def this(a: A, b: Boo, c: Cow) <-- this is already generated, the others are not


Then it is only in the face of named parameters that default parameter values need to use the "full" constructor.

OR there's some very good reason why it's not like this already? Or perhaps an annotation to force the compiler to be a bit more Java friendly?


Cheers,


--
Viktor Klang

Akka Tech LeadTypesafe - Enterprise-Grade Scala from the Experts

Twitter: @viktorklang
gkossakowski
Joined: 2010-03-11,
User offline. Last seen 33 weeks 5 days ago.
Re: default parameter values and constructors
2011/8/11 √iktor Ҡlang <viktor [dot] klang [at] gmail [dot] com>
def this() = this(B.defaultA, B.defaultBoo, B.defaultCow)
def this(a: A) = this(a, B.defaultBoo, B.defaultCow)
def this(a: A, b: Boo) = this(a, b, B.defaultCow)
def this(a: A, b: Boo, c: Cow) <-- this is already generated, the others are not


Then it is only in the face of named parameters that default parameter values need to use the "full" constructor.

OR there's some very good reason why it's not like this already? Or perhaps an annotation to force the compiler to be a bit more Java friendly?

I'm not authoritative source by any means but your list above is not complete. You need need also:
def this(B: Boo) = ...def this(C: Cow) = ...def this(A: A, c: Cow) = ...def this(B: Boo, c: Cow) = ...
That gives you 8 constructors for 3 parameters. Actually, you would need to generate 2^n constructors. In general, we don't like anything of 2^n complexity in computer science :-)
--
Grzegorz Kossakowski

Viktor Klang
Joined: 2008-12-17,
User offline. Last seen 1 year 27 weeks ago.
Re: default parameter values and constructors


On Thu, Aug 11, 2011 at 11:28 AM, Grzegorz Kossakowski <grzegorz [dot] kossakowski [at] gmail [dot] com> wrote:
2011/8/11 √iktor Ҡlang <viktor [dot] klang [at] gmail [dot] com>
def this() = this(B.defaultA, B.defaultBoo, B.defaultCow)
def this(a: A) = this(a, B.defaultBoo, B.defaultCow)
def this(a: A, b: Boo) = this(a, b, B.defaultCow)
def this(a: A, b: Boo, c: Cow) <-- this is already generated, the others are not


Then it is only in the face of named parameters that default parameter values need to use the "full" constructor.

OR there's some very good reason why it's not like this already? Or perhaps an annotation to force the compiler to be a bit more Java friendly?

I'm not authoritative source by any means but your list above is not complete. You need need also:
def this(B: Boo) = ...def this(C: Cow) = ...def this(A: A, c: Cow) = ...def this(B: Boo, c: Cow) = ...
That gives you 8 constructors for 3 parameters. Actually, you would need to generate 2^n constructors. In general, we don't like anything of 2^n complexity in computer science :-)

Nononononono, as I said, for Scala, when you use parameter names, you'd stick to the original implementation, that uses the "full" constructor. So you only need to generate one constructor per parameter (extra, since you already have the "full" constructor)

 

--
Grzegorz Kossakowski




--
Viktor Klang

Akka Tech LeadTypesafe - Enterprise-Grade Scala from the Experts

Twitter: @viktorklang
Jason Zaugg
Joined: 2009-05-18,
User offline. Last seen 38 weeks 5 days ago.
Re: default parameter values and constructors

2011/8/11 √iktor Ҡlang :
> I'm facing a bit of a bummer when it comes to generating sensible immutable
> builders that works great with both Java and Scala:
> object B {
>   val defaultA = ...
>   val defaultBoo = ...
>   val defaultCow = ...
> }
>
> case class B(a: A = B.defaultA, b: Boo = B.defaultBoo, c: Cow =
> B.defaultCow)
>
>
> Now, this works great in scala, and if I want to share the same "root" B, I
> can add the following to object B:
>
> val defaultB = new B()
> def apply(): B = defaultB
>
> So all calls to B() will reuse the same instance.
>
> Up until now life was good.
>
> Then we need some sensible builder API:
>
> B().copy(a = new A) <--- works well, but perhaps a bit sterile.
>
> so we add the following methods to class B:
>
> def withA(_a: A) = copy(a = _a)
> def withBoo(_b: Boo) = copy(b = _b)
> def withCow(_c: Cow) = copy(c = _c)
>
> So now we can do:
>
> B().withA(someA).withBoo(someBooFromTehInternetz())
>
> and also: new B(a = someA, b = someBooFromTehInternetz())
>
> Now we need this to work with Java.
>
> so:
>
> new B() <--- doesn't work, only constructor generated is this(a, b, c)
> B$.MODULE$.apply() <-- not very nice now is it

See: https://issues.scala-lang.org/browse/SI-4278

-jason

Viktor Klang
Joined: 2008-12-17,
User offline. Last seen 1 year 27 weeks ago.
Re: default parameter values and constructors


On Thu, Aug 11, 2011 at 11:29 AM, Jason Zaugg <jzaugg [at] gmail [dot] com> wrote:
2011/8/11 √iktor Ҡlang <viktor [dot] klang [at] gmail [dot] com>:
> I'm facing a bit of a bummer when it comes to generating sensible immutable
> builders that works great with both Java and Scala:
> object B {
>   val defaultA = ...
>   val defaultBoo = ...
>   val defaultCow = ...
> }
>
> case class B(a: A = B.defaultA, b: Boo = B.defaultBoo, c: Cow =
> B.defaultCow)
>
>
> Now, this works great in scala, and if I want to share the same "root" B, I
> can add the following to object B:
>
> val defaultB = new B()
> def apply(): B = defaultB
>
> So all calls to B() will reuse the same instance.
>
> Up until now life was good.
>
> Then we need some sensible builder API:
>
> B().copy(a = new A) <--- works well, but perhaps a bit sterile.
>
> so we add the following methods to class B:
>
> def withA(_a: A) = copy(a = _a)
> def withBoo(_b: Boo) = copy(b = _b)
> def withCow(_c: Cow) = copy(c = _c)
>
> So now we can do:
>
> B().withA(someA).withBoo(someBooFromTehInternetz())
>
> and also: new B(a = someA, b = someBooFromTehInternetz())
>
> Now we need this to work with Java.
>
> so:
>
> new B() <--- doesn't work, only constructor generated is this(a, b, c)
> B$.MODULE$.apply() <-- not very nice now is it

See: https://issues.scala-lang.org/browse/SI-4278


Wow, that's sad. Boilerplate FTL
 
-jason



--
Viktor Klang

Akka Tech LeadTypesafe - Enterprise-Grade Scala from the Experts

Twitter: @viktorklang
extempore
Joined: 2008-12-17,
User offline. Last seen 35 weeks 3 days ago.
Re: default parameter values and constructors

On 8/11/11 2:34 AM, √iktor Ҡlang wrote:
> Wow, that's sad. Boilerplate FTL

I supported the creation of the default constructor (this the one
meeting for which I was physically present) and was chewed out for
several minutes for trying to wreck the purity of the language with my
expediences. This experience led me since then to focus on my own
specific interests rather than supporting things just because I think
they make sense. Since good java interop is in the second category, not
the first, you might want to find an advocate from the akka ranks.

odersky
Joined: 2008-07-29,
User offline. Last seen 45 weeks 6 days ago.
Re: default parameter values and constructors
Generating overloaded variants has always the risk that unexpected clashes appear, and some call becomes ambiguous. So it should not be done lightly. I think Java interop is not a sufficiently strong reason to
mess with the language, as long as alternatives exist. And I think

https://issues.scala-lang.org/browse/SI-4278

does show valid ways to deal with the problem. Specifically, what's so bad about writing the missing constructors yourself?

Cheers

 -- Martin

2011/8/11 Paul Phillips <paulp [at] improving [dot] org>
On 8/11/11 2:34 AM, √iktor Ҡlang wrote:
Wow, that's sad. Boilerplate FTL

I supported the creation of the default constructor (this the one meeting for which I was physically present) and was chewed out for several minutes for trying to wreck the purity of the language with my expediences.  This experience led me since then to focus on my own specific interests rather than supporting things just because I think they make sense.  Since good java interop is in the second category, not the first, you might want to find an advocate from the akka ranks.



--
Martin Odersky
Prof., EPFL and Chairman, Typesafe
PSED, 1015 Lausanne, Switzerland
Tel. EPFL: +41 21 693 6863
Tel. Typesafe: +41 21 691 4967

Viktor Klang
Joined: 2008-12-17,
User offline. Last seen 1 year 27 weeks ago.
Re: default parameter values and constructors


2011/8/11 martin odersky <martin [dot] odersky [at] epfl [dot] ch>
Generating overloaded variants has always the risk that unexpected clashes appear, and some call becomes ambiguous. So it should not be done lightly. I think Java interop is not a sufficiently strong reason to
mess with the language, as long as alternatives exist. And I think

https://issues.scala-lang.org/browse/SI-4278

does show valid ways to deal with the problem. Specifically, what's so bad about writing the missing constructors yourself?

Because I have to both write a lot of BP, in my case it's a class with 10 parameters with default parameter values, which means quite few extra lines, and also, when I want to rearrange the parameters or add or remove a parameter, I need to remember to change and/or create new constructors as well as adding all of them to unit-tests so I'm sure that the Java API works as expected and doesn't crap out silently.
 
There shouldn't be any clashes since any user defined constructors with the same signature should take priority over constructor generation.

Also, it's kind of a silent killer, because unless you actually test in Java, you won't notice the interop problem until some Java, JRuby, Groovy user tells you they don't know how to create an instance of the class...

Now, clearly this is just a Java interop issue, but alas.

Cheers,



Cheers

 -- Martin

2011/8/11 Paul Phillips <paulp [at] improving [dot] org>
On 8/11/11 2:34 AM, √iktor Ҡlang wrote:
Wow, that's sad. Boilerplate FTL

I supported the creation of the default constructor (this the one meeting for which I was physically present) and was chewed out for several minutes for trying to wreck the purity of the language with my expediences.  This experience led me since then to focus on my own specific interests rather than supporting things just because I think they make sense.  Since good java interop is in the second category, not the first, you might want to find an advocate from the akka ranks.



--
Martin Odersky
Prof., EPFL and Chairman, Typesafe
PSED, 1015 Lausanne, Switzerland
Tel. EPFL: +41 21 693 6863
Tel. Typesafe: +41 21 691 4967




--
Viktor Klang

Akka Tech LeadTypesafe - Enterprise-Grade Scala from the Experts

Twitter: @viktorklang
Jason Zaugg
Joined: 2009-05-18,
User offline. Last seen 38 weeks 5 days ago.
Re: default parameter values and constructors

2011/8/11 √iktor Ҡlang :
>
>
> 2011/8/11 martin odersky
>>
>> Generating overloaded variants has always the risk that unexpected clashes
>> appear, and some call becomes ambiguous. So it should not be done lightly. I
>> think Java interop is not a sufficiently strong reason to
>> mess with the language, as long as alternatives exist. And I think
>>
>> https://issues.scala-lang.org/browse/SI-4278
>>
>> does show valid ways to deal with the problem. Specifically, what's so bad
>> about writing the missing constructors yourself?
>
> Because I have to both write a lot of BP, in my case it's a class with 10
> parameters with default parameter values, which means quite few extra lines,
> and also, when I want to rearrange the parameters or add or remove a
> parameter, I need to remember to change and/or create new constructors as
> well as adding all of them to unit-tests so I'm sure that the Java API works
> as expected and doesn't crap out silently.
>
> There shouldn't be any clashes since any user defined constructors with the
> same signature should take priority over constructor generation.
>
> Also, it's kind of a silent killer, because unless you actually test in
> Java, you won't notice the interop problem until some Java, JRuby, Groovy
> user tells you they don't know how to create an instance of the class...
>
> Now, clearly this is just a Java interop issue, but alas.

Sounds like a good candidate for an opt-in annotation, a-la
@BeanProperty. It could also be useful on methods.

But I wouldn't want to see this by default.

-jason

Viktor Klang
Joined: 2008-12-17,
User offline. Last seen 1 year 27 weeks ago.
Re: default parameter values and constructors


On Thu, Aug 11, 2011 at 7:03 PM, Jason Zaugg <jzaugg [at] gmail [dot] com> wrote:
2011/8/11 √iktor Ҡlang <viktor [dot] klang [at] gmail [dot] com>:
>
>
> 2011/8/11 martin odersky <martin [dot] odersky [at] epfl [dot] ch>
>>
>> Generating overloaded variants has always the risk that unexpected clashes
>> appear, and some call becomes ambiguous. So it should not be done lightly. I
>> think Java interop is not a sufficiently strong reason to
>> mess with the language, as long as alternatives exist. And I think
>>
>> https://issues.scala-lang.org/browse/SI-4278
>>
>> does show valid ways to deal with the problem. Specifically, what's so bad
>> about writing the missing constructors yourself?
>
> Because I have to both write a lot of BP, in my case it's a class with 10
> parameters with default parameter values, which means quite few extra lines,
> and also, when I want to rearrange the parameters or add or remove a
> parameter, I need to remember to change and/or create new constructors as
> well as adding all of them to unit-tests so I'm sure that the Java API works
> as expected and doesn't crap out silently.
>
> There shouldn't be any clashes since any user defined constructors with the
> same signature should take priority over constructor generation.
>
> Also, it's kind of a silent killer, because unless you actually test in
> Java, you won't notice the interop problem until some Java, JRuby, Groovy
> user tells you they don't know how to create an instance of the class...
>
> Now, clearly this is just a Java interop issue, but alas.

Sounds like a good candidate for an opt-in annotation, a-la
@BeanProperty. It could also be useful on methods.


I'd be completely fine with that as well, I could even envision some kind of @JavaFriendly that could be sprinkled all over the place, or a compiler flag, but that's a bit more blunt.
 
But I wouldn't want to see this by default.

What problems do you envision?
 

-jason



--
Viktor Klang

Akka Tech LeadTypesafe - Enterprise-Grade Scala from the Experts

Twitter: @viktorklang
Jason Zaugg
Joined: 2009-05-18,
User offline. Last seen 38 weeks 5 days ago.
Re: default parameter values and constructors

2011/8/11 √iktor Ҡlang :
> On Thu, Aug 11, 2011 at 7:03 PM, Jason Zaugg wrote:
>>
>> 2011/8/11 √iktor Ҡlang :
>> >
>> >
>> > 2011/8/11 martin odersky
>> >>
>> >> Generating overloaded variants has always the risk that unexpected
>> >> clashes
>> >> appear, and some call becomes ambiguous. So it should not be done
>> >> lightly. I
>> >> think Java interop is not a sufficiently strong reason to
>> >> mess with the language, as long as alternatives exist. And I think
>> >>
>> >> https://issues.scala-lang.org/browse/SI-4278
>> >>
>> >> does show valid ways to deal with the problem. Specifically, what's so
>> >> bad
>> >> about writing the missing constructors yourself?
>> >
>> > Because I have to both write a lot of BP, in my case it's a class with
>> > 10
>> > parameters with default parameter values, which means quite few extra
>> > lines,
>> > and also, when I want to rearrange the parameters or add or remove a
>> > parameter, I need to remember to change and/or create new constructors
>> > as
>> > well as adding all of them to unit-tests so I'm sure that the Java API
>> > works
>> > as expected and doesn't crap out silently.
>> >
>> > There shouldn't be any clashes since any user defined constructors with
>> > the
>> > same signature should take priority over constructor generation.
>> >
>> > Also, it's kind of a silent killer, because unless you actually test in
>> > Java, you won't notice the interop problem until some Java, JRuby,
>> > Groovy
>> > user tells you they don't know how to create an instance of the class...
>> >
>> > Now, clearly this is just a Java interop issue, but alas.
>>
>> Sounds like a good candidate for an opt-in annotation, a-la
>> @BeanProperty. It could also be useful on methods.
>>
>
> I'd be completely fine with that as well, I could even envision some kind of
> @JavaFriendly that could be sprinkled all over the place, or a compiler
> flag, but that's a bit more blunt.
>
>>
>> But I wouldn't want to see this by default.
>
> What problems do you envision?

Bytecode bloat.

-jason

Randall R Schulz
Joined: 2008-12-16,
User offline. Last seen 1 year 29 weeks ago.
Re: default parameter values and constructors

On Thursday 11 August 2011, Jason Zaugg wrote:
> 2011/8/11 √iktor Ҡlang :
> > ...
> >
> > What problems do you envision?
>
> Bytecode bloat.
>
> -jason

Seriously? In Scala? Every little function literal / closure / by-name
parameter produces its own class! Surely we're beyond making
"bytecode bloat" a first-order concern?

Randall Schulz

Jason Zaugg
Joined: 2009-05-18,
User offline. Last seen 38 weeks 5 days ago.
Re: default parameter values and constructors

On Fri, Aug 12, 2011 at 2:46 AM, Randall R Schulz wrote:
> On Thursday 11 August 2011, Jason Zaugg wrote:
>> 2011/8/11 √iktor Ҡlang :
>> > ...
>> >
>> > What problems do you envision?
>>
>> Bytecode bloat.
>>
>> -jason
>
> Seriously? In Scala? Every little function literal / closure / by-name
> parameter  produces its own class! Surely we're beyond making
> "bytecode bloat" a first-order concern?

I have constructors with a dozen parameters with defaults, typically
for config objects. If the proposal is to generate overloads for all
combinations of defaults, there is a very real problem. If we just
create a default constructor, there isn't a big win in boilerplate
reduction.

-jason

Viktor Klang
Joined: 2008-12-17,
User offline. Last seen 1 year 27 weeks ago.
Re: default parameter values and constructors


On Fri, Aug 12, 2011 at 7:24 AM, Jason Zaugg <jzaugg [at] gmail [dot] com> wrote:
On Fri, Aug 12, 2011 at 2:46 AM, Randall R Schulz <rschulz [at] sonic [dot] net> wrote:
> On Thursday 11 August 2011, Jason Zaugg wrote:
>> 2011/8/11 √iktor Ҡlang <viktor [dot] klang [at] gmail [dot] com>:
>> > ...
>> >
>> > What problems do you envision?
>>
>> Bytecode bloat.
>>
>> -jason
>
> Seriously? In Scala? Every little function literal / closure / by-name
> parameter  produces its own class! Surely we're beyond making
> "bytecode bloat" a first-order concern?

I have constructors with a dozen parameters with defaults, typically
for config objects. If the proposal is to generate overloads for all
combinations of defaults, there is a very real problem. If we just
create a default constructor, there isn't a big win in boilerplate
reduction.

We could have an opt-out instead: @dietcode
 

-jason



--
Viktor Klang

Akka Tech LeadTypesafe - Enterprise-Grade Scala from the Experts

Twitter: @viktorklang

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