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

Re: Name Collisions With Private Fields and Public Getters/Setters

15 replies
Kevin Wright
Joined: 2009-06-09,
User offline. Last seen 49 weeks 4 days ago.
Thanks Daniel, just beat me to it :)
I've also noticed a convention in scala.swing to use name0 and password0 instead of initialName and initialPassword for this kind of thing.  Definitely worth considering if you like conciseness, but I'm not really sure if it's going to become a standard pattern though...

On Wed, Aug 26, 2009 at 11:47 PM, Daniel Sobral <dcsobral [at] gmail [dot] com> wrote:
On Wed, Aug 26, 2009 at 7:38 PM, Philip Köster <philip [dot] koester [at] web [dot] de> wrote:
Have you considered using an inner singleton object to contain these private fields?

No, I'm afraid I haven't. (Been learning Scala for two days now. ;)) Mind to share an example?

 class User(initialName: String, initialPassword: String) {
   private object fields {
     var name: String = initialName;
     var password: String = initialPassword;
   }
   def name = fields.name
   def name_=(newName: String) = fields.name = newName
   def password = fields.password
   def password_=(newPassword: String) = fields.password = newPassword
 }
--
Daniel C. Sobral

Something I learned in academia: there are three kinds of academic reviews: review by name, review by reference and review by value.

phkoester
Joined: 2009-08-23,
User offline. Last seen 42 years 45 weeks ago.
Re: Name Collisions With Private Fields and Public Getters/Set

Thanks, Kevin,

you came up with a solution that abandons the unwanted prefixes---at the
expense of adding a boilerplate inner class managing a class's private
vars. Whilst I'm seeing the beauty in your approach, it is clear that
lines-of-code would increase this way, compared to the suggestion that I
proposed.

---Ph.

Kevin Wright
Joined: 2009-06-09,
User offline. Last seen 49 weeks 4 days ago.
Re: Name Collisions With Private Fields and Public Getters/Set


On Thu, Aug 27, 2009 at 12:20 AM, Philip Köster <philip [dot] koester [at] web [dot] de> wrote:
Thanks, Kevin,

you came up with a solution that abandons the unwanted prefixes---at the expense of adding a boilerplate inner class managing a class's private vars. Whilst I'm seeing the beauty in your approach, it is clear that lines-of-code would increase this way, compared to the suggestion that I proposed.

---Ph.

Yup, there's always a trade-off in any design :)
This one has a lofty heritage and dates back to the pimpl/compile firewall pattern from the heady days of C++
I've found it can also pay for itself in certain circumstances, consider the following (not run this though a compiler yet, so apologies for any errors):
class User(name0: String, password0: String) {   private case class Fields(var name: String, var password0: String)  private object fields = Fields(name0, password0)

  def name = fields.name
  def name_=(newName: String) = fields.name = newName
  def password = fields.password
  def password_=(newPassword: String) = fields.password = newPassword
}
equality, copy, etc. can now delegate to the fields member and take advantage of case class semantics. (insert the normal disclaimer against using mutable objects as hash keys here)
phkoester
Joined: 2009-08-23,
User offline. Last seen 42 years 45 weeks ago.
Re: Name Collisions With Private Fields and Public Getters/Set

> Yup, there's always a trade-off in any design :)

We're moving from a user posting to a language-specification request.
With a bit of luck, Martin Odersky is listening.

Without further knowledge on the nitty-gritty but with some experience
in parser generation, I think that overloading of intrinsic (i.e.
auto-supplied) getter and setter method can be added to the Scala
language without breaking existing code if these two conditions are
fulfilled:

1. The SLS (= Scala Language Specification) documents the exact method
signature and method bodies that derive from intrinsic auto-generation
of getters and setters.

2. Overloading such methods matching the exact signature does not yield
a compile-time error but has the intrinsic methods replaced by
user-defined methods.

