cellio: (avatar)
[personal profile] cellio
One of these years I may make a real effort to compile some of what I do into the beginnings of "Tech-Writing Pearls", but for now all I'm doing is stashing stuff away when I realize I've written something that could be fodder later. Like now. :-)

On an API-documentation list someone asked about verb choice for access methods -- "returns", "gets", "retrieves", "queries", and so on.



I strive to be very careful to expose the correct amount of implementation in the documentation. That is, sometimes we only want to promise that we return a value somehow. Other times, we want to convey to the user that a new computation (e.g. a database query) is happening, which should affect the conditions under which he calls the method. So, using a word that implies computation when we're promising not to compute actually makes things worse.

I use "returns" almost universally. If we're actually computing or fetching a value, and this behavior is part of the interface specification, I'll say that, but I'll also try to get the programmers to name the method something other than "getFoo" in that case, too.

I view the method itself as the subject of the sentence, so I dislike "gets" because that's not what the method does. Your code is getting a value by calling the method, but the method does not "get", it "returns" or "provides access to". This may seem like excessive anal-retentiveness, but there can be cases elsewhere in an interface where it is not at all clear where the work gets done, and I find that if I am stubbornly consistent about using verbs that apply to the method (rather than the caller), I can reduce the potential for confusion elsewhere. My readers can learn the pattern if there is a pattern.



Update: I intended to focus here on what to say in the documentation, and not how to design the API, but I probably didn't make that clear enough before. Sorry 'bout that.

(no subject)

Date: 2003-07-22 11:30 am (UTC)
geekosaur: orange tabby with head canted 90 degrees, giving impression of "maybe it'll make more sense if I look at it this way?" (Default)
From: [personal profile] geekosaur
Your code is getting a value by calling the method, but the method does not "get", it "returns" or "provides access to".

Sadly, that's fighting an uphill battle against pretty much every C++ book and C++ instructor I've ever seen or heard of; students are regularly abjured to name the accessor for foo getFoo, and code generators from the GPLed Glade to IBM's VisualAge product line follow the same convention.

(no subject)

Date: 2003-07-22 01:31 pm (UTC)
From: [identity profile] tangerinpenguin.livejournal.com
Likewise the Java world; I think getFoo() (often with the addition of isFoo() for predicates) and setFoo() have become so well-known that you may be losing more immediate comprehension by defying the convention than you gain by more strictly expressive language.

(no subject)

Date: 2003-07-22 01:49 pm (UTC)
From: [identity profile] tangerinpenguin.livejournal.com
I strive to be very careful to expose the correct amount of implementation in the documentation. That is, sometimes we only want to promise that we return a value somehow. Other times, we want to convey to the user that a new computation (e.g. a database query) is happening, which should affect the conditions under which he calls the method.

In what cases is this more true for a specific method, rather than being something derived from the class or the context? In general, I see a danger here of tying the interface too much to the implementation - given subsequent changes "under the hood", a computation that initially seemed heavy-weight might become trivial, or vice versa, but at that point it's been enshrined into a method name that's distributed throughout existing code.

In practice, I tend to get the same semantic value from the context provided by the class: I assume that getFoo() (or returnFoo() :-)) on classes in the DB layer are going to be doing some sort of database hit (possibly optimizing through caching somehow), that the same call on an EJB has attendant RMI overhead, the same call on a value object or simple databean is (probably) pulling it off a local attribute, and the same call on a Business Object may be fronting any of the above (this week...) and my business logic is the wrong place to be worried about it.

And, further, that there are maintainence advantages to having all of the above implement (under Java or the like) one interface that specifies the same data contract crossing the physical layers of the application.

Ah...

Date: 2003-07-22 02:11 pm (UTC)
From: [identity profile] tangerinpenguin.livejournal.com
OK, "my bad" not reading it correctly (can you tell I've been working a lot this week with "principles of API design" and "layered architectures" and "developing to the interface"? :-)). Yes, I can fall in behind this point much more easily: if there are any interesting constraints posed by the implementation, they need to be documented for the class where they're implemented.

As a bonus, automation works for you in the case of "get" versus "return" - Javadoc documents the return value for everything using "return" (although you ought to explicitly use the @return tag to give a useful description rather than just letting it say "returns something of type long")

Expand Cut Tags

No cut tags