Java Forum / General / October 2006
Method naming convention required
Xagyg - 20 Oct 2006 05:40 GMT In Ruby, a method that modifies the instance using it is suffixed with a '!'.
E.g. someString.reverse() returns a String with a reversed result, however, someString.reverse! reverses the result of someString.
Does anyone have/use/know of a method-naming convention in Java to distinguish between methods that modify the instance and methods that don't?
Feel free to suggest one if you like.
Xagyg - 20 Oct 2006 05:45 GMT > E.g. someString.reverse() returns a String with a reversed result, > however, someString.reverse! reverses the result of someString.
> reverses the result of someString. I meant "reverses someString" in-place.
Daniel Dyer - 20 Oct 2006 09:52 GMT >> E.g. someString.reverse() returns a String with a reversed result, >> however, someString.reverse! reverses the result of someString. > >> reverses the result of someString. > > I meant "reverses someString" in-place. I'm not aware of any naming convention like this in Java. However, if you are only concerned with Strings, it's impossible(*) to reverse them in place anyway since they are immutable.
[*] Almost.
Dan.
 Signature Daniel Dyer http://www.dandyer.co.uk
John W. Kennedy - 22 Oct 2006 04:16 GMT >>> E.g. someString.reverse() returns a String with a reversed result, >>> however, someString.reverse! reverses the result of someString. [quoted text clipped - 4 lines] > > I'm not aware of any naming convention like this in Java. It's a Rubyism.
 Signature John W. Kennedy "The blind rulers of Logres Nourished the land on a fallacy of rational virtue." -- Charles Williams. "Taliessin through Logres: Prelude"
Lasse Reichstein Nielsen - 23 Oct 2006 02:10 GMT > It's a Rubyism. It's a notation that has also been used in other, earlier, languages, e.g., Scheme. (set! x (integer? y)) ; read: set-bang x to integer-huh y :)
I don't know much about Ruby, but it seems they have stolen liberally from Scheme and probably also other languages.
/L 'Genious is stealing from the right people, plagarism is stealing from the wrong'
 Signature Lasse Reichstein Nielsen - lrn@hotpop.com DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleDOM.html> 'Faith without judgement merely degrades the spirit divine.'
John W. Kennedy - 23 Oct 2006 02:39 GMT >> It's a Rubyism. > [quoted text clipped - 4 lines] > I don't know much about Ruby, but it seems they have stolen liberally > from Scheme and probably also other languages. SmallTalk's "everything is an object" philosophy plus lambdas and closures from LISP plus some Ada syntax plus Perl's core functionality plus a mania for duck typing. I quite like it as a Perl replacement -- in fact, I ported all my personal Perl utilities to Ruby -- but I'm too old to accept the attitude of too many Rubyists that Ruby is a perfectly good replacement for Java or even C "because CPU time doesn't matter anymore".
 Signature John W. Kennedy "The blind rulers of Logres Nourished the land on a fallacy of rational virtue." -- Charles Williams. "Taliessin through Logres: Prelude"
