Hello monks.

I have not seen any discussion regarding this topic after a few searches, but it seem like a topic that must have been broached. Forgive me if my searches were not diligent enough.

One way that I try to maintain readability in my code (especially in projects involving multiple packages working together to perform associated tasks) is to give my subroutines readable, descriptive names. Given that any decent editor has some level of word completion these days, excessive keystrokes do not really pose an argument against this anymore.

A couple of examples of on of the funciton names that I'm using in a reporting package that I'm working on today are:
set_contact_source_type( $contact_id ); # where did the customer come + from? set_contact_pander_flags( $contact_id ); # how do they like to be cont +acted?

This style of naming subroutines becomes problematic when the subroutine is answering a yes or no question.
$answer = is_contact_male; # just doesn't look right. $answer = is_contact_female?; # Ahhh. Much better.

Is this something that other monks yearn for, or do you look at this code and say, "eek!"?


Thanks,
  Dug

Replies are listed 'Best First'.
Re: Question Marks in Subroutine Names
by belg4mit (Prior) on May 07, 2002 at 22:56 UTC
    ? in subroutine names seem like a bad idea, it adds amibguity. This is valid syntax:
    print is_contact_male?'zut':pickupLine;

    It seems like your style of coding might be better done in OO such as $obj->sex.

    --
    perl -pew "s/\b;([mnst])/'$1/g"

      It's not legal now, but it may well become so in perl 6 since ?: is becoming ??:: in order to free up the colon (Larry hasn't told us what's going to happen to the question mark, but I wouldn't have a problem with making it a valid character in an identifier. I'd love to be able to write
      given $employee { when male? {...} when female? {...} default { "Ooh... neuter"; ... } }
      I tend to think that 'question form' methods/functions sit best in a functional or objective programming style; they seem to jar slightly when you're writing procedural stuff. But that could just be me.

      Probably what will really happen is that Larry will show us some utterly clear and really useful trick that can be done with '?' as an operator and we'll gleefully use that and forget about using ?s in our identifiers.

        Eep. This style of subroutine naming would do my head in, I see the 'when male?' and the natural-language part of my brain takes that as a stand-alone sentance and asks something like "I don't know, when are they male?".

        It's the different between 'When raining, put on a coat' and 'When raining? Put on a coat'. The first sounds natural to me, and the second like a bad translation.

        Maybe my brain's wired wrongly though.

      if ($person->sex) { print "True sex\n"; } else { print "False sex\n"; }
      :)))
      And seriously, everybody has probably seen way too many boolean sex variables to understand that each if sex then construct confuses reader a lot.
      Hmm.
      This certainly doesn't effect the way that I think about the question that I posed. A subroutine declaration like sub sex { # do stuff }; won't exist in my style of coding. And you're telling me that I'm adding ambiguity? :-)
        hein? The sex method would return a value indiciating whether the object/individual was male or female.

        --
        perl -pew "s/\b;([mnst])/'$1/g"

Re: Question Marks in Subroutine Names
by jsprat (Curate) on May 07, 2002 at 22:39 UTC
    eek!!!!

    Seriously though, I'd leave the punctuation out. It looks too much like an operator to me.

    How about changing the sub's name to 'contact_is_male' or 'contact_is_female'? This reads more like an English sentence to my eye, at least in this case.

      You are turning a question into a statement, which in my mind is far less idiomatic. Using an English usage based naming convention, your recomendation would look like this to me:
      ## # contact_is_male( contact_id => $contact_id ) # requires contact_id, makes contact male sub contact_is_male { my ( $self, %arg ) = @_; die "contact_id required\n"; unless $arg{contact_id}; $self->{contacts}{$arg{$contact_id}}{sex}{male}; }

      NOTE: writing subs after beer in an environment without a Perl interpreter *grin*

        I disagree with your views on English Usage, I think... your sentence is declarative, but your subroutine is imperative. The statement "contact is male", like the statement "ChemBoy is human" makes an assertion, and may or may not be true--your interpretation would seem to me to be equivalent to somebody saying "ChemBoy is martian" and having it magically become true (which has not so far taken place, as far as I can tell--though I haven't hit submit, yet...). Whereas if you had a subroutine &make_martian($ChemBoy), I'd be entitled to be worried. :-)

        And if you want English-like syntax, why a question mark in the first place? In standard English usage, conditionals do not have question marks: the phrase "if the customer is female, start the letter with 'Ms.'; otherwise, with 'Mr.'" yields the following code, which seems to me perfectly readable without further punctuation:

        if ($customer->is_female) { print "Dear Ms. ", $customer->surname(); } else { print "Dear Mr. ", $customer->surname(); }

        Or, of course, with punctuation (as mentioned elsewhere in this thread):

        print "Dear ", ($customer->is_female?"Ms. ":"Mr. "),$customer->surname +();

        All of which, of course, are missing the final comma of the salutation, but that's a separate issue. :-)



        If God had meant us to fly, he would *never* have given us the railroads.
            --Michael Flanders

