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

Property accessors in Scala and DRY?

3 replies
Harmath Dénes
Joined: 2009-05-07,
User offline. Last seen 42 years 45 weeks ago.

Hi all,

though Scala's property mechanism (to access a mutable property, you
use obj.prop_= and obj.prop) is far better than the JavaBeans
approach. But I notice a violation of the DRY principle here: the
property name is redundant.
This not just hampers maintenance, but: given a property reference,
you cannot access the corresponding other setter/getter without
reflection.
Wouldn't it be good if this looked like, say, C#'s auto-implemented
properties? Why was this mechanism solved this way? Just wondering...

Cheers,
thSoft
http://thsoft.hu

extempore
Joined: 2008-12-17,
User offline. Last seen 35 weeks 3 days ago.
Re: Property accessors in Scala and DRY?

On Fri, Jun 05, 2009 at 01:27:28AM +0200, Harmath Dénes wrote:
> This not just hampers maintenance, but: given a property reference,
> you cannot access the corresponding other setter/getter without
> reflection. Wouldn't it be good if this looked like, say, C#'s
> auto-implemented properties? Why was this mechanism solved this way?
> Just wondering...

I have no answer, but I have been super annoyed by this lately! I wanted
to write a generic save-and-restore wrapper something like

def saving[T](x: T, body: => Unit) = {
val old: T = x.get
try { body } finally { x.set(old) }
}

...but I can't see how to do it without three parameters:

def saving[T](xGet: () => T, xSet: T => Unit, body: => Unit) ...

which is sufficiently inconvenient as to mostly defeat the purpose.

Arthur Peters
Joined: 2009-01-09,
User offline. Last seen 42 years 45 weeks ago.
Re: Property accessors in Scala and DRY?
I'm not all that experienced in this arena but I thought I'd throw in an idea.

Maybe properties as a language construct are a bad idea and instead there should be a Property class in the standard library that can be used something like this:

class A {
  val prop = new Property[Int]()
}

val o = new A
o.prop = 3
val i1 = o.prop()
val i2 : Int = o.prop // This works via an implicit conversion from Property[T] to T

However Property[T] could also be extended to implement observers or binding or whatever people wanted. Also the Property objects would be first class so you could pass them around and use them like you want to for your "saving" function. I'm not sure it is could be implemented as written. If you use "<=" instead of "=" to set the property it is easy to implement. I've pasted my code thoughts below.

The reason I think that built in property support might not be a good idea is that it is very unlikely to cover every use case and so people will still complain about it and have to implement JavaBean-ish solutions or something like what I am talking about here. The down side of my idea is that it creates another level of indirection and therefor will slow things down slightly at runtime (unless the compiler knows how to embed the Property instance in the class that uses it (Value type?))

-Arthur

object PropertyIdea {
    class Property1[T] {         
        def apply() : T = v    
        def update(_v:T) =  v=_v
        var v : T          
    }
    class Property2[T] {         
        def apply() : T = v    
        def <=(_v:T) =  v=_v
        var v : T          
    }
   
    implicit def Property2Val[T](p:Property2[T]) : T = p()

    def main(args : Array[String]) : Unit = {
            val p1 = new Property1[Int];
            p1()
            val v1 : Int = p1 //Does not compile as there is not implicit for it, but there could be
            p1 = 2 // does not compile because update is not called instead of = in this context
            val p2 = new Property2[Int]
            p2()
            val v2 : Int = p2
            p2 <= 2
    }
}



2009/6/4 Paul Phillips <paulp [at] improving [dot] org>
On Fri, Jun 05, 2009 at 01:27:28AM +0200, Harmath Dénes wrote:
> This not just hampers maintenance, but: given a property reference,
> you cannot access the corresponding other setter/getter without
> reflection. Wouldn't it be good if this looked like, say, C#'s
> auto-implemented properties? Why was this mechanism solved this way?
> Just wondering...

I have no answer, but I have been super annoyed by this lately! I wanted
to write a generic save-and-restore wrapper something like

 def saving[T](x: T, body: => Unit) = {
   val old: T = x.get
   try { body } finally { x.set(old) }
 }

...but I can't see how to do it without three parameters:

 def saving[T](xGet: () => T, xSet: T => Unit, body: => Unit) ...

which is sufficiently inconvenient as to mostly defeat the purpose.