Chris Uppal - 23 Oct 2006 09:54 GMT [We're getting way off-topic here, but what the hell ? It's only Monday...]
> > I don't know much about Ruby, but it seems they have stolen liberally > > from Scheme and probably also other languages. > > SmallTalk's "everything is an object" philosophy plus lambdas and > closures from LISP plus some Ada syntax plus Perl's core functionality > plus a mania for duck typing. Not only "everything is an object" from Smalltalk (note spelling) but Ruby's blocks are essentially the same (if you ignore some wierd chunkiness) as Smalltalk's. Mixins from CLOS (etc). Obfuscatory syntax from Perl (;-)...
> I quite like it as a Perl replacement -- > in fact, I ported all my personal Perl utilities to Ruby -- but I'm too > old to accept the attitude of too many Rubyists that Ruby is a perfectly > good replacement for Java or even C "because CPU time doesn't matter > anymore". I find it odd, too, that the Ruby (and some other scripty languages' enthusiasts) are so willing to claim it doesn't matter. I may be cynical, but I suspect that if they ever get decent VM technology (as has, of course, been available for /ages/ in languages with semantics at least as dynamic and flexible as Ruby's) then they'd suddenly start touting performance as a necessity, or at least as /highly/ desirable...
-- chris
Bent C Dalager - 24 Oct 2006 10:07 GMT >I find it odd, too, that the Ruby (and some other scripty languages' >enthusiasts) are so willing to claim it doesn't matter. I may be cynical, but >I suspect that if they ever get decent VM technology (as has, of course, been >available for /ages/ in languages with semantics at least as dynamic and >flexible as Ruby's) then they'd suddenly start touting performance as a >necessity, or at least as /highly/ desirable... I expect that for so long as Ruby is "slow", it gets used for tasks where slowness is acceptable and with this taken into account, the Rubyists would be quite correct: it doesn't matter if it's slow.
If Ruby should ever get a decent VM to speed it up, people would start using it for tasks where speed is important and when this happens, well, of course they will start claiming speed as desirable, because it will be :-)
(Disclaimer: I know next to nothing about Ruby and have no idea whether it actually _is_ slow or not.)
Cheers Bent D
 Signature Bent Dalager - bcd@pvv.org - http://www.pvv.org/~bcd powered by emacs
John W. Kennedy - 26 Oct 2006 05:22 GMT > (Disclaimer: I know next to nothing about Ruby and have no idea > whether it actually _is_ slow or not.) As a rough rule of thumb, it takes about 130%-150% as long to do something in Ruby as in Perl. There are exceptions, however. I wrote a set of perfect-number finders where Ruby is much, much faster than Perl, and also faster than Java (I suspect the BigInteger class in Java may need a tweak). GCLISP is faster than any of them.
 Signature John W. Kennedy "The blind rulers of Logres Nourished the land on a fallacy of rational virtue." -- Charles Williams. "Taliessin through Logres: Prelude"
Simon Brooke - 23 Oct 2006 17:35 GMT >> It's a Rubyism. > > It's a notation that has also been used in other, earlier, languages, > e.g., Scheme. > (set! x (integer? y)) ; read: set-bang x to integer-huh y :) And in earlier LISPs, predicate functions typically had names ending in P, as in CONSP.
 Signature simon@jasmine.org.uk (Simon Brooke) http://www.jasmine.org.uk/~simon/
;; Human history becomes more and more a race between ;; education and catastrophe. H.G. Wells, "The Outline of History"
Thomas Weidenfeller - 20 Oct 2006 09:58 GMT > Does anyone have/use/know of a method-naming convention in Java to > distinguish between methods that modify the instance and methods that > don't? The attribute setter/getter convention taken from the JavaBeans spec http://java.sun.com/j2se/1.5.0/docs/guide/beans/index.html is probably closest:
void setSomething(type value) type getSomething()
That convention is largely observed, even for non-JavaBean-compliant classes. One can argue it is even often overused.
Other stuff is defined chapter 10 of
http://java.sun.com/docs/codeconv/index.html
/Thomas
 Signature The comp.lang.java.gui FAQ: http://gd.tuwien.ac.at/faqs/faqs-hierarchy/comp/comp.lang.java.gui/ ftp://ftp.cs.uu.nl/pub/NEWS.ANSWERS/computer-lang/java/gui/faq
