12

Apart from unambiguous clarity, why should we stick to:
car.getSpeed() and car.setSpeed(55)
when this could be used as well : car.speed() and car.speed(55)

I know that get() and set() are useful to keep any changes to the data member manageable by keeping everything in one place.

Also, obviously, I understand that car.speed() and car.speed(55) are the same function, which makes this wrong, but then in PHP and also in Zend Framework, the same action is used for GET, POST, postbacks.
In VB and C# there are "properties", and are used by many, much to the disgust of purists I've heard, and there are things in Ruby like 5.times and .each, .to_i etc.
And you have operator overloading, multiple inheritance, virtual functions in C++, certain combinations of which could drive anyone nuts.

I mean to say that there are so many paradigms and ways in which things are done that it seems odd that nobody has tried the particular combination that I mentioned.

As for me, my reason is that it is short and cleaner to read the code.
Am I very wrong, slightly wrong, is this just odd and so not used, or what else?

If I still decide to stay correct, I could use car.speed() and car.setSpeed(55).
Is that wrong in any way (just omitting the "get" )?

Thanks for any explanations.

crowne
  • 8,456
  • 3
  • 35
  • 50
namespaceform
  • 690
  • 1
  • 6
  • 14
  • "in PHP and also in Zend Framework, the same action is used for GET, POST, postbacks." lolwut – BlueRaja - Danny Pflughoeft Jan 12 '10 at 19:34
  • 8
    jQuery actually follows your proposed syntax. `$('.foo').val()` and `$('.foo').val(5)` – Joel Mueller Jan 12 '10 at 19:37
  • @Joel: In lighter vein, IMO, we are in general so sick of Javascript and browser compatibility, that many of us are willing to let go of our coding convention religions and follow the jQuery style of doing things just because it saves so many other troubles that sticking to a few conventions against our religions is a much better choice than not using jQuery / Scriptaculous / YUI etc. So it's more of a cost/benefit ;-) – namespaceform Jan 12 '10 at 19:56
  • 2
    @BlueRaja: lolwut is a content-free reply :-) 1. The disclaimers were in place. 2. This is not slashdot :-) – namespaceform Jan 12 '10 at 19:57
  • 1
    Would you have preferred "Whatchu talkin' 'bout?" As far as I know, that is not true in any respect. – BlueRaja - Danny Pflughoeft Jan 12 '10 at 20:39
  • There is a car-analogy tag??? With one follower???? – augustin May 30 '12 at 06:33

12 Answers12

10

If I called car.speed(), I might think I am telling the car to speed, in other words to increase speed and break the speed limit. It is not clearly a getter.

Some languages allow you to declare const objects, and then restrict you to only calling functions that do not modify the data of the object. So it is necessary to have seperate functions for modification and read operations. While you could use overloads on paramaters to have two functions, I think it would be confusing.

Also, when you say it is clearer to read, I can argue that I have to do a look ahead to understand how to read it:

car.speed()

I read "car speed..." and then I see there is no number so I revise and think "get car speed".

car.getSpeed()

I read "for this car, get speed"

car.setSpeed(55)

I read "for this car, set speed to 55"

It seems you have basically cited other features of the language as being confusing, and then used that as a defense for making getters/setters more confusing? It almost sounds like are admitting that what you have proposed is more confusing. These features are sometimes confusing because of how general purpose they are. Sometimes abstractions can be more confusing, but in the end they often serve the purpose of being more reusable. I think if you wanted to argue in favor of speed() and speed(55), you'd want to show how that can enable new possibilities for the programmer.

On the other hand, C# does have something like what you describe, since properties behave differently as a getter or setter depending on the context in what they are used:

Console.WriteLine(car.Speed); //getter

car.Speed = 55 //setter

But while it is a single property, there are two seperate sections of code for implementing the getting and setting, and it is clear that this is a getter/setter and not a function speed, because they omit the () for properties. So car.speed() is clearly a function, and car.speed is clearly a property getter.

AaronLS
  • 37,329
  • 20
  • 143
  • 202
  • 4
    **"If I called car.speed(), I might think I am telling the car to speed, in other words to increase speed and break the speed limit. It is not clearly a getter."** - That explains it prefectly. It is indeed confusing if you think of it that way. My aim was to be "short and sweet", but if it can be misunderstood half the time, it's a *new problem, not a solution* :-) – namespaceform Jan 12 '10 at 19:48
  • 3
    If I see "car.speed()" I see a method. If I see "int speed = car.speed()" I see a getter. – CaffGeek Jan 12 '10 at 19:52
  • 1
    To clarify, it will be very difficult to keep track of which member name sounds like a method name, and to prevent that the price to pay is just a "get", which is quite fine. – namespaceform Jan 12 '10 at 20:01
  • 2
    This answer is specific to the word "speed", because it is both a verb and a noun. Replace "speed" which is something that is just a noun, and it no longer applies. – Terry Mahaffey Jan 12 '10 at 20:25
  • 1
    @Terry, the example I gave was to illustrative of the problems that could result from the proposed naming convention. Why do we often use camel case in case sensitive languages, and underscores in case insensitive languages? There are several reasons, but one is because without those conventions, identifiers like "therapist" might be confused with "The Rapist". So my answer was not specific to the word "speed". That was simply an example of the type of problem that is avoided by the convention of prepending get* and set*. You have to learn to generalize examples or you miss the point. – AaronLS Jan 13 '10 at 01:05
  • IMO, this is an argument for proper API documentation, and not one against the get-set style per se. There's only a level of descriptiveness you can reach with method naming without resorting to unreadable long method names. – Gerry Nov 21 '12 at 04:36
