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

case class auxiliary constructors

6 replies
extempore
Joined: 2008-12-17,
User offline. Last seen 35 weeks 3 days ago.

I have modified scalac to generate apply methods for all constructors in case classes (at present you have to use "new" on any
constructor except the primary) which doesn't seem to cause any problems. Was this absence intentional for some reason, or would
this be a welcome addition?

The primary is still special of course, because there's only one unapply method. But I think that distinction is a lot less
surprising than the need to use new only sometimes.

odersky
Joined: 2008-07-29,
User offline. Last seen 45 weeks 6 days ago.
Re: case class auxiliary constructors

On Wed, Feb 25, 2009 at 6:40 PM, Paul Phillips wrote:
> I have modified scalac to generate apply methods for all constructors in case classes (at present you have to use "new" on any
> constructor except the primary) which doesn't seem to cause any problems.  Was this absence intentional for some reason, or would
> this be a welcome addition?
>
> The primary is still special of course, because there's only one unapply method.  But I think that distinction is a lot less
> surprising than the need to use new only sometimes.
>
It's a tradeoff like so many things. You either lose the symmetry of
apply/unapply, or you lose the analogy of multiple constructors. Since
it's speced and documented the way it is, I'd leave it. The problem is
that
the change is likely to break existsing code.

Cheers

extempore
Joined: 2008-12-17,
User offline. Last seen 35 weeks 3 days ago.
Re: case class auxiliary constructors

On Fri, Feb 27, 2009 at 09:28:59PM +0100, martin odersky wrote:
> The problem is that the change is likely to break existsing code.

Really? I had thought about that and couldn't come up with the situation
where it would break anything, which was supported at least a bit by the
fact that the whole test suite passed. Do you have a circumstance in
mind where this would alter the behavior of currently legal code?

I had thought maybe the 0-arg version would cause a problem, but it's
already the case that "Foo" is of Foo.type and "Foo()" calls the apply
method, and that's the same after the change.

odersky
Joined: 2008-07-29,
User offline. Last seen 45 weeks 6 days ago.
Re: case class auxiliary constructors

The problem is that the apply methods are added blindly without
reference whether they are already present or not. So if a user did write
an explicit apply (because they did not want to write `new', say) you
get a double definition error.

Cheers

- Martin

On Fri, Feb 27, 2009 at 9:36 PM, Paul Phillips wrote:
> On Fri, Feb 27, 2009 at 09:28:59PM +0100, martin odersky wrote:
>> The problem is that the change is likely to break existsing code.
>
> Really? I had thought about that and couldn't come up with the situation
> where it would break anything, which was supported at least a bit by the
> fact that the whole test suite passed.  Do you have a circumstance in
> mind where this would alter the behavior of currently legal code?
>
> I had thought maybe the 0-arg version would cause a problem, but it's
> already the case that "Foo" is of Foo.type and "Foo()" calls the apply
> method, and that's the same after the change.
>
> --
> Paul Phillips      | It's not enough to bash in heads - you've got to
> Caged Spirit       | bash in minds.
> Empiricist         |     -- Capt Hammer
> up hill, pi pals!  |----------* http://www.improving.org/paulp/ *----------
>
>

extempore
Joined: 2008-12-17,
User offline. Last seen 35 weeks 3 days ago.
Re: case class auxiliary constructors

On Fri, Feb 27, 2009 at 09:39:42PM +0100, martin odersky wrote:
> The problem is that the apply methods are added blindly without
> reference whether they are already present or not. So if a user did write
> an explicit apply (because they did not want to write `new', say) you
> get a double definition error.

Ah. I hadn't implemented it, but my plan was only to insert them if
they weren't already present. I figured this followed in the footsteps
of toString and equals at least, which are selective inserted in case
objects (even companion case objects) based on whether or not the AnyRef
versions have already been overridden.

I'm only noticing for the first time now that the current implementation
puts the apply in blindly so it's an error to define your own for the
case class's primary. This seems unnecessarily restrictive to me - for
better or worse case classes have a few different kinds of functionality
in them, and as it stands you cannot use the rest of it if you're not
willing to cede control of your primary constructor.

So I am proposing that both these can be handled by inserting only
non-conflicting constructors.

odersky
Joined: 2008-07-29,
User offline. Last seen 45 weeks 6 days ago.
Re: case class auxiliary constructors

On Fri, Feb 27, 2009 at 10:10 PM, Paul Phillips wrote:
> On Fri, Feb 27, 2009 at 09:39:42PM +0100, martin odersky wrote:
>> The problem is that the apply methods are added blindly without
>> reference whether they are already present or not. So if a user did write
>> an explicit apply (because they did not want to write `new', say) you
>> get a double definition error.
>
> Ah.  I hadn't implemented it, but my plan was only to insert them if
> they weren't already present.  I figured this followed in the footsteps
> of toString and equals at least, which are selective inserted in case
> objects (even companion case objects) based on whether or not the AnyRef
> versions have already been overridden.
>
> I'm only noticing for the first time now that the current implementation
> puts the apply in blindly so it's an error to define your own for the
> case class's primary.  This seems unnecessarily restrictive to me - for
> better or worse case classes have a few different kinds of functionality
> in them, and as it stands you cannot use the rest of it if you're not
> willing to cede control of your primary constructor.
>
> So I am proposing that both these can be handled by inserting only
> non-conflicting constructors.
>
I knew you would say that :-) It does not work, though, because there
are very subtle interactions which lead
to cyclic reference errors because things would be foced to quickly. I
tried it, and it did not work. That's why the methods are added
blindly, which is indeed not in line with Scala's philosophy
elsewhere.

Cheers

extempore
Joined: 2008-12-17,
User offline. Last seen 35 weeks 3 days ago.
Re: case class auxiliary constructors

On Fri, Feb 27, 2009 at 10:53:54PM +0100, martin odersky wrote:
> I knew you would say that :-) It does not work, though, because there
> are very subtle interactions which lead to cyclic reference errors
> because things would be foced to quickly. I tried it, and it did not
> work. That's why the methods are added blindly, which is indeed not in
> line with Scala's philosophy elsewhere.

I should have known... okay, unless I come up with something brilliant
I'll file this code in the bitbucket. This has been helpful even if all
that comes of it is clear documentation as to why things are the way
they are.

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