Given these two rules followed, it should be possible to overload
compiler-generated getters and setters without incurrying that dreaded
``method defined twice.´´

ichoran
Joined: 2009-08-14,
User offline. Last seen 2 years 3 weeks ago.
Re: Name Collisions With Private Fields and Public Getters/Set
On Wed, Aug 26, 2009 at 9:25 PM, Philip Köster <philip [dot] koester [at] web [dot] de> wrote:

1. The SLS (= Scala Language Specification) documents the exact method signature and method bodies that derive from intrinsic auto-generation of getters and setters.

2. Overloading such methods matching the exact signature does not yield a compile-time error but has the intrinsic methods replaced by user-defined methods.

Given these two rules followed, it should be possible to overload compiler-generated getters and setters without incurrying that dreaded ``method defined twice.´´

In Scala, you can substitute getters/setters for fields transparently.  How, then, do you propose to keep the naming straight?

class A(var a:Int) {
  def a = a   // Should this be using the var, or is it tail-recursion?
  def a = this.a  // No, this.a still could be the method a()
}

The issue is that if you have a non-standard getter and setter you need one place to store the data and another place to store the method name, and it's impossible to tell from context which is which unless you take the non-functional view that methods/functions are entirely distinct from fields/variables.  If you don't want a default getter or setter, then don't ask for one (e.g. as in Daniel Sobral's first example with passwords--the second argument to the class constructor was neither val nor var, but was just used as an input to the internal encrypted password data structure).

  --Rex

phkoester
Joined: 2009-08-23,
User offline. Last seen 42 years 45 weeks ago.
Re: Name Collisions With Private Fields and Public Getters/Set

> In Scala, you can substitute getters/setters for fields transparently.
> How, then, do you propose to keep the naming straight?

I couldn't tell until I fully understand how the compiler does it. But
if there is a way for the compiler, I don't see why it shouldn't be
possible for clients ...

I just want to get rid off the prefixes for instance vars---no more, no
less. If Scala is targeted at reducing boilerplate-code, then here is
another opportunity ...

rytz
Joined: 2008-07-01,
User offline. Last seen 45 weeks 5 days ago.
Re: Name Collisions With Private Fields and Public Getters/Set


On Thu, Aug 27, 2009 at 03:25, Philip Köster <philip [dot] koester [at] web [dot] de> wrote:
> Yup, there's always a trade-off in any design :)

We're moving from a user posting to a language-specification request. With a bit of luck, Martin Odersky is listening.

Without further knowledge on the nitty-gritty but with some experience in parser generation, I think that overloading of intrinsic (i.e. auto-supplied) getter and setter method can be added to the Scala language without breaking existing code if these two conditions are fulfilled:

1. The SLS (= Scala Language Specification) documents the exact method signature and method bodies that derive from intrinsic auto-generation of getters and setters.

2. Overloading such methods matching the exact signature does not yield a compile-time error but has the intrinsic methods replaced by user-defined methods.

Given these two rules followed, it should be possible to overload compiler-generated getters and setters without incurrying that dreaded ``method defined twice.´´


We discussed exactly this proposal one week ago in our group meeting at EFPL. People agreed
that this would be a handy feature, but the problem is (as noted by Rex Kerr): there's no way to
access the underlying field directly, every access goes through the getter or setter.

class A {
  var x: Int = 0
  def x_=(x1: Int) { <x-the-field> = abs(x1) }
}

Writing "x = abs(x1)" is a recursive call to the setter.
If somebody has a proposal to access <x-the-field> we're all ears! :)

Lukas
Carsten Saager
Joined: 2008-12-19,
User offline. Last seen 42 years 45 weeks ago.
Re: Name Collisions With Private Fields and Public Getters/Set
Why not using backticking to denote direct access to the var?

class A {
  var x: Int = 0
  def x_=(x1: Int) { `x` = abs(x1) }
  def x = `x`
}

-Carsten