--
Paul Phillips      | We must respect the other fellow's religion, but only
Imperfectionist    | in the sense and to the extent that we respect his
Empiricist         | theory that his wife is beautiful and his children smart.
pal, i pill push   |     -- H. L. Mencken

rodant
Joined: 2009-04-10,
User offline. Last seen 3 years 5 weeks ago.
Re: Property accessors in Scala and DRY?
Hello,

I can imagine this approach with a Property class, but there is another downside with it, I think. It assumes, the programmer of the class uses the property class to define his properties and not the build-in feature of Scala. And what about using Java beans with setters and getters?

I also has the same wish as Paul Phillips when I was making data binding from properties to SWT widgets. I also end up using a similar signature like:

def bind[T <: Any](setter: T => Unit, getter: () => T)(target: Control): DataBindingContext

What I would like to have, would be the possibility to refer to the property, and not the value, and then to be able to get the accessors:

bind(user.firstName)(control) or bind(user.firstName _)(control) //this doesn't work now

I don't wanna use a solution based on a String literal for the property name and the Java reflexion API. I would like to have compiler checks:

bind(user, "firstName")(control)

A kind of type save Scala reflexion would be needed, I think.

Cheers,
Antonio Rodríguez S.

2009/6/5 Arthur Peters <arthur [dot] peters [at] gmail [dot] com>
I'm not all that experienced in this arena but I thought I'd throw in an idea.

Maybe properties as a language construct are a bad idea and instead there should be a Property class in the standard library that can be used something like this:

class A {
  val prop = new Property[Int]()
}

val o = new A
o.prop = 3
val i1 = o.prop()
val i2 : Int = o.prop // This works via an implicit conversion from Property[T] to T

However Property[T] could also be extended to implement observers or binding or whatever people wanted. Also the Property objects would be first class so you could pass them around and use them like you want to for your "saving" function. I'm not sure it is could be implemented as written. If you use "<=" instead of "=" to set the property it is easy to implement. I've pasted my code thoughts below.

The reason I think that built in property support might not be a good idea is that it is very unlikely to cover every use case and so people will still complain about it and have to implement JavaBean-ish solutions or something like what I am talking about here. The down side of my idea is that it creates another level of indirection and therefor will slow things down slightly at runtime (unless the compiler knows how to embed the Property instance in the class that uses it (Value type?))

-Arthur

object PropertyIdea {
    class Property1[T] {         
        def apply() : T = v    
        def update(_v:T) =  v=_v
        var v : T          
    }
    class Property2[T] {         
        def apply() : T = v    
        def <=(_v:T) =  v=_v
        var v : T          
    }
   
    implicit def Property2Val[T](p:Property2[T]) : T = p()

    def main(args : Array[String]) : Unit = {
            val p1 = new Property1[Int];
            p1()
            val v1 : Int = p1 //Does not compile as there is not implicit for it, but there could be
            p1 = 2 // does not compile because update is not called instead of = in this context
            val p2 = new Property2[Int]
            p2()
            val v2 : Int = p2
            p2 <= 2
    }
}



2009/6/4 Paul Phillips <paulp [at] improving [dot] org>
On Fri, Jun 05, 2009 at 01:27:28AM +0200, Harmath Dénes wrote:
> This not just hampers maintenance, but: given a property reference,
> you cannot access the corresponding other setter/getter without
> reflection. Wouldn't it be good if this looked like, say, C#'s
> auto-implemented properties? Why was this mechanism solved this way?
> Just wondering...

I have no answer, but I have been super annoyed by this lately! I wanted
to write a generic save-and-restore wrapper something like

 def saving[T](x: T, body: => Unit) = {
   val old: T = x.get
   try { body } finally { x.set(old) }
 }

...but I can't see how to do it without three parameters:

 def saving[T](xGet: () => T, xSet: T => Unit, body: => Unit) ...

which is sufficiently inconvenient as to mostly defeat the purpose.

--
Paul Phillips      | We must respect the other fellow's religion, but only
Imperfectionist    | in the sense and to the extent that we respect his
Empiricist         | theory that his wife is beautiful and his children smart.
pal, i pill push   |     -- H. L. Mencken




--
Dr. Antonio R. Rodríguez Santiesteban
Java-Plattform-Entwickler

E-Mail: rodant68 [at] googlemail [dot] com

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