in reply to Re^7: Thread on Joel on software forum : "I hate Perl programmers."
in thread Thread on Joel on software forum : "I hate Perl programmers."

It's not that I wouldn't use a ST, but I would put a big comment above it saying "Use a Schwartzian Transform to sort by...", because it's hard to recognize an ST quickly without wasting time picking it apart. Putting it in a sub would probably be even better.

Regarding the code examples, I probably would have ended up somewhere in between. The OP used C-style for loops which would be better written as (0..12) and could have used more meaningful variables than $i and $j (like $row and $column) and used constants in place of the magic numbers 6 and 12, but it's legible. Your maps are cool, but take much longer to read than a for loop.

For example, I would change this:

my @nums = map { [qw/01 02 03 04 05 06 07 08 09 10 11 12/], } 1 .. 12;
to this:
# build the grid my @grid; my @row = qw/01 02 03 04 05 06 07 08 09 10 11 12/; for (1..$NUMBER_OF_ROWS) { push @grid, \@row; }
No doubt this looks horrible to you, but anyone can see what it does in a quick scan. At the very least, I would change your map to a for(), since it doesn't actually use the 1..12 for anything but looping.

Replies are listed 'Best First'.
Re^9: Thread on Joel on software forum : "I hate Perl programmers."
by BrowserUk (Patriarch) on Jun 17, 2005 at 14:15 UTC

    Probably just an oversight in posting, but there is a problem with this:

    # build the grid my @grid; my @row = qw/01 02 03 04 05 06 07 08 09 10 11 12/; for (1..$NUMBER_OF_ROWS) { push @grid, \@row; }
    #! perlmy @grid; use strict; use Data::Dumper; use constant NUMBER_OF_ROWS => 12; my @grid; my @row = qw/01 02 03 04 05 06 07 08 09 10 11 12/; for (1..NUMBER_OF_ROWS) { push @grid, \@row; } print Dumper \@grid; __END__ $VAR1 = [ [ '01', '02','03', '04', '05', '06', '07', '08', '09', '10', + '11', '12' ], $VAR1->[0], $VAR1->[0], $VAR1->[0], $VAR1->[0], $VAR1->[0], $VAR1->[0], $VAR1->[0], $VAR1->[0], $VAR1->[0], $VAR1->[0], $VAR1->[0] ];

    I made the same mistake initially by coding

    my @grid = ( [ '01' .. '12' ] ) x 12;

    This is being addressed in p6 by a new operator (which I cannot remember if it is 'xx' or 'xxx', but the effect is to iterate it's left operand, not replicate it. (As far as I understand it).

    It has become my "standard conversion" for where I want to type

    my @grid = ( .... ) x $n;

    but need new instances instead of replicated references to exchange the 'x' operator for map:

    my @grid = map{ ... } 1 .. 12;

    I appreciate your misgivings about the 1 .. 12, but that is (as it's position on the right-hand side tends to denote (to my brain) the lesser suboperation of the significant operation; namely that I am initialising the array grid with separate instances of some constant expression. (Oh. And there are 12 of them :).

    Beyond the thinko, the problem I have with the for/push method is that the main objective--that of initialising the array @grid--gets lost in the noise of the construction.


    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
    "Science is about questioning the status quo. Questioning authority".
    The "good enough" maybe good enough for the now, and perfection maybe unobtainable, but that should not preclude us from striving for perfection, when time, circumstance or desire allow.

      FWIW, coming in such a long time after the party:

      It has become my “standard conversion” for where I want to type

      Of course, in this particular case, the correct, optimal solution is trivial:

      my @grid = ( '01' .. '12' ) x 12;

      In the more general case, I prefer another way, because it maintains symmetry:

      my @grid = map @$_, ( [ '01' .. '12' ] ) x 12;

      And to this:

      Beyond the thinko, the problem I have with the for/push method is that the main objective – that of initialising the array @grid – gets lost in the noise of the construction.

      I say bingo. That’s the reason I use Perl to begin with, rather than C. (“If I had a nickel for every time I wrote for( i = 0; i < LEN ; ++i ), …”)

      Makeshifts last the longest.

        Of course, in this particular case, the correct, optimal solution is trivial: my @grid = ( '01' .. '12' ) x 12;

        Actually, no. That builds a single dimension array with 144 elements, not a 2 dimension array of 12 elements with 12 elements each.

        In the more general case, I prefer another way, because it maintains symmetry: my @grid = map @$_, ( [ '01' .. '12' ] ) x 12;

        Let's see.

        1. You build an anonymous array of twelve elements;
        2. replicate the reference to that 12 times into a list;
        3. Pass that list to map(*), where you dereference that reference 12 times to produce a list of 144 scalars which get assigned to the array you are initialising.

        And after all that, for the sake of "symmetry", you still end up with the wrong thing?

        I just read that back and it sounds sarcastic, but it is not intended to be. I relish the opportunity to explain and defend my choices of coding style that so many people apparently find...shall we say eccentric :)

        We may never agree on this, but what you are trying to avoid  1 .. 12; in favour of  x 12;. Ie. You would like to avoid the generation of a list that doesn't get used except for the side-effect it produces.

        But, in your code, you are producing a list of 12 references that only get used for the side-effect it produces! What is the difference between a list of 12 integers and a list of 12 references? Besides the memory consumed.

        Whilst I agree that if/when the language supportes an x-like operator that executes it's left argument 12 times rather than executing it once and replicating it twelve times, I would use that in preference.

        But until that operator becomes available, all those shinnanagins to avoid generating a list of integers that is only used for the side-effect of the iterations it causes, to me, introduces more obfusication, mis-direction and potential for misunderstanding and errors, than using the list for it's side-effects.

        (*)Using the non-block form which even TheDamian agrees with me (in PBP) should be avoided.


        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.
Re^9: Thread on Joel on software forum : "I hate Perl programmers."
by Anonymous Monk on Jun 17, 2005 at 15:35 UTC
    Your maps are cool, but take much longer to read than a for loop.
    <snip>
    No doubt this looks horrible to you, but anyone can see what it does in a quick scan.
    Is that really objectively true, or are you just more familiar with for and less use to map? Do you think there are any legitimate uses of map (and grep, fold, etc)?
      I think map and grep often lead to code that is too dense to read quickly. I do use them, when I have an operation that is short and simple enough. In particular, grep is a good "Are there any like this in the list?" operation.
        Here's a hypothetical for you. Let's say we have a two working implementations of a chunk of code. One incarnation (code "A") uses map, grep, and other higher order functions, and is 25 lines long. The other piece of code ("B") uses for and while loops and is 75 lines long. We've also done some studies and found the following correlations between programmer experience and time to grok each example...
        TIME TO UNDERSTAND (minutes) Experience | Code "A" | Code "B" Level | (maps) | (fors) ------------+----------+----------- Expert | 10 | 20 Average | 50 | 35 Entry Level | 120 | 60
        ...which coding style would you prefer? (Feel free to make up your own example to show different time breakpoints/code density levels/costs of programmers).