On Thu, Aug 27, 2009 at 10:01 AM, Lukas Rytz <lukas [dot] rytz [at] epfl [dot] ch> wrote:


On Thu, Aug 27, 2009 at 03:25, Philip Köster <philip [dot] koester [at] web [dot] de> wrote:
> Yup, there's always a trade-off in any design :)

We're moving from a user posting to a language-specification request. With a bit of luck, Martin Odersky is listening.

Without further knowledge on the nitty-gritty but with some experience in parser generation, I think that overloading of intrinsic (i.e. auto-supplied) getter and setter method can be added to the Scala language without breaking existing code if these two conditions are fulfilled:

1. The SLS (= Scala Language Specification) documents the exact method signature and method bodies that derive from intrinsic auto-generation of getters and setters.

2. Overloading such methods matching the exact signature does not yield a compile-time error but has the intrinsic methods replaced by user-defined methods.

Given these two rules followed, it should be possible to overload compiler-generated getters and setters without incurrying that dreaded ``method defined twice.´´


We discussed exactly this proposal one week ago in our group meeting at EFPL. People agreed
that this would be a handy feature, but the problem is (as noted by Rex Kerr): there's no way to
access the underlying field directly, every access goes through the getter or setter.

class A {
  var x: Int = 0
  def x_=(x1: Int) { <x-the-field> = abs(x1) }
}

Writing "x = abs(x1)" is a recursive call to the setter.
If somebody has a proposal to access <x-the-field> we're all ears! :)

Lukas

rytz
Joined: 2008-07-01,
User offline. Last seen 45 weeks 5 days ago.
Re: Name Collisions With Private Fields and Public Getters/Set
Is problematic when the identifier needs to be backquoted.

class A {
  var `def`: Int = 0
  def def_=(d: Int) = { `def` = abs(d) }
}

It would also change the meaning of backquotes. Right now, `x` is just
equivalent to x. Or would the new rule only be enabled inside getters / setters?

Lukas


On Thu, Aug 27, 2009 at 10:34, Carsten Saager <csaager [at] gmail [dot] com> wrote:
Why not using backticking to denote direct access to the var?

class A {
  var x: Int = 0
  def x_=(x1: Int) { `x` = abs(x1) }
  def x = `x`
}

-Carsten

On Thu, Aug 27, 2009 at 10:01 AM, Lukas Rytz <lukas [dot] rytz [at] epfl [dot] ch> wrote:


On Thu, Aug 27, 2009 at 03:25, Philip Köster <philip [dot] koester [at] web [dot] de> wrote:
> Yup, there's always a trade-off in any design :)

We're moving from a user posting to a language-specification request. With a bit of luck, Martin Odersky is listening.

Without further knowledge on the nitty-gritty but with some experience in parser generation, I think that overloading of intrinsic (i.e. auto-supplied) getter and setter method can be added to the Scala language without breaking existing code if these two conditions are fulfilled:

1. The SLS (= Scala Language Specification) documents the exact method signature and method bodies that derive from intrinsic auto-generation of getters and setters.

2. Overloading such methods matching the exact signature does not yield a compile-time error but has the intrinsic methods replaced by user-defined methods.

Given these two rules followed, it should be possible to overload compiler-generated getters and setters without incurrying that dreaded ``method defined twice.´´


We discussed exactly this proposal one week ago in our group meeting at EFPL. People agreed
that this would be a handy feature, but the problem is (as noted by Rex Kerr): there's no way to
access the underlying field directly, every access goes through the getter or setter.

class A {
  var x: Int = 0
  def x_=(x1: Int) { <x-the-field> = abs(x1) }
}

Writing "x = abs(x1)" is a recursive call to the setter.
If somebody has a proposal to access <x-the-field> we're all ears! :)

Lukas


