Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses
 
PerlMonks  

Re: Efficiency in maintenance coding...

by dws (Chancellor)
on Nov 15, 2001 at 01:33 UTC ( [id://125427]=note: print w/replies, xml ) Need Help??


in reply to Efficiency in maintenance coding...

Now, tell me... is that not a *lot* easier to comprehend... and more importantly, if you were a maintenance coder... would you not prefer to have to understand these 2 lines of code, rather than the chunk of java?

If I were a Perl maintenance coder, I might prefer something slightly more verbose (but only slightly).

But if I were using this example to wave at Java coders to convince them that Perl will save them grief, I would make it even more verbose, lest it reenforce a notion that Perl is overly cryptic. Past a point, "Look how small we can do this with Perl!" becomes a negative. Instead, present Java programmers with something more familiar.

Something like

#!/usr/bin/perl -w use strict; my %frequency = (); # maps token -> count # for every line of every input file while ( <> ) { # for each token on the line foreach my $token ( split /\W/ ) { # increment the count for the token $frequency{$token}++; } } # print each token and its count foreach my $token ( sort keys %frequency ) { print "$token: $frequency{$token}\n"; }
A bit more verbose than what would automatically fly off the fingertips of a seasoned Perl hacker, but even with comments, it is less than a third the size of the Java example. AND it only uses control structures that a Java programmer should recognize. The only thing they might object to is the hidden use of $_.

(I don't know how TreeMap behaves, so the sort might need to be changed to sort on value.)

Replies are listed 'Best First'.
Re (tilly) 2: Efficiency in maintenance coding...
by tilly (Archbishop) on Nov 15, 2001 at 02:31 UTC
    Were I trying to tout the advantages of Perl to a maintainance programmer who had been around the block, I would not put in comments that they would be sure to recognize as maintainance pitfalls! Instead I would go the other way:
    #! /usr/bin/perl -w use strict; # Create a frequency count of all words in all input files my %freq_count; while (defined(my $line = <>)) { while ($line =~ /(\w+)/g) { $freq_count{$1}++; } } # Print the frequency summary. foreach my $word (sort keys %freq_count) { print "$word:\t$freq_count{$word}\n"; }
    There. The looping constructs are all readily explainable, there are no hidden uses of $_, and no comments that will become wrong with time. I also removed a bug in the code that you wrote (which you copied unchanged from eduardo).

    Kudos to the first person to figure out what the bug is.

      tilly: Kudos to the first person to figure out what the bug is.

      I'm guessing split /\W/: this splits on each non-word character, but if there are several \Ws together(a comma followed by a space, for instance) it will split between them, creating a spurious "" word. The fix was to look for \w+ (although you might also say split /\W+/).

      Update: The above split-based "solution" introduces spurious "" words if a line (say) begins (or ends) with a \W. Looks like m/(\w+)/g is the Right Thing in this case.

      Update 2: Of course, split discards any empty trailing entries, so only the ones at the beginning of the line are a problem. (I'll get this eventually...)

      --
      :wq
        Pretty good...

        But your proposed fix only handles 95% of the problem. Why didn't I try fixing things that way? (ie What does your fix miss?)

        BTW so far this code example is not making the case for Perl being maintainable look very good... :-(

        UPDATE
        Your update is half-right. The half that is wrong is the most common misunderstanding I have encountered about how split behaves...

        UPDATE 2
        Eventually seems to have come. Modulo difficult questions about how the definition of a word ain't what you would expect. Consider a kudo delivered. :-)


      One last hurdle,

      What if you want to print out the list not alphabetically, but by how many occurances of the word occur? The easiest way to do this would be an ST1. Is an ST easy to maintain?

      Correct me if i'm wrong but i believe that Java has a method of doing this immediately (which is probably why they used the Tree to print it) whereas Perl can do it readily, but it's harder to understand for the common Java programmer, not to mention a few Perl programmers. Who wins maintainability this time?

      jynx

      1Schwartzian Transform
      update - d'oh, i shouldn't post before my first cup of coffee. please disregard...

        Perl.

        Right now our Java solution hasn't yet figured out how to handle contractions yet. Perl is still ahead. Secondly why break out the sledgehammer when you don't have to?

        foreach my $word ( sort { $freq_count{$b} <=> $freq_count{$a} or $a cmp $b } keys %freq_count ) { print "$word:\t$freq{$word}\n"; }
        Most Perl programmers should understand this. Doing the same in Java, well probably somewhere in their maze of classes is one that naturally sorts in exactly the order you want. Good luck finding it, and good luck for the average Java programmer realizing why you chose this way of doing things.

        And as for the maintainability of a Schwartzian Transform, it is a trick. If you think in a list-oriented way, or if you have ever really understood the tranform, then maintaining it when you see one is pretty easy. I understand it, and I try to ensure that people I train are able to handle list-oriented thinking. So it isn't a problem for me. But YMMV on its maintainability.

        No Schwartzian Transform is required. Does Java let you easily sort ignoring case? How about by length?...

        sort { $freq{$a} <=> $freq{$b} } keys %freq sort { lc($a) cmp lc($b) || $a cmp $b } keys %freq sort { length($a) <=> length($b) || lc($a) cmp lc($b) || $a cmp $b } keys %freq
        You might find that a ST executes faster for that second case (and you could almost certainly speed it up with one of several techniques that are faster in Perl than an ST), but I doubt the speed gain would be worthwhile since lc() shouldn't be that slow.

        Speeding up the third case with a ST would be more difficult than using some other sort-speeding techniques (many of which have names that I don't recall). Though you'd have to have a whole lot of different words for the trade off of sort speed for code complexity to be a "win" here, especially since we are trying to write very maintainable code.

                - tye (but my friends call me "Tye")
Re: Re: Efficiency in maintenance coding...
by eduardo (Curate) on Nov 15, 2001 at 02:02 UTC
    But if I were using this example to wave at Java coders to convince them that Perl will save them grief, I would make it even more verbose, lest it reenforce a notion that Perl is overly cryptic. Past a point, "Look how small we can do this with Perl!" becomes a negative. Instead, present Java programmers with something more familiar.

    I agree with your sentiment. However, I want to play devils advocate for a moment... This node stemmed from a conversation I had with a professor of mine a few weeks ago, where he was touting the value of languages like Java, due to the fact that they were easy to do maintenance coding for. I vehemently disagreed with him (I am currently doing maintenance java coding...) as I feel that one of the biggest problems with languages such as Java is that the *idioms* of the language do now allow for elegant expression of algorithms without a very liberal propegation of metasyntactic variables.

    So, I wrote this particular example in the most idiomatic Perl I knew how. This is my logic: Average Java programmers will program average Java idioms with an average level of skill. The companion to that is that average *Perl* programmers will program average Perl idioms with an average level of skill. What I wanted to show was that with a comparable level of skill between Java and Perl, using the idioms that were native to average programmers of *both* environments, the resulting idiomatic Perl code would be easier to maintain (from a cognitive psychology standpoint, as well as the other "benefits.")

    I feel that I am, at best, an "average" perl developer, and when I read the problem description on the Java page, the exact idiom that came to mind was the one I put down on paper... as a matter of fact, I had considered asking either maverick or jeffa, who are considerably better Perl programmers than myself, for a good idea as to how to make it shorter. I fortunately quickly realized that asking wizards for help, in attempting to create a compelling example as to how the average coder would fare... was a bit of an improper turn of logic on my part!

    In closing... were I trying to win over Java developers, I think I would have done something more along the lines of what you very elegantly suggest. However, I am past a point in my life where I want to win language wars, and proselytize and convert the lost :) I was more interested in showing how an "average" developer with an "average" skillset, would probably fare better in Perl...

    Thx for the comment, btw...
      I'm with dws on this one. His example is much more maintainable than your original one. Hanging out on Perlmonks might make you think that lots of Perl developers are comfortable with throwing around condensed code with unusual uses of for and splitting on <>, but that just isn't the case in the rest of the world. I have a pretty good amount of professional Perl experience under my belt, and I had to stare at your code for a minute to figure out what was going on there.

      When people attack Perl, they often do it on the basis of readability. That's why I think it's very important to write clean and understandable code when it's for public consumption. It's not so much a Perl vs. Java thing as a general advocacy thing. Note that I didn't say never to use Perl idioms. Just know the difference between idiomatic and confusing.

        Maintainable by whom?

        Maintainability is an interaction between code, users, and programmers. I think that most "Perl hackers" would prefer to work with eduardo's code. Most people who put Perl on their resumes would prefer what dws produced.

        I personally prefer working with people who can figure out things like:

        $freq_count{$_}++ for get_words(<>); # Takes one or more strings, returns all words it finds. sub get_words { map /(\w+(?:'[ts])?)/g, @_; }
        (Not that I try to abuse people, but should I find something convenient, I like not having to worry about whether the next person can figure that out.)
      Hmmm. Another look what I can do in two lines discussion. I've been in quite a few of these so let me toss in something that might be a little different.

      First up, you have picked one of perls strongest features to beat one of Java's weakest. If you compared opening a window and displaying a list of selections, I think I know which language would come out ahead.

      And now to the debate. The fantastic people who designed perl made some particular choices about the functionality they were going to build into perl. The possibly fantastic people who wrote Java made different choices. Why did the perl designers stop at map and split and not continue to give us commands like 'load_and_split'?

      Why did the Java designers stop long before that? I suspect that the Java designers were expecting people to write classes like 'load_and_split' and share them around. But for various reasons the Java community doesn't work like the perl community and so these higher level functions don't get passed around.

      If there was a decent string library produced by someone, then java would win in your example because all average java programmers would be using GNU.string.file_load_and_split( FH, "\W") or however you would say it in Java. But we ended up with the great designers somehow and so we have the great functions that do just enough and not too much.

      If Dr Conway hadn't found perl you might have found java developers touting their Conway.quantum.superpositions or Wall.array.map functions as being the epitomy of programming.

      Perl people seem to delight in commands which are powerful but still somehow clear. Java people seem to love lots of code. But there's no reason why de facto standard class libraries couldn't be generated and passed around

      However given the amount of head kicking it takes to get people to use CGI and strict here at the monastery, I imagine you could never get Java developers to use other peoples classes. They'd always be whinging about how they could do it faster or one line less or something. Sounds kinda familiar actually...

      ____________________
      Jeremy
      I didn't believe in evil until I dated it.

        Hmmm. Another look what I can do in two lines discussion. I've been in quite a few of these so let me toss in something that might be a little different.

        no. not quite. the purpose of my original node was not that by a long shot. The purpose of my node was to discuss the relative complexity between VHLLs and more "systems" languages, especially as related to maintenance programming. To be honset, I am a little bit distressed that it was taken to be a "language wars" node, because I can guarantee you, that was *not* the intent.

        First up, you have picked one of perls strongest features to beat one of Java's weakest. If you compared opening a window and displaying a list of selections, I think I know which language would come out ahead.

        I am afraid I am going to have to disagree with this point. Currently, for a living, I am a maintenance java developer, working on an AWT application, so I do know the inner workings of managing UI's. Quite frankly, I do not find that the AWT or Swing would provide a clearer more concise, easier to maintain example than say, Tk, or Win32, or any of the other modules. I agree that the comparison would not be so drastic, but I think the languages would end up roughly "even." I do however believe that the code that would be required to grab, process, and understand the data that was put in to one of these "lists of selections" would probably be considerably easier in a VHLL. I do not have time right now to work up a small example, however tonight I may create an AWT example, a PerlTK example, and for fun a Python Win32 example... (or I may forget about this and have a fun night away from "the machine" :)

        As for everything else, yes... one of the greatest values of Perl *is* the community there is no doubt of that. And one of the greatest things the community has created *is* CPAN. However, the code that I showed used *no* CPAN modules, it used the inner expressiveness of the language. That's the incredible thing... Larry Wall (and those around him) worked very hard to create a language that is *expressive*, not because it has a wonderful class library (although it does), not because we have TheDamian or merlyn or Larry... but because the *language*, as a VHLL, allows me to *express* my program efficiently, without the overwhelming propegation of variables and constructs that create a supporting scaffolding for the *actual* task at hand... a problem that I see *every single day* on production Java code from dozens of different sources.

        My node happened to be on Perlmonks, and it happened to show 2 (as tilly showed via maintenance coding) poor lines of Perl code. However, this node could have been at ISETLmonks or PythonMonks or RubyMonks, or any of the hundreds of other languages which allow the programmer the freedom to *express* their software, rather than mechanically dictate and regurgitate it.

        However given the amount of head kicking it takes to get people to use CGI and strict here at the monastery, I imagine you could never get Java developers to use other peoples classes. They'd always be whinging about how they could do it faster or one line less or something. Sounds kinda familiar actually...

        Well, you're never going to get all people everywhere to agree on the 100% right set of modules... and even when you give them good evidence as to why doing things a certain way leads to better results... sometimes they ignore you. Wouldn't it be nice to have them make these mistakes in a language that when *YOU* go to maintenance code behind them, because their code was flawed (as so many hand rolled solutions have a tendency to be), you can replace their cargo-cultness with a few concise, expressive, ideomatic, and well tested and understood lines of code (probably using a CPAN module or two)? :) I know that's a situation I'd much rather be in.
        First up, you have picked one of perls strongest features to beat one of Java's weakest. If you compared opening a window and displaying a list of selections, I think I know which language would come out ahead.

        That's a loaded statement and you know it. I have been developing Perl applications to "open a window and display a list of selections" for almost 10 years, and it's really really easy. It requires a web browser and a web connection. Oh, is that what Java tends to require as well? Oh, do my CGI scripts work with more browsers and more OSes? Oops.

        And, if you're talking about stand-alone systems, I've got a webpage that acts as its own secure server (though this only works with browsers that understand ActiveX). Oops, did I just beat you again?

        *grins*

        ------
        We are the carpenters and bricklayers of the Information Age.

        Then there are Damian modules.... *sigh* ... that's not about being less-lazy -- that's about being on some really good drugs -- you know, there is no spoon. - flyingmoose

Re: Re: Efficiency in maintenance coding...
by Sweeper (Pilgrim) on Nov 15, 2001 at 02:33 UTC
    Are you sure your code snippet could convince Java coders to switch to Perl? They would still object the funny characters "$", "@" and "%". And they would also object names without a class qualifier, the typeless definitions of variables, the use of plain functions instead of methods.

    At the same time, Perl coders, even seasoned coders would cringe when reading your code. Why code a Perl program with a Java mindset?

    Can we really convince Java coders to adopt Perl? Some people love bureaucracy and red tape, others don't like it, but it gives them a feeling of security, and they would be afraid to exercise their free will (supposing they still have one). So, there exist coders that love code red tape, or feel secure only when bound in code red tape.

    Hopeless.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://125427]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others chanting in the Monastery: (2)
As of 2024-04-20 04:21 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found