Re: Question Marks in Subroutine Names
by japhy (Canon) on May 07, 2002 at 22:49 UTC
    Use Ruby. ;)

    _____________________________________________________
    Jeff[japhy]Pinyan: Perl, regex, and perl hacker, who'd like a job (NYC-area)
    s++=END;++y(;-P)}y js++=;shajsj<++y(p-q)}?print:??;

      Aaaarrrrg!!!
      *big smile*

      Yes, or lisp, or some hacked up version of logo, or write a fairly complicated module that will let me, or ...

      Come on now, I'm a believer. Maybe, in the Do What I Mean tradition, I'm looking for  sub_name? = { return $foo } to return true or false.

        ...or Forth. You can use other punctuation to make your point too. :-)

        variable light 1 light ! ( turn on the light to start ) : off! ( a -- ) 0 swap ! ; : on? ( a -- f ) @ 1 = ; light on? if light off! then

        Some people even (mistakenly) believe that Forth is nothing but punctuation.

Re: Question Marks in Subroutine Names
by Kanji (Parson) on May 07, 2002 at 22:44 UTC

    If it really bothers you that much, you could do...

    use constant YES => 1; use constant NO => 0; # ... my $answer = is_contact_female ? YES : NO;

    ... but it's shamefully redundant if is_contact_female is already returning a true or false; not to mention limiting (ie, you couldn't use 1 to represent 'Yes, and adult', 2 to be 'Yes, but teen', etc.).

        --k.


        ++crazyinsomniac ... I would probably go just one step further and use type-globbing to simplify the subsequent function call - For example ...

        *{'is_contact_female?'} = sub { my @args = @_; ... }; &{'is_contact_female?'}( @args );

        I first encountered this manner of subroutine assignment in Damian Conway's selfGOL obfuscation, a "must-read" for any aspiring obfuscator.

         

      I'm thinking of this in a boolean context, so what you call limiting I wasn't thinking of as limiting in this context. Good point though. However, this is a hideously ugly solution that could easily be taken care of by allowing question marks in subroutine names.

Re: Question Marks in Subroutine Names
by lachoy (Parson) on May 08, 2002 at 00:18 UTC

    Eeek! I'd imagine that something like:

    if ( $user->is_female ) { print "Madam?"; }

    would be sufficiently concise and clear for anyone. The 'is_property' (or 'isProperty') is also transferrable to other languages, making it the equivalent of the 'no smoking' graphic :-)

    Chris
    M-x auto-bs-mode

      Yes, clear. Concise as well. At least as far as the current limitations of Perl go. This qustion isn't about the current limitations of Perl. It's not a question of "How do I do this?". It's a question about the evolution of a language. The only reason that I posed it is because "I'd imagine" someting that doesn't exist in the current incarnation of Perl.