Carsten Saager
Joined: 2008-12-19,
User offline. Last seen 42 years 45 weeks ago.
Re: Name Collisions With Private Fields and Public Getters/Set
Well, backticks is just an abuse as this character is not used otherwise. Perhaps ''`def`` and ''x is clearer (two single-quotes, easier to type).

Limiting the direct access to (g|s)etters is perhaps OK, but I think accessing ''x from a subclass might be useful for implementing overrides of the getter and setter

-Carsten

On Thu, Aug 27, 2009 at 11:36 AM, Lukas Rytz <lukas [dot] rytz [at] epfl [dot] ch> wrote:
Is problematic when the identifier needs to be backquoted.

class A {
  var `def`: Int = 0
  def def_=(d: Int) = { `def` = abs(d) }
}

It would also change the meaning of backquotes. Right now, `x` is just
equivalent to x. Or would the new rule only be enabled inside getters / setters?

Lukas


On Thu, Aug 27, 2009 at 10:34, Carsten Saager <csaager [at] gmail [dot] com> wrote:
Why not using backticking to denote direct access to the var?

class A {
  var x: Int = 0
  def x_=(x1: Int) { `x` = abs(x1) }
  def x = `x`
}

-Carsten

On Thu, Aug 27, 2009 at 10:01 AM, Lukas Rytz <lukas [dot] rytz [at] epfl [dot] ch> wrote:


On Thu, Aug 27, 2009 at 03:25, Philip Köster <philip [dot] koester [at] web [dot] de> wrote:
> Yup, there's always a trade-off in any design :)

We're moving from a user posting to a language-specification request. With a bit of luck, Martin Odersky is listening.

Without further knowledge on the nitty-gritty but with some experience in parser generation, I think that overloading of intrinsic (i.e. auto-supplied) getter and setter method can be added to the Scala language without breaking existing code if these two conditions are fulfilled:

1. The SLS (= Scala Language Specification) documents the exact method signature and method bodies that derive from intrinsic auto-generation of getters and setters.

2. Overloading such methods matching the exact signature does not yield a compile-time error but has the intrinsic methods replaced by user-defined methods.

Given these two rules followed, it should be possible to overload compiler-generated getters and setters without incurrying that dreaded ``method defined twice.´´


We discussed exactly this proposal one week ago in our group meeting at EFPL. People agreed
that this would be a handy feature, but the problem is (as noted by Rex Kerr): there's no way to
access the underlying field directly, every access goes through the getter or setter.

class A {
  var x: Int = 0
  def x_=(x1: Int) { <x-the-field> = abs(x1) }
}

Writing "x = abs(x1)" is a recursive call to the setter.
If somebody has a proposal to access <x-the-field> we're all ears! :)

Lukas



Kevin Wright
Joined: 2009-06-09,
User offline. Last seen 49 weeks 4 days ago.
Re: Name Collisions With Private Fields and Public Getters/Set
Most scenarios I can imagine where a simple field access is being wrapped with richer functionality (i.e. logging), it's usually easier to think in terms of the entire object being wrapped and not just the field.
In this case, we already have a valid solution through mixins - where it makes perfect sense to override a synthetic getter or setter with a custom method and use super instead of directly accessing the underlying field.


On Thu, Aug 27, 2009 at 11:41 AM, Carsten Saager <csaager [at] gmail [dot] com> wrote:
Well, backticks is just an abuse as this character is not used otherwise. Perhaps ''`def`` and ''x is clearer (two single-quotes, easier to type).

Limiting the direct access to (g|s)etters is perhaps OK, but I think accessing ''x from a subclass might be useful for implementing overrides of the getter and setter

-Carsten

On Thu, Aug 27, 2009 at 11:36 AM, Lukas Rytz <lukas [dot] rytz [at] epfl [dot] ch> wrote:
Is problematic when the identifier needs to be backquoted.

class A {
  var `def`: Int = 0
  def def_=(d: Int) = { `def` = abs(d) }
}