Xagyg - 20 Oct 2006 12:31 GMT > The attribute setter/getter convention taken from the JavaBeans spec > http://java.sun.com/j2se/1.5.0/docs/guide/beans/index.html is probably [quoted text clipped - 5 lines] > That convention is largely observed, even for non-JavaBean-compliant > classes. One can argue it is even often overused. I'll give another example. I want my Set class to have 2 "union" methods. The first method unions another set to the caller. The second one unions another set and returns a new set, but the caller is not modified.
e.g. this.union(s) modifies this, whereas the other version of this.union(s) does NOT modify this, it returns a new set containing the union of this and s. It might seem a little strange to have setUnion(s) and getUnion(s) since the set and get are actually doing extra processing ... not just setting and getting some object. I like the suggestion though - it is based on a sound principle. Not sure it feels right though.
Chris Uppal - 20 Oct 2006 13:22 GMT > I'll give another example. I want my Set class to have 2 "union" > methods. The first method unions another set to the caller. The second > one unions another set and returns a new set, but the caller is not > modified. Call the second union(), but don't call the first one that, since that's not what "union" means. If it fits with your framework then use the established name addAll() instead.
(addAll() is part of the contract defined by the java.util.Collection interface.)
A more general point: I think that one good way to distinguish between methods which modify the target object and those which answer a modified version is to (try to) follow the English pattern: verb/verbed. So that the string reversal example would have methods called reverse() (which modified the string in place), and reversed() which returned a reversed copy. Of course you can go beyond that into, say, beReversed() vs reversed(), or even reverse() vs copyReversed().
It's a bit unfortunate that there isn't a Lisp/Ruby style qualifier character available, but there isn't. And also there is no established convention, so we just have to do the best we can with well chosen method names (fighting the oddities of English grammar the while...)
-- chris
Xagyg - 20 Oct 2006 15:05 GMT > > I'll give another example. I want my Set class to have 2 "union" > > methods. The first method unions another set to the caller. The second [quoted text clipped - 22 lines] > > -- chris Nice post. Thanks. I'll work with something along these lines.
djthomp - 20 Oct 2006 23:30 GMT > e.g. this.union(s) modifies this, whereas the other version of > this.union(s) does NOT modify this, it returns a new set containing the [quoted text clipped - 3 lines] > suggestion though - it is based on a sound principle. Not sure it feels > right though. One approach would be to use static class methods for all of the functions that produce new objects.
i.e. Set.union(setA, setB)
Just a thought.
Xagyg - 22 Oct 2006 12:59 GMT > One approach would be to use static class methods for all of the > functions that produce new objects. > > i.e. Set.union(setA, setB) This is a reasonable approach and was my first thought. However, it makes chaining calls less obvious.
For example --
we want: r.domRes(tomSet).union(q).rangeRes(carSet).contains(?)
Using statics produces ugly chaining which is not the natural order of our query. Nice chaining requires use of object instances.
Ugly chaining (using statics):
assertTrue(Relation.rangeRestriction((Relation)Relation.domainRestriction(r,new Set("tom")).union(q),new Set("car")).contains(new Maplet("jane","car")));
Nice chaining:
assertTrue(((Relation)r.domainRestriction(new Set("tom")).union(q)).rangeRestriction(new Set("car")).contains(new Maplet("jane","car")));
Now, I have domainRestriction which returns a new object (i.e. no update to caller). And I have domainRestrict which updates the caller. Statics would allow naming them the same (since the signatures are different), but see problem immediately above.
I am thinking of using: domainRestriction for the no-update call, and something like restrictByDomain for the update call. Currently I have domainRestriction and domainRestrict which is probably too close.
If anyone is interested at looking further into the project, see http://sourceforge.net/projects/zedlib
Thanks for all the comments and ideas.
Thomas Hawtin - 20 Oct 2006 17:31 GMT > In Ruby, a method that modifies the instance using it is suffixed with > a '!'. [quoted text clipped - 5 lines] > distinguish between methods that modify the instance and methods that > don't? The convention is that mutable objects stick with methods that mutate themselves. Equivalent methods return results without modifying the source objects belong to immutables.
Tom Hawtin
Mark Rafn - 20 Oct 2006 18:45 GMT >> Does anyone have/use/know of a method-naming convention in Java to >> distinguish between methods that modify the instance and methods that >> don't? How I wish the language supported this! There's probably no reason not to add an annotation (@Const is probably too controversial, but @ReadOnly could work) to indicate methods that don't change any values.
>The convention is that mutable objects stick with methods that mutate >themselves. Equivalent methods return results without modifying the >source objects belong to immutables. Note that this convention is not universal, even within the JDK. StringBuilder, for instance, mutates and returns a copy itself for easy chaining of calls.
It's a good idea to follow it when you can, but there's no subsitute for understanding the API you're calling and knowing which methods read vs write. -- Mark Rafn dagon@dagon.net <http://www.dagon.net/>
Stefan Ram - 20 Oct 2006 21:08 GMT >How I wish the language supported this! There's probably no >reason not to add an annotation (@Const is probably too >controversial, but @ReadOnly could work) to indicate methods >that don't change any values. Support for this might be found to some extend in libraries, when the "value" (immutable) or "state system" (mutable) nature of objects is documented.
In my library, I have two package prefixes
de.dclj.ram.system...
packages with this prefix contain classes, whose instances model systems (i.e., mutable state systems).
de.dclj.ram.type....
packages with this prefix contain classes, whose instances model values (i.e., immutable values).
http://www.purl.org/stefan_ram/html/ram.jar/overview-frame.html
Mark Rafn - 21 Oct 2006 00:05 GMT > Support for this might be found to some extend in libraries, > when the "value" (immutable) or "state system" (mutable) > nature of objects is documented. Sure, I like immutable value objects when possible. Documenting this is fairly painless, and I haven't seen much need for conventions around it. The OP was asking about (and I agree with) how to determine which methods on a mutable object actually change the state. -- Mark Rafn dagon@dagon.net <http://www.dagon.net/>
Stefan Ram - 21 Oct 2006 02:55 GMT >The OP was asking about (and I agree with) how to determine >which methods on a mutable object actually change the state. This might be considered to be an implementation detail, which should not be visible to a client.
Why should a client programmer need to know this?
For example,
shape.rotate( a )
might rotate a shape around its center (of gravity) by the angle a.
After
Shape shape = new Rectangle();
"rotate" will change the state, while after
Shape shape = new Circle();
"rotate" might be a no-operation (not changing the state of its object). So "rotate" in the interface "Shape" can not be named to reflect both a state change and no state change.
Moreover, for certain values of a, like "0" or multiples of 360 degrees, "rotate( a )" may not change the state of a rectangle.
Or, when a method does not change the state of its object, but the state of a referenced object, should this considered to be a change of the state of the object, too?
Does
System.out.println( "a" );
change the state of the object "System.out"? If this is take to represent the console, the answer is "yes", because text is added to the console. However, the answer might be "no", if only the modification of primitve fields are considered to be a change.
Mark Rafn - 21 Oct 2006 23:08 GMT >>The OP was asking about (and I agree with) how to determine >>which methods on a mutable object actually change the state.
> This might be considered to be an implementation detail, > which should not be visible to a client. Not at all, it's a critical part of an API to know when an object will mutate.
>shape.rotate( a ) > might rotate a shape around its center (of gravity) by the > angle a. Knowing whether this returns a new Shape that is rotated or whether it mutates the given Shape is fairly important to the caller.
>Shape shape = new Rectangle(); > "rotate" will change the state, while after >Shape shape = new Circle(); > "rotate" might be a no-operation (not changing the state of Sure, but who cares? A mutator that happens not to need to do anything is harmless. It's the opposite that causes bugs: a method the caller thinks is non-state-changing but actually mutates.
> its object). So "rotate" in the interface "Shape" can not be > named to reflect both a state change and no state change. It is a state-changing method, clearly. Unless it is really a clone+rotate method that returns a new object.
> Does System.out.println( "a" ); change the state of the object "System.out"? Funny edge case, but easy to answer: no. There's nothing that System.out will do differently after calling println(). -- Mark Rafn dagon@dagon.net <http://www.dagon.net/>
Chris Uppal - 22 Oct 2006 12:54 GMT > > The OP was asking about (and I agree with) how to determine > > which methods on a mutable object actually change the state. > > This might be considered to be an implementation detail, > which should not be visible to a client. I have claimed before that "state" is not really something that belongs to an object in an OO system. That's to say that it's not an observable property of any object considered in isolation, but only of the system (or subsystem) as a whole.
So, although whether a given method changes the observable state of the system (or /might/ do so) is very definitely not an implementation detail, whether it changes the internal state of the receiving object itself /is/ an implementation detail.
So I would say that there's nothing at all wrong with wanting to indicate what a method does by proper choice of its name -- hell, that's what method names are /for/ ! -- but that the notion of "change" is subtle and should not be interpreted naively.
Note, btw, that whether a method is a mutator (in the above OO sense) is a property of a cluster of polymorphically interchangeable concrete methods. If only Circles have rotate() then there's something insane in the design; if rotate() is a method common to several shapes, then rotate() is a mutator even if the implementation in Circle happens to be a no-op.
-- chris
Doug Pardee - 20 Oct 2006 18:07 GMT > Does anyone have/use/know of a method-naming convention in Java to > distinguish between methods that modify the instance and methods that > don't? Not a naming convention, but a signature convention: If the method has a return value, it doesn't modify anything. If the method modifies anything, it doesn't have a return value.
This is called Command/Query Separation. CQS is generally considered to be a good thing to do, although there are a few isolated instances where there is real value in returning a value from a method that modifies things.
Virtually all programming languages prior to C strictly separated statements from expressions, subroutines from functions. C introduced side-effect functions, statement expressions, and expression statements, and derivative languages like Java have followed suit. But just because a language allows you to do something and doing so saves you ten keystrokes, that doesn't mean that it's a good idea in terms of code quality.
(Most languages couldn't actually stop you from putting a side effect into a function definition, but it wasn't something that was routinely done, particularly if there was a chance that the compiler might optimize the function calls.)
Patricia Shanahan - 20 Oct 2006 21:59 GMT ...
> Virtually all programming languages prior to C strictly separated > statements from expressions, subroutines from functions. C introduced > side-effect functions ... Is a Fortran function that modifies a common block a side-effect function?
Patricia
Doug Pardee - 23 Oct 2006 06:18 GMT > Is a Fortran function that modifies a common block a side-effect function? Of course. For that matter, a FORTRAN function could modify its parameters (call by reference and all that). Which is why I noted that "Most languages couldn't actually stop you from putting a side effect into a function definition". But in most cases it was discouraged because you didn't know what the compiler would do when optimizing the function calls; the compilers generally treated function calls as being idempotent and side-effect free.
But with C, side-effect functions became fully legitimized. The C standard library includes zillions (approximately) of intentional side-effect functions. Oh, and I shouldn't forget to mention the side-effect operators ++ and --. Then along came "const" to try to patch up some of the mess that got created.
That's all ancient history now, though. Java is what it is. But I still recommend separating the imperative from the applicative. Albeit with the occasional dalliance with the likes of the "pop" method for stacks.
Godspeed - 22 Oct 2006 14:44 GMT This approach wouldn't be so bad except for the case where the only difference between the methods is their return value. As you know, Java does not allow methods whose only diff is their return value.
Also, loads of Java classes return a value for modifying methods (e.g. Set.add returns true/false if the set was changed due to the operation)... however, I like your general idea/approach.
>> Does anyone have/use/know of a method-naming convention in Java to >> distinguish between methods that modify the instance and methods that [quoted text clipped - 21 lines] > done, particularly if there was a chance that the compiler might > optimize the function calls.) Xagyg - 23 Oct 2006 00:47 GMT > In Ruby, a method that modifies the instance using it is suffixed with > a '!'. [quoted text clipped - 7 lines] > > Feel free to suggest one if you like. One idea would be to prefix or suffix one of the methods with an underscore. I'll think about that too. Not sure which one.... Following Ruby, I could suffix the destructive method with an underscore.
e.g. Set union(Set s) - non-destructive - i.e. returns the result as a Set boolean union_ (Set s) - updates "this" (returns true if "this" set changed).
Xagyg - 23 Oct 2006 00:56 GMT > One idea would be to prefix or suffix one of the methods with an > underscore. I'll think about that too. Not sure which one.... Following [quoted text clipped - 4 lines] > boolean union_ (Set s) - updates "this" (returns true if "this" > set changed). Can we vote... use _ as suffix as per Ruby exclamation '!' or judicious use of method names?
e.g. Set union(Set s) boolean setUnionWith(Set s)
another e.g. of naming:
"Ruby" method: domainRestriction and domainRestriction_ "Name" method: domainRestriction and restrictDomainBy
?????
Votes?
Hendrik Maryns - 23 Oct 2006 10:20 GMT Xagyg schreef:
>> One idea would be to prefix or suffix one of the methods with an >> underscore. I'll think about that too. Not sure which one.... Following [quoted text clipped - 15 lines] > "Ruby" method: domainRestriction and domainRestriction_ > "Name" method: domainRestriction and restrictDomainBy Name.
H. - -- Hendrik Maryns http://tcl.sfs.uni-tuebingen.de/~hendrik/ ================== http://aouw.org Ask smart questions, get good answers: http://www.catb.org/~esr/faqs/smart-questions.html
Ed - 23 Oct 2006 11:12 GMT Xagyg skrev:
> > One idea would be to prefix or suffix one of the methods with an > > underscore. I'll think about that too. Not sure which one.... Following [quoted text clipped - 19 lines] > > Votes? .ed
Name.
Computer languages are complicated proportional to the number of non-alphanumeric characters they employ.
And yes, I'm looking at you, < and >.
-- www.EdmundKirwan.com - Home of The Fractal Class Composition.
Download Fractality, free Java code analyzer: www.EdmundKirwan.com/servlet/fractal/frac-page130.html
Chris Uppal - 23 Oct 2006 10:05 GMT > One idea would be to prefix or suffix one of the methods with an > underscore. I'll think about that too. Not sure which one.... Following > Ruby, I could suffix the destructive method with an underscore. If you want any of the following:
- your software to be used by other people;
- your software to be a good advertisement of your skills to potential employers;
- your own coding habits to be compatible with other people's;
then don't do it. Don't even /consider/ doing it.
Of course, you could follow Stefan's example and write your own code in (I mean no offence) "abnormal" Java, following whatever personal conventions you like, and use a preprocessor to create the public version of the code from that. Seems a lot of effort for little or no gain to me, but YMMV.
-- chris
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|