Hacker News new | ask | show | jobs
by isostatic 2513 days ago
"too clever constructions which feel smart at the time you come up with them"

That's the coder, not the language.

Which is more obvious what's happening.

  print ''.join('%(pre)s%(num)s %(bot)s on the wall, %(nul)s %(bot)s,\n%(tak)s\n' % (lambda c,b: {'pre':['','%s %s on the wall.\n\n' % (c,b)][abs(cmp(c,'Ninety-nine'))], 'num':c, 'nul':c.lower(), 'bot':b, 'tak':['Go to the store and buy some more... Ninety-nine %s.' % b,'Take one down, pass it around,'][abs(cmp(x,0))] })((lambda x,o: [(['Twenty','Thirty','Forty','Fifty', 'Sixty','Seventy','Eighty','Ninety'][x/10-2]+'-'+o.lower()).replace('-no more',''), o][int(x<20)])(x, ['No more','One','Two', 'Three','Four','Five','Six','Seven','Eight', 'Nine','Ten','Eleven','Twelve','Thirteen','Fourteen', 'Fifteen','Sixteen','Seventeen','Eighteen','Nineteen'][[x,x%10][int(x>=20)]]),'bottle%s of beer' % ['','s'][abs(cmp(x,1))]) for x in xrange(99,-1,-1))

Or

  my $firstline = 1;
 my @tens = qw/Ninety Eighty Seventy Sixty Fifty Forty Thirty Twenty/;
 my @teens = qw/Nineteen Eighteen Seventeen Sixteen Fifteen Fourteen Thirteen Twelve Eleven Ten/;
 my @ones = qw/Nine Eight Seven Six Five Four Three Two One/;

  sub go {
     my $num = shift;
     my $bottles = "bottles";
     if ($num eq "One") {
         $bottles = "bottle";
     }
     if ($firstline == 0) {
         print "$num $bottles of beer on the wall.\n";
         print "\n";
     }
     $firstline = 0;

     print "$num $bottles of beer on the wall, ".lc($num)." $bottles of beer,\n";
     print "Take one down, pass it around,\n";
     if ($num eq "One") {
         print "No more bottles of beer on the wall.\n";
         print "\n";
     }
 }
     
 foreach my $ten (@tens) {
     foreach my $one (@ones) {
         go("$ten-".lc($one));
     }
     go($ten);
 }
 foreach my $teen (@teens) {
     go($teen);
 }
 foreach my $one (@ones) {
     go($one);
 }
 
 print "No more bottles of beer on the wall, no more bottles of beer,\n";
 print "Go to the store and buy some more... Ninety-nine bottles of beer.\n";
 print "\n";


People can do clever things in either language, people can write clear code in either language.
3 comments

Languages are not just platonic, ideal things, living in an abstract world. They are also people, core developers and BDFLs, guidelines, communities, cultures.

The Perl culture is overall about being practical but also being clever and leaning towards code golf.

The Python culture is overall about being explicit and readable.

As usual, YMMV, but that's the impression an awfully lot of people get, so there must be some truth to that.

The problem with any language is most people don’t spend time to actually learn it to proficiency. They don’t read the books, just google a quick solution.

Perl is great because it has nuances many languages don’t, for instance sigils which allow the language to evolve safely (adding language constructs won’t clash with vars.) and “magic variables” designed to allow shortcuts like we use in spoken language. But, just like people shouldn’t use much spoken vernacular in writing, a lot of those features are designed for quick “conversations” and one-off scripts. And it should be peer reviewed before publication.

Python is great for many things too, but it’s no C++, and it’s also no Perl.

This post reminded me that Perl doesn’t even have a concept of a method signature, even so much as showing the number of arguments. You have to look at the next few lines to hopefully see all the `... = shift;` lines to see what you’re actually supposed to send.

I mean, a lack of type annotations is normal for a scripting language, but Perl always seemed to go a bit far by not even having a standard way of showing parameter names.

I remember doing `my ($arg1, $arg2) = @_;` or something similar, but even that felt weird, and not everyone adopted that convention.

I usually do

  sub mymethod($$)
    my ($arg1, $arg2) = @_;
  }
Apart from on the smallest programs. So it does have a method signature (obv it's an untyped language)

There are shortcuts (just like you could write "doSometing() unless $var;"). Perl does give you options.

Python has different options for passing methods - passing variables, passing a dict,

P.S. while looking at python method declartions, you can send variables, a key-value, multiple keyvalue, and then there's this: https://stackoverflow.com/a/16785702

Which comes out with

  f = lambda **dic: ' '.join(dic.get(key, 'None') for key in 'abc')

Which is no more or less readable than the most confusing perl I've ever encountered.

"Cool Shortcuts" are a problem in any language. There are values in anonymous functions on occasion (especially in sorts), there should be a very compelling reason to do so.

> sub mymethod($$)

That does not work. Prototypes are ignored for method calls. You are expected to not abuse prototypes for signatures as they serve a different purpose.

> it's an untyped language

That's wrong even with the most lenient/charitable interpretation. Using an unexpected type of data is a fatal error.

    perl -e'$x = {}; $x->[0]; print "survived"'
    Not an ARRAY reference at -e line 1.
Type constraints have existed for a very long time, for example see http://p3rl.org/Kavorka::Manual::Signatures#Type-constraints
... but it does, since perl 5.20, which was released May 27, 2014. More than five years ago.

Here's a short example:

    use 5.020_000;
    use warnings;
    use experimental qw<signatures>;
    # this works:
    say add(2, 3);
    # this dies: Too many arguments for subroutine 'main::add' at ...
    say add(2, 3, 4);
    sub add ($x, $y) {
        $x + $y;
    }
This is not a fair comparison.

You golfed the Python to fit on one line with one-letter variable names, while you took a very literal approach with the Perl code.

That's my point, it's not the language itself that changes readability (although personally I find the lack of visual blocks and statement ends in python a right pain). Perl isn't a "write-only language" unless you want it to be.

I'm not a programmer, I'll bash something out to solve a problem and move on, but in general I find reading other peoples perl far easier than reading other peoples python. Maybe that's because I have more experience with perl, because it's well suited for problem solving.

I avoid cpan and pip as much as possible as it makes code much less portable, and unless the module is available in apt (and thus trivial to deploy) it would have to be really compelling to get me to wrap into a custom deb, but that's because I'm not writing products, I'm writing utilities to help run my network.

That was the point they were making, that you can write horribly ugly code in Python if you really put a lot of effort into it, and that you can kinda sorta write readable Perl if you put a lot of effort into it.
If one is marginally literate, one cannot read or write coherently.
You forgot to add:

    ... in any language.