It would also change the meaning of backquotes. Right now, `x` is just
equivalent to x. Or would the new rule only be enabled inside getters / setters?

Lukas


On Thu, Aug 27, 2009 at 10:34, Carsten Saager <csaager [at] gmail [dot] com> wrote:
Why not using backticking to denote direct access to the var?

class A {
  var x: Int = 0
  def x_=(x1: Int) { `x` = abs(x1) }
  def x = `x`
}

-Carsten

On Thu, Aug 27, 2009 at 10:01 AM, Lukas Rytz <lukas [dot] rytz [at] epfl [dot] ch> wrote:


On Thu, Aug 27, 2009 at 03:25, Philip Köster <philip [dot] koester [at] web [dot] de> wrote:
> Yup, there's always a trade-off in any design :)

We're moving from a user posting to a language-specification request. With a bit of luck, Martin Odersky is listening.

Without further knowledge on the nitty-gritty but with some experience in parser generation, I think that overloading of intrinsic (i.e. auto-supplied) getter and setter method can be added to the Scala language without breaking existing code if these two conditions are fulfilled:

1. The SLS (= Scala Language Specification) documents the exact method signature and method bodies that derive from intrinsic auto-generation of getters and setters.

2. Overloading such methods matching the exact signature does not yield a compile-time error but has the intrinsic methods replaced by user-defined methods.

Given these two rules followed, it should be possible to overload compiler-generated getters and setters without incurrying that dreaded ``method defined twice.´´


We discussed exactly this proposal one week ago in our group meeting at EFPL. People agreed
that this would be a handy feature, but the problem is (as noted by Rex Kerr): there's no way to
access the underlying field directly, every access goes through the getter or setter.

class A {
  var x: Int = 0
  def x_=(x1: Int) { <x-the-field> = abs(x1) }
}

Writing "x = abs(x1)" is a recursive call to the setter.
If somebody has a proposal to access <x-the-field> we're all ears! :)

Lukas




ijuma
Joined: 2008-08-20,
User offline. Last seen 22 weeks 3 days ago.
Re: Name Collisions With Private Fields and Public Getters/Sett

Hi,

On Thu, 2009-08-27 at 12:07 +0100, Kevin Wright wrote:
> Most scenarios I can imagine where a simple field access is being
> wrapped with richer functionality (i.e. logging), it's usually easier
> to think in terms of the entire object being wrapped and not just the
> field.

A very common scenario is when you want to add some validation on the
setter, so not sure I agree with that statement.

Best,
Ismael

Joshua.Suereth
Joined: 2008-09-02,
User offline. Last seen 32 weeks 6 days ago.
Re: Name Collisions With Private Fields and Public Getters/Set
var,val and def all share the same namespace (i.e. they all become methods).   This can catch you unawares when coming from a language like java.  However it does have a lot of benefits.

You can override an abstract def with a val or lazy-val (which happens quite frequently).

Anyway, I'd recommend making sure your variables and methods use different names.

On Thu, Aug 27, 2009 at 4:34 AM, Carsten Saager <csaager [at] gmail [dot] com> wrote:
Why not using backticking to denote direct access to the var?

class A {
  var x: Int = 0
  def x_=(x1: Int) { `x` = abs(x1) }
  def x = `x`
}

-Carsten

On Thu, Aug 27, 2009 at 10:01 AM, Lukas Rytz <lukas [dot] rytz [at] epfl [dot] ch> wrote:


On Thu, Aug 27, 2009 at 03:25, Philip Köster <philip [dot] koester [at] web [dot] de> wrote:
> Yup, there's always a trade-off in any design :)

We're moving from a user posting to a language-specification request. With a bit of luck, Martin Odersky is listening.

Without further knowledge on the nitty-gritty but with some experience in parser generation, I think that overloading of intrinsic (i.e. auto-supplied) getter and setter method can be added to the Scala language without breaking existing code if these two conditions are fulfilled:

