http://qs321.pair.com?node_id=592860


in reply to Re^2: What is code readability?
in thread What is code readability?

1st & 4th, my favourite one BTW, are much easier on the eyes.

There is one more variation ...

some_function ( some_variable , some_other_variable , and_yet_another_variable , and_one_more_for , luck )

Replies are listed 'Best First'.
Re^4: What is code readability?
by BrowserUk (Patriarch) on Jan 04, 2007 at 05:45 UTC

    Ug :) I really hate that. I see no benefit in spaces both sides of the commas, or breaking the open paren away from the function name. And if you have to break the params across lines, at least balance their lengths :)

    some_function( some_variable, some_other_variable, and_yet_another_variable, and_one_more_for, luck );

    That's not so bad for simple (void) calls as, but when you're retrieving data and checking you get something like

    if( some_return_value = some_function( some_variable, some_other_variable, and_yet_another_variable, and_one_more_for, luck ) ) { // do some stuff here with some_return_value } else { // report or otherwise handle the error }

    It's just a mess.The best I've come up with for this is

    if( some_return_value = some_function( some_variable, some_other_variable, and_yet_another_variable, and_one_more_for, luck ) ) { // do some stuff here with some_return_value } else { // report or otherwise handle the error }

    Which ain't great, but is better than most alternatives to my eyes.

    And much better still is

    if( someRv = fSome( some, oSome, AYAnother, OneMoreFor, luck )) { // do some stuff here with someRv } else { // report or otherwise handle the error }

    With the point being that whilst ths abbreviated variable names don't immediately make much sense, by the time a programmer has got familiar enough with the code to consider making changes, they will.


    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
      Even more vertical.

      And you're always going to get all those args in the right order? I know I wouldn't.

      # round em up... my $args = { # no need to worry about the order arg1 => $some_variable, arg2 => $some_other_variable, arg3 => $and_yet_another_variable, arg4 => $and_one_more_for, arg5 => $luck, arg6 => some_other_function(), arg7 => $maybe_a_variable or $default, }; # ...and herd em in my $some_return_value = some_function($args); if($some_return_value) { # do some stuff here with some_return_value # and if there are more than a few lines # I'd consider another sub } else { # and don't cuddle your else # report or otherwise handle the error # in another sub :-) } sub some_function { my ($args) = @_; # no need to worry about the order here either }

      I should point out I'm presently having terrible trouble debugging an app (that I'm writing). It gets more vertical by the day! :-)

        Hmm. I really do have a strong aversion to this vertical coding style. I've attempted to explain the reasons for this on many occasions here and elsewhere, but I'm not sure I've ever done so successfully. I may try again at the end of this post, or in another post.

        I'm also skeptical about the need for/benefits of named arguments. For example, there are very few functions in perlfunc that take more than 4 arguments. And for those that do, those beyond 4 are final LISTs that extend indefinitely in an obvious and unnameable way.

        Of those that (can) take four, non-list arguments, the ones I use regularly: splice, substr, index, rindex, vec, open/sysopen, read/sysread/syswrite; I do remember the ordering without any specific effort to do so.

        Of the others in perlfunc that take four or more args, most of which I have rarely if ever had occasion to use--mostly because they don't work or make little sense on my platform--I would have to look them up. But then, I'd have to look them up anyway just to know what they do, and what they require to do it--let alone what order they expect those things in.

        Of the APIs that use named argument interfaces that I use regularly, the IO::Socket::* constructor is probably the one I've used most. And if I ever need to call that in anything other than the simplest $sock = IO::Socket::INET->new('127.0.0.1:25'); form, I always have to look it up. In large part because I can never remember the correct capitalisation of the argument names!

        The upshot is that I think that

        • A well defined API rarely needs more that 4 or 5 arguments.

          If you find yourself writing APIs that require more than 4 or 5 arguments then that is usually indicative of more fundamental problems in your architecture.

        • Where more than 3 arguments are required, there is generally an obvious, 'natural ordering' that makes the need for naming the arguments redundant.

          This, as in so many ways, Perl's API is exemplary in the way it DWIMs.

          This is one (of several) reasons why I get irked by people recommending the substitution of modules that are bare wrappers around Perl's built-in APIs. Perl has one of the richest and complete, yet simplest set of built-ins of any language. Despite all of it's well-known quirks, foopars, anomalies and out-right errors, as a whole, it hangs together and works together to provide immense power without the need to resort to loads of often incompatible add-ons, tack-ons and overarching frameworks to get the vast majority of things done.

          There are many modules on CPAN that set out to 'correct' some perceived flaw in Perl's built-ins that wrap a simple, cohesive API in a behemoth of a (usually OO) API that creates as many problems as it fixes. And in doing so, forces the maintenance programmer of code using those modules to have to learn all the twists, roundabout, flaws and limitations of that API--in addition to knowing those of Perl itself. This is false economy in 90% (made up statistic warning!) of cases.

        • In many situations, naming arguments simply shifts the problem.

          You end up looking up the API documentation in order to remember what arguments are required/optional; how they are spelt; what naming conventions are used; etc. Once you've looked it up, the ordering is the easiest thing to document and read.

        • And actually, looking up the documentation for APIs is a 'Good Thing'.

          Assuming that is a reasonably simple process--which it should be--then scanning the documentation even for APIs that you're familiar with will often remind you of quirks, caveats, short cuts or alternatives that may not have immediately sprung to mind had you not.

          And even for 'simple' APIs, there are often reasons other than the ordering, for looking at the documentation.

        There are occasions when it is necessary to have an API with more than 4 or 5 arguments and for which named arguments makes sense, but on those occasions there are several things that (IMO) should be true.

        • Argument names should be short.
        • They should be passed as pairs, not as you have shown as a hashref:

          Eg:

          sub some_function { my (%args) = @_; # no need to worry about the order here either } ## optionally sub someMethod { my( $self, $mandatoryFirstArg, %args ) = @_; # no need to worry about the order here either }
        • Names should be case-insensitive.

          Not easy to do with Perl's hashes, but still very desirable for a bunch of reasons. It's easier to arrange with the camelCasesNamingConvention than it is with the underscaler_separated_naming_convention.

          The use of Mixed_Case_And_Underscore_Separated naming should be outlawed by the UN and enforced by OHCHR under the heading of "Crimes against Humanity" :)

        • Often, hash-based named argument interfaces can (and would be better) replaced by the use of a 'string' interface.

          The 'simple' form of the IO::Socket::* constructor is a good example of this.


        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.
      if( some_return_value = some_function( some_variable, some_other_variable, and_yet_another_variable, and_one_more_for, luck ) ) { // do some stuff here with some_return_value } else { // report or otherwise handle the error }

      My take on it is pretty close, I just see OK to open more than one paren in a line (and hence close them all in the same line):

      if (some_return_value = some_function ( some_variable, some_other_variable, and_yet_another_variable, and_one_more_for, luck )) { // do some stuff here with some_return_value } else { // report or otherwise handle the error }

        Yes, That's okay too, though I do prefer to have the indent level reflect the number of currently open parens. So:

        if( some_return_value = some_function( some_variable, some_other_variable, and_yet_another_variable, and_one_more_for, luck )) { // do some stuff here with some_return_value } else { // report or otherwise handle the error }

        but sensible length variable names (and camelCase :) are better.

        if( someRV = someFunc( some, someOther, yetMore, oneMore4, luck ) ) { // do some stuff here with some_return_value } else { // report or otherwise handle the error }

        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.
Re^4: What is code readability?
by jdporter (Paladin) on Jan 04, 2007 at 05:37 UTC
    There is one more variation

    Only one?

    some_function ( some_variable , some_other_variable , and_yet_another_variable , and_one_more_for , luck , ) some_function ( some_variable , some_other_variable , and_yet_another_variable , and_one_more_for , luck )
    A word spoken in Mind will reach its own level, in the objective world, by its own weight

      Of course; I did not claim the posted version as "'only|sole|last' one variation" (but "a variation").

      Problem with your first variation -- for that matter, any other code in which things are aligned along the columns -- is that aligning commas for short varaibles like "luck" is too much effort. (Second one is just ridiculous overkill.)

      (I was hoping not to contribute anything (as I do not have much to say about brain d foy's points) but I was suckered in anyway.)

      A reply falls below the community's threshold of quality. You may see it by logging in.
Re^4: What is code readability?
by Anonymous Monk on Jan 04, 2007 at 17:29 UTC
    some_function(some_variable, some_other_variable, and_yet_another_variable, and_one_more_for, luck);
    ...getting better...
    some_function( filename => $some_variable, address => $some_other_variable, amount => $and_yet_another_variable, phone_num => $and_one_more_for, diameter => $luck );
      And that bites when you want to cut the first or last, or paste another first or last, argument. I prefer the args on separate lines, and indenting a normal (4 or whatever the standard) number of spaces.