http://qs1969.pair.com?node_id=502605


in reply to seeds...

Great story -- thanks. I was especially struck by this piece:
... He liked it, saying the way I'd done it was "like .NET in concept" (I think this was because of the Response->Write syntax and that I'd declared a bunch of tags at the top of the script that I knew I'd use ...). He was also surprised by how clear it was to him.

This points to the importance of a notion that tends to be forgotten sometimes by truly dedicated (addicted) Perl users (including me): not only is it possible to write Perl programs so that they resemble programs written in some other language, but sometimes it is a Good Idea(tm) to do so.

We all know how cool it is (clever, intriguing, sexy, etc) to write Perl code that is highly idiomatic, tersely compact, even ethereally abstracted. But this sort of usage will pose problems for maintenance, especially in shops where Perl is only one of several available tools (and not necessarily the predominant one).

Replies are listed 'Best First'.
Re^2: seeds...
by Anonymous Monk on Oct 25, 2005 at 00:33 UTC
    We all know how cool it is (clever, intriguing, sexy, etc) to write Perl code that is highly idiomatic, tersely compact, even ethereally abstracted. But this sort of usage will pose problems for maintenance, especially in shops where Perl is only one of several available tools (and not necessarily the predominant one).

    *shudder* Where does that horrid "cleverness" mentality come from, anyway?!? What happened to professionalism; the KISS principle; clean, obvious code that doesn't require wasted thought or effort to maintain?

    I see so many would-be clever programmers using complex idioms for the sake of cleverness; playing games with scoping, closures, OO to implement a theoretically elegant solution that's convoluted, hard to maintain, and hard to test.

    Sometimes it's simpler to just plain write:

    print "Hello, World";
    and be done with it, rather than some "sophisticated" mess like:
    use Config::Parser; # "clever" in house module to parse config files; +relies heavily on closures, XS, and mutual recursion; contains own le +xer and parser use Language::Gylph::Unicode; # "clever" in house module for unicode; +written in as a clever polyglot of FORTRAN, C, and Assembler, "just i +n case" only one of the languages is available at any given time my $parser; $parser = Config::Parser->new( $ARGV[0] || $ENV{CONFIG} || get_default +_config($0) ); $parser->set_output_device(\*STDOUT); $parser->set_Encoding( Language::Glyph::Unicode->get_encoding( $ENV{LA +NGUAGE} ) ); $parser->set_display_string( $parser->get_data(TYPE=>GREETING)); $parser->output_display_string();
    where the hastily written perldocs for the parser claim that only ASCII encoding is currently supported, and the entire target audience speaks only English, and only has access to 7-bit ascii text terminals. And yes, I've seen code that ugly before! :-(

    I see sooo much over-engineering, would-be cleverness, and solving of non-problems in my workplace that I'm perhaps oversensitive to it, but I find that "clever" is far too often code for "writing obfuscated code to stroke my own ego, and protect my job security"; my ex-boss did this for several years, and completely destroyed all semblence of maintainable code here at my company. :-( I'd re-write it, but I'm not allowed to until it breaks. :-(

    So, perhaps as a reaction to that, I very much prefer the K.I.S.S principle; make it work, and make it obvious. Be clear on your own time; don't waste your co-workers time on ugly idioms unless the idiom is necessary, and not just "cute". "Cute, clever, and tricky" is quite often the opposite of "simple, obvious, and correct", at least in my experience.

      *shudder* Where does that horrid "cleverness" mentality come from, anyway?!? What happened to professionalism; the KISS principle; clean, obvious code that doesn't require wasted thought or effort to maintain?

      The original poster talked about idiomatic and tersely compact code which is quite a bit different than "clever" code. To me, idiomatic perl is clean and obvious. "Clever" code is typically non-idiomatic and often obfuscated in some fashion. When the comments say something like "we rely on the undocument return value of this function to index into the array", the code is clearly too clever for it's own good.

      Judging from the rest of your post I'd say that you have a very different idea of what "idioms" are than I do. Just as you don't code C as if it were Fortran once you learn C well enough, you don't code Perl as if it were something else (unless that's explicitly your goal) once you learn Perl well enough. I certainly don't "dumb down" my perl code for the sake of those who don't know perl well enough to understand it. Rather I encourage them to learn perl better.

      Anyway ...

      "Cute, clever, and tricky" is quite often the opposite of "simple, obvious, and correct", at least in my experience.
      I could not agree more. I just think you and I perhaps have differing ideas of what's "simple, obvious, and correct"
        I certainly don't "dumb down" my perl code for the sake of those who don't know perl well enough to understand it. Rather I encourage them to learn perl better.

        Well, for me, my company's corporate goals don't including "encouraging language elitism". Like most companies, they focus on getting the job done; and if they don't have to train more, that's better. It's a lot harder to train someone to learn all that someone can do with perl (approximately 5-10 years of solid experience). It's more time and money efficient to write your code so that people who aren't perl experts can still understand your code than to spend five years teaching all of them all of the ins and outs of the language, especially one with so *many* wierd exception cases like Perl.

        If there's a choice between writing something in plain language, obvious to a reader from any language background, I'll take it.

        The example I gave in another thread was:

        my %y = %$x;
        versus
        *y = $x;
        Both do roughly the same thing: access the contents of the hash x. The second is far more efficient in terms of operations performed; it also avoids doing a copy, since it's a direct alias into the hash contents. It's therefore "faster", albeit riskier as well, in the case of accidentally overwriting the hash contents.

        I very much prefer the first example, because it's more obvious what's going on. The code will fail immediately if $x isn't a hashref. And more to the point, it's obvious to everyone reading it that a hashref is what was expected. In the second line, it's very unclear as to what's expected to happen; in fact, whatever is passed in gets aliased.

        I try to code in such a way as to express intent, not just function. If the code reflects my intent, anyone can fix mistakes in the encoding of that intent. The more obvious my code is to more people, the more value it has to my company, because more people can fix it or formally review it to ensure complexity.

        I've had business analysts notice mistakes in the business logic of my code; *because* it's written so to be so obvious that even non-coders have a chance at grasping it. It's very satisfying to them to be sure that what they want is what's being coded; and it's reassuring as a coder to me, as well! If you write for perl-gurus only, your code will only be readable by gurus.

        There aren't many perl gurus, and their time is expensive, and not worth wasting on testing tasks that could be done by others, if the code was written to a reasonable level.

      To be honest, I prefer seeing idioms. It tells me that the user has a grasp on the elegance of the language. But I think that's completely orthogonal to "cleverness" - at least in the usage seen here. Idiomatic can be clear, clean, precise - and can be all these things while still being flexible to handle changing requirements.

      I'll definitely agree to the "simple, obvious, correct." But I don't think idiomaticness has anything to do with that.

      Then again, I've managed to eliminate about 80-90% of my manager's code from our department, and significant portions of his design. His design often is "simple, works, and rigid." I've replaced most of that with "simpler, consistant, flexible." At least, in my not-so-humble opinion ;-)

        To be honest, I prefer seeing idioms. It tells me that the user has a grasp on the elegance of the language.

        Or a complete lack of a grasp, in my boss's case! ;-)

        Knowing when to use Perl's idioms, and when to avoid them is the real point, I think.

        For example, assigning to a typeglob just to get rid of a single level of indirection is a Perl idiom that's non-obvious, and not a wonderful idea if done for no reason. If you need to play with the typeglob syntax, it's there, and it's on rare occasions quite useful, but there's no reason to dabble lightly.

        My boss didn't think so. He would frequently write stuff like this:

        sub foo { my $x = shift; *y = $x; # Quick, what's he just done? He's just added something # to our namespace via aliasing, (and stripped a level # of indirection thereby), but what, exactly, has been # added? # Is it %y, @y, $y or even &y? What's he # up to? Arrrgh! # hundreds of lines later (a separate annoyance) # Ah, he aliased %y!!! $x must have been a *hashref* # He could have just written %y = %$x, but that # would be less efficient, and far less idiomatic foreach my $key ( keys %y) { bar($key); } }

        Me, I'd just explictly dereference %$x, and skip the whole typeglob idiom, unless there was a significant reason not to do so. If I really wanted an automatic conversion, I'd probably use signatures instead. And if I were for some reason going to use the idiom, I'd point out at least the types (scalar, hash, array, or coderef) that I expected to be aliased by the idiom.

        Making a section of a hash "local" is another of my boss's abuses of Perl idioms, in my opinion. Yes, you can make things "local". Wow, you can even make sections of things local. What a cute, quirky little way to express yourself: idiomatic perl at it's finest! It's barely even a documented feature!

        And with it, you can call a function on a hash, and then go back, and undo what parts of the function did, based on a poorly documented set of flag settings! What fun!

        Me? I'm just bitter, I guess. ;-) Too much burnout. :-(
        --
        AC