1. The SLS (= Scala Language Specification) documents the exact method signature and method bodies that derive from intrinsic auto-generation of getters and setters.

2. Overloading such methods matching the exact signature does not yield a compile-time error but has the intrinsic methods replaced by user-defined methods.

Given these two rules followed, it should be possible to overload compiler-generated getters and setters without incurrying that dreaded ``method defined twice.´´


We discussed exactly this proposal one week ago in our group meeting at EFPL. People agreed
that this would be a handy feature, but the problem is (as noted by Rex Kerr): there's no way to
access the underlying field directly, every access goes through the getter or setter.

class A {
  var x: Int = 0
  def x_=(x1: Int) { <x-the-field> = abs(x1) }
}

Writing "x = abs(x1)" is a recursive call to the setter.
If somebody has a proposal to access <x-the-field> we're all ears! :)

Lukas


ichoran
Joined: 2009-08-14,
User offline. Last seen 2 years 3 weeks ago.
Re: Name Collisions With Private Fields and Public Getters/Set


On Thu, Aug 27, 2009 at 4:01 AM, Lukas Rytz <lukas [dot] rytz [at] epfl [dot] ch> wrote:
class A {
  var x: Int = 0
  def x_=(x1: Int) { <x-the-field> = abs(x1) }
}

Writing "x = abs(x1)" is a recursive call to the setter.
If somebody has a proposal to access <x-the-field> we're all ears! :)

You should only be able to do this with final classes anyway.  If it's a non-final class, what if the subclass wants to override the getter?  Or is the idea to only allow access to field as an lvar?  You then could overload the "with" keyword:

class A {
  var x:Int = 0 with { abs(_) }
  var y:Int = 0 with { i => abs(i) - min(x,i) }
}

Shorthand for:

class ALongwindedExample {
  private var hidden_x,hidden_y = 0
  def x = hidden_x
  def x_=(i:Int) { hidden_x = abs(i) }
  def y = hidden_y
  def y_=(i:Int) { hidden_y = abs(i) - min(x,i) }
}

And you could allow the extra-short form:

class A(var x:Int with { abs(_) }, var y:Int with { i=>i*i }) {
}

  --Rex

Kevin Wright
Joined: 2009-06-09,
User offline. Last seen 49 weeks 4 days ago.
Re: Name Collisions With Private Fields and Public Getters/Set
On Thu, Aug 27, 2009 at 12:27 PM, Ismael Juma <mlists [at] juma [dot] me [dot] uk> wrote:
A very common scenario is when you want to add some validation on the setter, so not sure I agree with that statement.

I think this is a classic case for adding validation at the object level.  If you're validating one property then chances are that you'll want to validate them all!
i.e.case class Customer(name: String)
class ValidatingCustomer(name: String) extends Customer {  def name_=(newName : String) =    if (newName.length < 5) error("too short")     else super.name_=(newName)}
val cust = new ValidatingCustomer("xyz123")
ijuma
Joined: 2008-08-20,
User offline. Last seen 22 weeks 3 days ago.
Re: Name Collisions With Private Fields and Public Getters/Sett

On Thu, 2009-08-27 at 14:13 +0100, Kevin Wright wrote:
> On Thu, Aug 27, 2009 at 12:27 PM, Ismael Juma
> wrote:
> A very common scenario is when you want to add some validation
> on the setter, so not sure I agree with that statement.
>
> I think this is a classic case for adding validation at the object
> level. If you're validating one property then chances are that you'll
> want to validate them all!

Not really. And even if it were, your solution implies that a Customer
without validation is actually useful. In many cases, it isn't. So we're
increasing the API surface for no benefit. Further, people now have to
check both classes to understand the code where one would do.

Note that I am not saying that the suggested solution does not make
sense in some cases, just that it's unnecessarily heavy for the common
case of adding some validation to a setter.

Best,
Ismael

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