That would be great. -Jay
On Thu, May 31, 2012 at 11:22 AM, Joel Koshy <jjkosh...@gmail.com> wrote: > Agreed - if there are no objections, I can add this to our coding > conventions page. > > Joel > > On Wed, May 30, 2012 at 11:24 PM, Jay Kreps <jay.kr...@gmail.com> wrote: > > > Cool, so let's standardize on that approach then? > > > > -Jay > > > > On Wed, May 30, 2012 at 4:09 PM, Joel Koshy <jjkosh...@gmail.com> wrote: > > > > > Update - there must have been some stray classes lying around. > Actually, > > > only _= works. Also, we got some useful info from Chris Conrad: > > > > > > Basically for any declaration: > > > var x > > > > > > the scala compiler creates a (private[this] x_) along with a getter > (def > > x > > > = x_) and setter (def x_=(v) {x_=v}) - although the x_ is inaccessible > to > > > code > > > > > > So the def xyz_= and def xyz effectively create a synthetic var. > > > > > > We can actually go with public vals or vars - there is not much point > in > > > defining a custom getter/setter as that is redundant. > > > > > > For example: > > > - start with "val x" > > > - over time, we determine that it needs to be mutable - change it to > "var > > > x" > > > - if you need something more custom (e.g., enforce constraints on the > > > values that you can assign) then we can add the custom setter > > > private[this] var underyling: T = ... > > > def x = underlying > > > def x_=(update: T) { if (constraint satisfied) {underlying = update} > > > else {throw new Exception} } > > > > > > All of the above changes will be binary compatible since under the > > covers, > > > reads/assignments are all through getter/setter methods. > > > > > > Joel > > > > > > On Fri, May 25, 2012 at 4:58 PM, Joel Koshy <jjkosh...@gmail.com> > wrote: > > > > > > > Interesting - so according to that article, the _ is not operator > > > > overloading, rather it is a whitespace symbol: xyz_= means a method > > named > > > > "xyz =". > > > > > > > > However, that explanation appears to be incomplete, because all of > > these > > > > seem to work and I don't understand why: > > > > def xyz_=(x: Int) {underlying = x} > > > > def xyz_(x: Int) {underlying = x} > > > > def xyz_abc(x: Int) {underlying = x} > > > > > > > > o.xyz = ...; // works with all of the above > > > > > > > > If we are going with this convention, then it would be good to fully > > > > understand how it works. Also, if we need to access setters from Java > > we > > > > would need to provide an explicit setter. > > > > > > > > Thanks, > > > > > > > > Joel > > > > > > > > On Fri, May 25, 2012 at 2:29 PM, Jay Kreps <jay.kr...@gmail.com> > > wrote: > > > > > > > >> Yes, that's my understanding. This blog gives a reasonable overview: > > > >> http://www.dustinmartin.net/2009/10/getters-and-setters-in-scala/ > > > >> > > > >> Kind of sad that a year or so in we are just figuring this out, but > I > > > >> guess > > > >> better late then never. :-) > > > >> > > > >> -Jay > > > >> > > > >> On Fri, May 25, 2012 at 2:13 PM, Joel Koshy <jjkosh...@gmail.com> > > > wrote: > > > >> > > > >> > Personally, I like options 3 and 4. (Option 4 more than 3, but I'm > > not > > > >> sure > > > >> > I follow it correctly - and I did not know that shorthand for > > > >> overloading! > > > >> > So is this right:) > > > >> > > > > >> > class GetSetXYZ { > > > >> > private var underlying = 10 > > > >> > def xyz = underlying > > > >> > def xyz_=(x: Int) {underlying = x} > > > >> > } > > > >> > > > > >> > val o = new GetSetXYZ > > > >> > println(o.xyz) // 10 > > > >> > o.xyz=5 > > > >> > println(o.xyz) // 5 > > > >> > > > > >> > On Fri, May 25, 2012 at 10:17 AM, Jay Kreps <jay.kr...@gmail.com> > > > >> wrote: > > > >> > > > > >> > > Oh no, you are no using xyz_() you are overriding =. So you > define > > > >> > > xyz_=(x:Int) > > > >> > > but to call it you do > > > >> > > o.xyz = 5 > > > >> > > The reason this is nice is because you can start with a simple > > > >> > > var xyz > > > >> > > and not need any getter/setter. Then later when you need to > change > > > the > > > >> > > behavior of the get you make > > > >> > > def xyz = ... > > > >> > > and none of the calling code changes. Later still you decide you > > > need > > > >> to > > > >> > > override the setter you do > > > >> > > def xyz_=(x: Int)... > > > >> > > and that overrides o.xyz=5, again without changing the calling > > code. > > > >> > > > > > >> > > Basically the point is that scala generates these getters and > > > setters > > > >> no > > > >> > > matter what so you might as well use the official scala > mechanism. > > > >> > > > > > >> > > Since I am only semi-scala literate any of the above may be > wrong. > > > >> > > > > > >> > > -Jay > > > >> > > > > > >> > > On Fri, May 25, 2012 at 9:42 AM, Jun Rao <jun...@gmail.com> > > wrote: > > > >> > > > > > >> > > > I think separating out the getter and setter makes the > > > >> implementation > > > >> > > > cleaner. I am not sure how intuitive it is to use xyz_() as > the > > > >> setter, > > > >> > > > although it is concise. > > > >> > > > > > > >> > > > Thanks, > > > >> > > > > > > >> > > > Jun > > > >> > > > > > > >> > > > On Tue, May 22, 2012 at 9:13 PM, Jay Kreps < > jay.kr...@gmail.com > > > > > > >> > wrote: > > > >> > > > > > > >> > > > > We are a little inconsistent in our use of setters and > > getters. > > > I > > > >> > think > > > >> > > > for > > > >> > > > > the most part well-written code shouldn't have too many > > setters > > > >> and > > > >> > > > getters > > > >> > > > > (especially setters) since they expose internal details of > the > > > >> > object. > > > >> > > > But > > > >> > > > > sometimes you need them. I see three common conventions: > > > >> > > > > > > > >> > > > > 1. Java-style getXyz() and/or setXyz() method > > > >> > > > > 2. xyz() plus semantically named setter that describes > what > > it > > > >> > does. > > > >> > > > > 3. In some newer code I see xyz(x: Option[Int]) > > > >> > > > > > > > >> > > > > There is also a forth option. My understanding of the proper > > > scala > > > >> > > idiom > > > >> > > > > was actually that scala automatically created get and set > > > methods > > > >> for > > > >> > > > you, > > > >> > > > > and the appropriate thing to do is to override these. This > is > > > >> > described > > > >> > > > > here: > > > >> > > > > > > http://www.codecommit.com/blog/scala/scala-for-java-refugees-part-2 > > > >> > > > > > > > >> > > > > Essentially you can start with just > > > >> > > > > > > > >> > > > > val xyz = ... > > > >> > > > > > > > >> > > > > Then later if you want to override the getter you would do > > > >> > > > > > > > >> > > > > private val x = ... > > > >> > > > > > > > >> > > > > // getter > > > >> > > > > > > > >> > > > > def xyz = if(check_something) x else throw new > > > >> IllegalStateException > > > >> > > > > > > > >> > > > > Then if you also want to add a setter you do > > > >> > > > > > > > >> > > > > private val x = ... > > > >> > > > > > > > >> > > > > def xyz = if(check_something) x else throw new > > > >> IllegalStateException > > > >> > > > > def xyz_=(x: Int) {xyz = x} > > > >> > > > > > > > >> > > > > Let's pick one of these and refactor towards it as we see > code > > > >> that > > > >> > > > doesn't > > > >> > > > > match. My vote would be for option 4. > > > >> > > > > > > > >> > > > > -Jay > > > >> > > > > > > > >> > > > > > > >> > > > > > >> > > > > >> > > > > > > > > > > > > > >