Re: Question Marks in Subroutine Names
by dbrunton (Novice) on May 08, 2002 at 00:49 UTC
    Okay...

    To begin with, I'm related to this kid, so take what I say with a grain of salt.

    But.

    TMTOWTDI.

    End of story. Anybody who's used LISP knows that this is a great feature. Subroutines that evaluate to true or false should be distinguished from ones that return a value.

    is_female() should return an object of type female or FALSE. is_female?() should simply return TRUE or FALSE. It's faster, you can short-circuit up the ying-yang and it's just generally better.

    Some implementations of LISP use conventions like is_femalep (stands for predicate) and that's pretty nice too. All in all, you should be able to do this sort of thing in Perl, because TMTOWTDI.

    My two cents,
    David.

      Anyone who's used Lisp knows that only Scheme heathen put question marks in predicates. Lisp (and Common Lisp) use the -P convention to mark predicates.

      You could to the same in Perl (use a -<samp>p</samp> or -<samp>_p</samp> suffix on predicates). is_female would become femalep, and Lisp hackers would feel right at home. Perl hackers might be somewhat less pleased, though.

      The reason you can do this sort of thing (use question marks in names) in Scheme (and could do it in Common Lisp, even though it isn't done) is that Lisps have a very simple lexical texture. In contrast, Perl has a horribly complex lexical texture to it, using every symbol on my keyboard (and overloading most of them). But any language using the C "ternary operator" ?: (and not promoting whitespace as a required separator) will not be able to have question marks in symbols.

      I'm always amused by something that says "end of story" at the beginning of the third paragraph from the end... :-) I'm also curious about some of your sweeping statements, here, because they don't make instant sense to me, and you didn't give me much to work with in figuring them out.

      To begin with, I haven't ever "used" Lisp, though I'm somewhat familiar with it, but from Lisp's general reputation, I'm assuming that when you say "faster" you don't mean "faster in execution time", since if you were worrying about execution time you'd be using something... er, faster. :-) So do please correct me if I'm wrong on that (since I'm going to ignore that consideration henceforth).

      That said, where is the advantage to the division of function names you propose? I can imagine some cases where it would be advantageous to have your test function return an object rather than a simple "to thine own self be true", certainly (though I would guess fewer in Perl than Lisp), but in that case, why have a second function which does the same amount of work and returns something else? Since the you can return any old Perl object and have it test True in boolean context, what's the need to have two functions for it?

      "Subroutines that evaluate to true or false should be distinguished from ones that return a value."

      Generally speaking, I agree--but I don't think functions that ask true-false questions should return much other than true or false, personally. Assuming that you do (for reasons hypothecated above) want to do so, why not do it all the time?

      None of this, of course, goes to show that your points are wrong, but merely that I do not understand quite what you're getting at--might I be enlightened?



      If God had meant us to fly, he would *never* have given us the railroads.
          --Michael Flanders

        I'm assuming that when you say "faster" you don't mean "faster in execution time", since if you were worrying about execution time you'd be using something... er, faster. So do please correct me if I'm wrong on that

        You're wrong on that. :-) Good modern Lisp implementations can move along pretty darn well.

      Im a little confused. While I'm well aware of the convention of using the _p -p p suffix for predicate I really dont see how it or a question mark makes the functions following the is_XXXX covention (ie is_female()) more readable.

      Its very clear (at least to me) that an is_XXXXX function returns a boolean (well, perls closest equivelent). What benefit do you derive from the extra marker? I can see how a function _not_ named is_XXXXX might need it, but then again we have a convention for that: is_XXXXXX.

      (partly serious, partly not)

      Yves / DeMerphq
      ---
      Writing a good benchmark isnt as easy as it might look.

        1) I believe the use of p was intended as a replacement for the other forms
        2) I see it as an analog of "Hungarian notation"

        --
        perl -pew "s/\b;([mnst])/'$1/g"

      To be more precise, in Scheme it seems to be traditional to end this type of function with a '?'. In Common Lisp, depending on whether or not the rest of the function's name has a '-' in it or not, one ends it with -p or p (e.g one would have simple-string-p and stringp). (I think there may be an exception to this, but it escapes me at the moment. And I don't think this is followed strictly for certain functions which get automatically defined when using defstruct - which may even be the exceptions I'm thinking of.) I do not know about other Lisp dialects.

Re: Question Marks in Subroutine Names
by seattlejohn (Deacon) on May 08, 2002 at 04:57 UTC
    There's a convention I ran across once, I think in Lisp or Scheme code, of using "p" at the end of a function name that returns a true or false value. (I think the "p" stood for "predicate".) So if you have a function that returns a true value if its argument is odd, false if not, you'd call it "oddp".

    This might not be the most, um, intuitive solution to the problem, but it's one more data point...

      The Jargon File has a great story about this.

      Cheers,
      Erik