Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"

Re^8: I want you to convince me to learn Perl

by soonix (Monsignor)
on Sep 26, 2013 at 07:09 UTC ( #1055789=note: print w/replies, xml ) Need Help??

in reply to Re^7: I want you to convince me to learn Perl
in thread I want you to convince me to learn Perl

I see your arguments and they are true. But - there are no comments in the sample code. Although it is more or less obvious what it does (even without the surrounding node), wouldn't
sub discard_sortkey { unpack 'x[nn]A*' }; sub prepend_yearmonth { my( $alpha, $num ) = m[^(\S+?)\s*(\d+)$]; $num += 2000 if $num <= 49; $num += 1900 if $num <= 99; pack 'nnA*', $num, $months{ $alpha }, $_; } print for map{ discard_sortkey } sort map { prepend_yearmonth } <DATA> +;
be evenly obvious, although there is still no comment?

My field of operations was mainly CRM/ERP systems. At my first job, we used AWK to generate COBOL program source for the different target systems. At my previous job I still generated (and sometimes programmed) COBOL - in this very century. Of course, when Perl became known, I liked it at first sight, especially because I knew the patchwork tools it aimed to replace.

OTOH, most of the languages I had worked with before, had variable declarations and no "contexts", hence no need for sigils. Thus, when I later saw Python, I liked it, too. I think this is what the OP called "cleaner".

I see virtues in both approaches.

(Update: Originally posted under a different node in this thread)

Replies are listed 'Best First'.
Re^9: I want you to convince me to learn Perl
by BrowserUk (Pope) on Sep 26, 2013 at 09:02 UTC
    e evenly obvious, although there is still no comment?

    First, almost a side-issue here, but an important one. My personal take on comments is expressed at length here and here; but can be summarised by saying that I think that for the most part comments in source code are a counter-productive waste of time, energy, resources and therefore, money.

    That said, in the isolated form, I find your self-documenting code a highly readable, fine attempt at the art.

    But ... it only works because it is in isolation of a context.

    For example, prepend_yearmonth() requires to close over %months. In a short script, the hash might be a package global and declared above the declaration of the subroutines; the actual sort is part of the package level code and everything's hunky-dory.

    But now put the sort inside a subroutine -- say, part of the logic of an object's method call. And the hash being referenced by the sort is a part of that object's instance data. Now there is simply no way to define those utility subs to close over the required reference hash.

    And that's the crux of the problem that anonymous lambda's address. They allow the programmer to define callback code in the context of its use, thus availing it of access to everything that is in scope at that point. Named-subroutines cannot do this -- in Perl at least -- because any closures used by subs declared in a nested context will result in the infamous:

    sub x{ my $y; sub z{ say $y; } };; Variable "$y" will not stay shared at ...

    If you feel it is necessary to (self)document the use pattern of the GRT -- and I can make a strong case that it is better for programmers to learn the pattern than to have it hidden from them -- then I would perhaps suggest something along the lines of:

    #! perl -slw use strict; use GRT; # contains: #sub GRT::prefix(&@) { my $code = shift; map &$code, @_ } #sub GRT::discard(&@) { my $code = shift; map &$code, @_ } my %months = ( FY => 0, Jan => 1, Feb => 2, Mar => 3, Apr => 4, May => 5, Jun => 6, Jul => 7, Aug => 8, Sep => 9, Oct => 10, Nov => 11, Dec => 12, ); print for GRT::discard{ unpack 'x[nn]A*' } sort{ $b cmp $a } GRT::prefix{ my( $alpha, $num ) = m[^(\S+?)\s*(\d+)$]; $num += 2000 if $num <= 49; $num += 1900 if $num <= 99; pack 'nnA*', $num, $months{ $alpha }, $_; } <DATA>; __DATA__ Apr 2006 FY05 FY98 FY04 Dec 2007 Jan 1997 Jan 1998 Dec 1998

    The key points of this are:

    1. The GRTsubs can be imported from a module.
    2. That module can document the GRT and the use of the helper functions.
    3. The purely implementation elements, the maps, are hidden.
    4. The sort comparator block can be specified to invert the order of the sort.
    5. It can be constructed at any scope and make full use of the context.

    Of course, it is also substantially slower and little more than a pair of 'active comments'; which leaves me believing that the simple addition of a couple of comments achieves the same thing:

    print for map{ ## remove them once sorted unpack 'x[nn]A*', $_ } sort map { ## prefix year & month in binary form my( $alpha, $num ) = m[^(\S+?)\s*(\d+)$]; $num += 2000 if $num <= 49; $num += 1900 if $num <= 99; pack 'nnA*', $num, $months{ $alpha }, $_; } <DATA>;

    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    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.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://1055789]
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others about the Monastery: (6)
As of 2018-06-18 15:58 GMT
Find Nodes?
    Voting Booth?
    Should cpanminus be part of the standard Perl release?

    Results (110 votes). Check out past polls.