8

IMHO the C# style of having properties as syntatic sugar for get and set methods is the most expressive.

Otávio Décio
  • 73,752
  • 17
  • 161
  • 228
4

I prefer active objects which encapsulate operations rather than getters and setters, so you get a semantically richer objects.

For example, although an ADT rather than a business object, even the vector in C++ has paired functions:

size_type capacity() const // how many elements space is reserved for in the vector  
void reserve(size_type n)  // ensure space is reserved for at least n elements 

and

void push_back ( const T& ) // inserts an element at the end
size_type size () const     // the number of elements in the vector

If you drive a car, you can set the accelerator, clutch, brakes and gear selection, but you don't set the speed. You can read the speed off the speedometer. It's relatively rare to want both a setter and a getter on an object with behaviour.

Pete Kirkham
  • 48,893
  • 5
  • 92
  • 171
  • **+1** That's a nice way of designing. Also, it does not give any unnecessary freedom to the calling code and is probably a more secure way of designing an API or classes that others just need to use, rather than modify. – namespaceform Jan 12 '10 at 20:13
3

FYI, Objective-C uses car.speed() and car.setSpeed(55) (except in a different syntax, [car speed] and [car setSpeed:55].

It's all about convention.

kennytm
  • 510,854
  • 105
  • 1,084
  • 1,005
3

There is no right answer, it's a matter of style, and ultimately it does not matter. Spend your brain cycles elsewhere.

FWIW I prefer the class.noun() for the getter, and class.verb() for the setter. Sometimes the verb is just setNoun(), but other times not. It depends on the noun. For example:

my_vector.size() 

returns the size, and

my_vector.resize(some_size) 

changes the size.

Terry Mahaffey
  • 11,775
  • 1
  • 35
  • 44
1

The groovy approach to properties is quite excellent IMHO, http://groovy.codehaus.org/Groovy+Beans

Kallin Nagelberg
  • 989
  • 8
  • 17
1

The final benchmarks of your code should be this:

  1. Does it work correctly?
  2. Is it easy to fix if it breaks?
  3. Is it easy to add new features in the future?
  4. Is it easy for someone else to come in and fix/enhance it?

If those 4 points are covered, I can't imagine why anybody would have a problem with it. Most of the "Best Practices" are generally geared towards achieving those 4 points.

Use whichever style works for you, just be consistent about it, and you should be fine.

rossipedia
  • 56,800
  • 10
  • 90
  • 93
1

This is just a matter of convention. In Smalltalk, it's done the way you suggest and I don't recall ever hearing anybody complain about it. Getting the car's speed is car speed, and setting the car's speed to 55 is car speed:55.

If I were to venture a guess, I would say the reason this style didn't catch on is because of the two lines down which object-oriented programming have come to us: C++ and Objective-C. In C++ (even more so early in its history), methods are very closely related to C functions, and C functions are conventionally named along the lines of setWhatever() and do not have overloading for different numbers of arguments, so that general style of naming was kept. Objective-C was largely preserved by NeXT (which later became Apple), and NeXT tended to favor verbosity in their APIs and especially to distinguish between different kinds of methods — if you're doing anything but just accessing a property, NeXT wanted a verb to make it clear. So that became the convention in Cocoa, which is the de facto standard library for Objective-C these days.

Chuck
  • 234,037
  • 30
  • 302
  • 389
1

It's convention Java has a convention of getters and setters C# has properties, python has public fields and JavaScript frameworks tend to use field() to get and field(value) to set

RHicke
  • 3,494
  • 3
  • 23
  • 23
0

Apart from unambiguous clarity, why should we stick to: car.getSpeed() and car.setSpeed(55) when this could be used as well : car.speed() and car.speed(55)

Because in all languages I've encountered, car.speed() and car.speed(55) are the same in terms of syntax. Just looking at them like that, both could return a value, which isn't true for the latter if it was meant to be a setter.

Jon Seigel
  • 12,251
  • 8
  • 58
  • 92
0

What if you intend to call the setter but forget to put in the argument? The code is valid, so the compiler doesn't complain, and it doesn't throw an immediate runtime error; it's a silent bug.

Justin
  • 1
0

.() means it's a verb. no () means it's a noun.

   car.Speed = 50;
   x = car.Speed
   car.Speed.set(30)
   car.setProperty("Speed",30)

but

   car.Speed()

implies command to exceed speed limit.

SF.
  • 13,549
  • 14
  • 71
  • 107