Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid

•Re: Re: Re: Re: Re: Re: What should be returned in scalar context? (best practice)

by merlyn (Sage)
on Dec 22, 2003 at 02:43 UTC ( #316291=note: print w/replies, xml ) Need Help??

in reply to Re: Re: Re: Re: Re: What should be returned in scalar context? (best practice)
in thread What should be returned in scalar context?

"returns an array" would be confusing to me, since it's not possible. Well, except maybe in an "lvalue" context.

An array is a container, holding a list. You can't return containers. Only values. Scalar value is to scalar variable what list is to array. You can no more return a scalar variable than you can return an array.

Put another way, you can't take a reference to a list, only to an array. And yet you can't take a reference to the return value of a subroutine. You have to construct an anonymous array (a new container) to hold the value.

These are not just implementation issues. These are user-visible concepts, and affect your behavior if you have the proper model.

Your casual conversation may make sense to you, but you'll confuse your reader. And the point of communication is to communicate for the reader, not just for your own notes.

-- Randal L. Schwartz, Perl hacker
Be sure to read my standard disclaimer if this is a reply.

  • Comment on •Re: Re: Re: Re: Re: Re: What should be returned in scalar context? (best practice)

Replies are listed 'Best First'.
Re: •Re: Re: Re: Re: Re: Re: What should be returned in scalar context? (best practice)
by sauoq (Abbot) on Dec 22, 2003 at 10:29 UTC
    Your casual conversation may make sense to you, but you'll confuse your reader.

    My point is not a casual one even if my explanation has failed to be as clear as I would like. Allow me to try to explain it to you as it is fundamentally about documentation, and your skill at technical writing is unquestionable.

    When I document that a sub of mine "returns an array", I mean very specifically that the expression supplied to return() (be it explicit or implicit) is an array.

    My use of the word "return" corresponds directly to the Perl keyword "return" without trying to describe what return() itself actually does. This is a considered choice, not laziness or lack of understanding.

    The behavior of return() is not within my purview. Isn't it to my own benefit to avoid describing it? Don't I, in fact, have a responsibility to yield to its proper documentation?

    Granted this is unlikely, but for the sake of argument consider the possibility of return()'s behavior changing. Imagine that a boolean context and a couple boolean values are added to the language. (Yes, it is a ridiculous notion but bare with me.) By not attempting to enumerate every context in the first place, haven't I insulated my own documentation from the change and avoided the need for edits?

    I believe this to be a fine documentation strategy. It is simple and allows me to be brief, describe the code itself, and communicate exactly what to expect. It avoids redundancy and protects the documentation, the published interface, from outside changes. It ignores the sometimes sticky issue of context which, really, should not have to reappear in every function's documentation. For these reasons, I will continue to use it.

    The one concern that I do have is that it seems several people are confused by it. I find this disconcerting as it is really quite simple. My only explanation is that many people are either too focused on their knowledge of Perl's inner workings or are hung up on documenting their own functions like Perl builtins. (Builtins aren't coded in Perl and hence, it wouldn't make sense to refer to the return keyword in their documentation; this is true of XS code as well.) Whatever the case, this kind of confusion seems to be prevalent wherever lists and list context are discussed. Maybe people still aren't comfortable with the concepts and want to be reminded of the specifics at every turn.

    "My two cents aren't worth a dime.";
      Saying it "returns an array", simply because you see the tokens for "return" and an array name, is like saying "assigns an array" in the statement "$foo = @bar".

      You are ignoring semantics, completely focussing on syntax. You are not describing what it does, you are describing the text of your source code.

      When you do that, you might as well leave all descriptions off, and let the reader go find the source for themselves.

      I find documentation much clearer when I describe what things do. Not what they are.

      It does not return an array. It can't. Writing "return @array" does not return an array.

      I'll hope not to run across your style of mis-documentation in any place other than the Monestary. It will frustrate me and my clients and my students.

      -- Randal L. Schwartz, Perl hacker
      Be sure to read my standard disclaimer if this is a reply.

        Conversely, in the handbook for a new phone, it says:

        If the other party's line is engaged, you will hear the engaged signal. When this happens, you should either hang up and try again later, or if you have ringback....

        It doesn't say,

        the exchange will periodically excite electrons that will be organised into a directional flow along the wires that will in turn, form a transient magnetic field within the coil in the earpiece which will in turn motivate a soft iron mass attached to a cone of rubberised paper to oscillate back and forth with the result that air pressure waves will be directed towards the tympanic membrane within your ear thus stimulating cilia within basilar membrane to generate tiny bio-electric impulses that are carried by the nervous system to the brain.

        It doesn't even say

        You will hear a square wave patterned audio signal with a frequency of 2 hertz and a duty cycle of 0.8 and an underlying carrier wave frequency of 1000 Hz.

        The reason is that the first conveys way to much information, most of which is technically accurate, but entirely redundant, and by it's bulk and detail, simply confusing. Whilst the second, even if re-couched in terms of "you will here a low regular pulsing sound" or similar, is still a problem as the engaged tone you hear is likely to vary depending upon such things as the location of the phone you are calling, home or overseas. The system the number you are calling is allocated on, land line, mobile, satellite. The phone itself is probably sold into many different market around the world.

        The documentation therefore refers to certain high-level concepts and defers the explanation of these to other sources.

        In the case of a perl sub, it always returns a list. This is understood. However, the way that list behaves in the calling code varies dependant upon whether the source of the list is an array, or a list. The results of a list in a scalar context and an array in a scalar context differ. Whether they should or not is a different discussion, but they do. The actual differences are well documented in elsewhere. However, it is important that the caller know which, an array or a list, is the source of the actual list returned, so that I may know how the sub will behave when called in a scalar context.

        The bottom line. As a user of a pre-written sub,

        1. I know that subs always return lists.
        2. I know how the behaviour of lists and arrays in a scalar context vary.

        I don't need (nor want) every module author to give me his or her explanation of either of these well-documented and understood features of perl. I only need them to tell me whether the source of the list returned by the sub is list or an array. With this information, I have the complete picture and can exactly predict how the sub will behave in either a list or scalar context.

        All I need is a statement of "the sub returns a list" or "the sub returns an array". All other information that might be documented is entirely inferable from one of these two statements.

        Except of course, what the list returned represents. But hey, a little trial and error... :)

        Examine what is said, not who speaks.
        "Efficiency is intelligent laziness." -David Dunham
        "Think for yourself!" - Abigail

        You are ignoring semantics, completely focussing on syntax.

        That's absolutely incorrect. Read my post again. I am relying on the semantics provided by Perl and on the fact that those semantics are already defined and documented. By doing so, I can be concise and precise while avoiding redundancy. Abstaining from redocumenting behavior which is not in my purview is a good thing.

        "My two cents aren't worth a dime.";

      I've decided that there's no changing your opinion on the matter. Despite the fact that four people have responded questioning your use of "returns an array", you have stood fast. You called my expectations of an arrayref in scalar context when you say "returns an array" as ridiculous and I certainly appreciate your input on the matter. It does show, however, that there's at least one idiot who reads "returns an array" this way. You state here that you can say "returns an array" and you won't need to update the documentation in the future. I mean no disrespect when I say that I read that as you intentionally use abstract terms and "golf" your documentation to lower the amount of maintainence needed. If this is the case, why bother at all? If you aren't going to properly describe your code in non-ambiguous terminology then what good does your documentation serve?

      But hey, I'm just a dimwit who believes "returns an array" means that the subroutine returns an arrayref in scalar context. =/

        If it helps any, you may offset me against, that list of 4, as one in total agreement with sauoq's position on this. So, 4:2. Any advance?

        It makes no sense whatsoever, that every piece of documentation, for every sub, in every module, that ever "returns an array", should have to repeatedly, re-document, re-clarify and re-explain the details of the consequences of this behaviour.

        It is already well docemented in the perl documentation. This is one of those things that everyone coming to perl for the first time, doesn't understand, falls foul of, perhaps rants against until they understand the efficacy of contextual behaviour, but then learns and understands.

        As for interpreting "returns an array", to mean "returns an array reference in a scalar context", I think that you called it on that one.

        Examine what is said, not who speaks.
        "Efficiency is intelligent laziness." -David Dunham
        "Think for yourself!" - Abigail

      My use of the word "return" corresponds directly to the Perl keyword "return" without trying to describe what return() itself actually does.

      That's where your mistake is.

      Consider that print 1 + 1; does not print 1 + 1. See how return @foo is not returning an array. Realise that split //, $foo is not splitting a regular expression. You can't just take syntax and use the same in English.

      Like I said before: if your documentation is there just to explain HOW your code works, then simply duplicate the code in a verbatim paragraph. Start documenting WHAT your code does. print 1 + 1; prints 2. return @foo returns either a list or a number of elements. Never an array. Just like how print @foo does not print an array and how with yoursub(@foo), yoursub never gets to use that array @foo. It receives a list (that is accessible through the special array @_, which not the array that was "passed").

      Juerd # { site => '', plp_site => '', do_not_use => 'spamtrap' }

        That's where your mistake is.

        It's not a mistake.

        Your analogies are incorrect. Would you document that print 1 + 1 "prints a list consisting of one element, '2'"? No, you'd say it "prints 2". What print() does is already documented. Your split "example" just stubbornly ignore the point.

        Like I said before

        Yeah, this whole post is what you said before. You fail to make any new points or to address the points I've made. If anyone "isn't getting it", it's you. And, hey! I thought that other post was going to be your last one on the subject.

        "My two cents aren't worth a dime.";

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://316291]
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others taking refuge in the Monastery: (5)
As of 2018-04-21 20:14 GMT
Find Nodes?
    Voting Booth?