Hacker News new | ask | show | jobs
by codetrotter 2308 days ago
I use a few different languages, one of which is Python, and I use the command line a lot, and I agree that Python is too verbose for a lot of the things that I do on the command line. Therefore, Python is not something that I reach for when doing simple tasks involving pipelines and/or file operations.

I have not yet put time into learning Perl. In no small part because I was intimidated by the weirdness of some of the Perl code that I've seen. The terseness that Perl allows, and which I desire, is at once compelling and scary at the same time. For this Perl also has earned the reputation that it "Write Once, Read Never".

But let's assume that I overcome my fear of Perl. Which version of Perl would you recommend that I learn? Perl 5 or the language formerly known as Perl 6?

4 comments

Perl5. Some version of perl5 is available by default on just about everything and can be counted on in a similar manner as counting on awk to be there for you.

I'm not going to defend Perl's readability, there are many opus's online in both directions. Suffice it to say that Perl is still a really good tool for certain $jobs.

For learning Perl, I used this: https://qntm.org/perl_en followed by some trial and error, followed by the book Modern Perl, then Higher Order Perl. glhf! Perl hacking is a blast

Learn Perl 5. Perl 6 is an interesting research project for future directions that it doesn't look like the programming world will go.

Most of the weirdness of Perl goes away when you read $ as "the", @ as "these" and a hash lookup as "of".

That's not exactly fair to Raku. A more fair critique (and keeping with the theme of this thread) is that Raku is less focused on integrating with the Unix command line than it is on tool building putting it closer to Python than Perl(5) in the spectrum of things. This was a specific design influence dating back to the first days of Perl 6, so it makes some sense.
That's not exactly fair to Raku.

I know that Raku supporters disagree with me, but that has been my considered opinion for several years. And this has been something I put a lot of thought into.

Let me lay out the case.

What are the key ideas invented or promoted in Perl 6 / Raku that people get excited about?

- Object-oriented programming including generics, roles and multiple dispatch

- Functional programming primitives, lazy and eager list evaluation, junctions, autothreading and hyperoperators (vector operators)

- Parallelism, concurrency, and asynchrony including multi-core support

- Definable grammars for pattern matching and generalized string processing

- Optional and gradual typing

I got this list from https://www.raku.org/. It is what Raku people think is interesting about their own language. (So I don't get to bring up things I really don't like, like twigils.)

Some of these ideas are mainstream, some not. According to Tiobe (yes, not to be taken seriously but it is accurate enough), the top languages today are Java, C, Python, C++ and C#. Let's eliminate from the list of Raku features anything that is supported by at least 2 of them to come up with things that are novel in Raku while not being broadly adopted today. The list gets much shorter.

- Roles (OO programming)

- Junctions, autothreading and hyperoperators (functional programming).

- Definable grammars for pattern matching and generalized string processing

- Optional and gradual typing

How many of these will be widely adopted by top languages in 25 years? My best estimate is 1. Could be none, could be 2, I'd be shocked if there were 3.

I say opinion, but it is a fairly well educated opinion. Here is my argument about each.

- Roles. They have been around for some years. The only language where I have seen them used heavily is Perl 5. Nobody else seems excited.

- Junctions are mostly a bit of syntax around any/all which is pretty convenient already. Autothreading and hyperoperators are a cool sounding way to parallelize stuff, but getting good parallel performance is complex and counterintuitive. I don't think that this is a good approach.

- Definable grammars are an interesting rethinking of regexes, but parsing is a difficult and specialized problem. I don't see an interesting approach in an unpopular language changing how the world tackles it.

- Optional and gradual typing sounded great when it made it into the Common Lisp standard. But over 30 years later, only Python supports it of the top 5. And it isn't widely used there. I see nothing about the next 25 years that makes it more compelling than in the last 25. (Though Raku's implementation is far, far better than Perl 5's broken prototype system. But that is damning with faint praise.)

So use Raku if you find it fun. You'll get a view into an alternate universe of might have beens. But I still believe that the ideas that are new to you won't be particularly relevant to the future of programming.

-----

It is hard at this date to make what a similar list would have been for Perl 5 at a similar stage. People were excited about CPAN. Perl people kind of took TAP unit testing for granted and didn't appreciate exactly how important it was. Perl people liked the improvements in regular expressions but probably couldn't have guessed how influential "perl compatible regular expressions" would become across languages. Ideas we were excited about like "taint mode" went approximately nowhere. And some ideas that Perl helped popularize, like closures, were ones that few Perl programmers realized were actually supported by the language.

However it would be a true shocker if Raku was anywhere near as influential on the programming landscape 25 years from now.

> Junctions are mostly a bit of syntax around any/all

A quick look at Raku junctions makes me think they're basically a slightly tarted-up version of Icon's generators and goal-directed execution (which is no bad thing, of course but hardly novel.)

Then you definitely did not grok it. What I gather from https://en.wikipedia.org/wiki/Icon_(programming_language)#Go... is that Icon's goal directed execution is more like `react whenever` in Raku (https://docs.raku.org/language/concurrency#whenever)

Junctions autothread. What does that mean? Using a Junction as an ordinary value, will cause execution for each of the eigenstates, and result in another Junction with the result of each of the executions. An example:

    # a simple sub showing its arg, returning twice the value
    sub foo($bar) { say $bar; 2 * $bar }

    # a simple "or" junction
    my $a = 1 | 2 | 3;
    say foo($a);  # executes for each of eigenstates
    # 1
    # 2
    # 3
    # any(2, 4, 6)
Documentation: https://docs.raku.org/type/Junction
Multi-threading and Junctions auto-threading are NOT the same thing.

Calling it auto-threading has lead many people to the wrong conclusion.

(It is possible that auto-threading may be done multi-threaded in the future, but it doesn't do it currently.)

Roles take the place of all of these:

- Java interfaces

- abstract classes

- C++ templates

- Python mixins

- Smalltalk traits

So are you telling me that you haven't used any of those?

---

Roles combine all of those features very simply.

    role Interface {
        method hello-world ( --> Str ) {...}
        # the ... means it needs to be implemented by consuming class
    }

    role Abstract {
        has Str $.name is required;
        # adds an accessor method of the same name

        method greet ( --> Str ) {...}
    }

    role Template[ Real ::Type, Type \initial-value ] {
        has Type $!value = initial-value;

        method get ( --> Type ) {
            $!value
        }
        method set ( Type \new-value ) {
            $!value = new-value
        }
    }


    my $value = 42 but anon role Mixin {
        method Str ( --> 'Life, the Universe and Everything' ){
        }
    }
Roles were heavily influenced by Smalltalk traits. Rather than being limited to those uses, Roles were expanded to include all of those other use-cases as well.

---

Really Roles are a better method of code-reuse than inheritance.

    role Animal {
        method species      ( --> Str  ){...}
        method produces-egg ( --> Bool ){...}
    }

    role Mammal does Animal {
        method produces-egg ( --> False ){
            # most mammals do not produce eggs.
        }
    }

    role Can-Fly {
        method flap-wings ( --> 'flap flap' ){
        }
    }



    class Bat does Mammal does Can-Fly {
        method species ( --> 'Bat' ){
        }
    }

    class Bird does Animal does Can-Fly {
        method species ( --> 'Bird' ){
        }

        method produces-egg ( --> True ) {
        }
    }

    class Platypus does Mammal {
        method species ( --> 'Platypus' ){
        }

        method produces-egg ( --> True ) {
            # override Mammal.produces-egg()
        }
    }
Of course a simple example doesn't do this ability justice. It really shines on large code-bases.

For a better example see: “Curtis Poe (Ovid) - Roles versus Inheritance” https://www.youtube.com/watch?v=cjoWu4eq1Tw

That is of course about roles in Perl, which doesn't have all the same features. All of the points do apply to Raku roles though.

---

Raku has so many good ideas it would be a waste if other languages didn't copy at least some of them. I of course can understand if a single language doesn't want to copy all of them at the same time.

It would definitely be a waste if no other language tries to combine regular expressions, parsers, and objects like Raku grammars have done.

At the very least Raku regular expressions are easier to understand than Perl compatible regular expressions. (Note that I very much DO understand PCRE syntax, having used it heavily in Perl for many years.)

Compare the Raku grammar for JSON https://modules.raku.org/dist/JSON::Tiny:cpan:MORITZ/lib/JSO... to the Perl version https://metacpan.org/release/JSON-Decode-Regexp/source/lib/J...

I would like to point out that when JSON started allowing any value as a top-level result, it actually made the Raku code simpler. https://github.com/moritz/json/commit/9888329771730574967197...

Perl 6 was indeed an interesting research project. Raku is much more than that.

BTW, now that Perl 6 has been renamed to Raku, you can drop the "5" from "Perl 5", and just call it "Perl". Saves on typing!

Re: learning Perl: by all means, but don't let that stop you from learning Raku as well.

Depends on what you want to achieve: do you want to be where the puck has been, or where the puck will be? Both approaches have their pros and cons.
I am willing to bet you $1000 that in 2030 there are more jobs on general $job_board of your choice that mention Perl than Raku.

We can say 2040 if you think that 2030 may be too soon for Raku to have any chance at all. But there is a good chance that one of us will be dead by then. (I'll be 70, I think you'll be in your 80s.)

My point being that if you yourself are not confident enough to take some bet of that form, you cannot expect people to take you seriously when you describe Raku as "where the puck will be". Particularly not people who are happy to explain why they think that Raku won't do that, and are willing to make bets of that kind.

> I am willing to bet you $1000 that in 2030 there are more jobs on general $job_board of your choice that mention Perl than Raku.

Bet taken. With the current rate of Perl's decline, I think that's a very safe bet to take.

> I'll be 70, I think you'll be in your 80s.

I know I'm an old hack, but not that old: I'll be 73 for 98% of 2030.

Bet taken. With the current rate of Perl's decline, I think that's a very safe bet to take.

Awesome. I know how hard it is to get rid of legacy code, and there are a lot more startups that I'm aware of starting with Perl today than starting with Raku.

I know I'm an old hack, but not that old: I'll be 73 for 98% of 2030.

The "then" that I was referring to in that sentence was 20 years from now. Which is 2040. As I said, you'll be in your 80s at that point.

The bet is for 2030. Let's be clear about that then :-)
Ruby is the best version of Perl. You can do command line one-liners and full-on object-oriented (SmallTalk object model) readable, maintainable programs.
My impression 20 years ago was that Ruby is an interesting mix between Perl and Python. In principle there is little that differentiates Perl and Ruby in terms of how maintainable or not their code can be.

However the Ruby ecosystem wound up with a lot of modules contributed by people who had just moved to it from languages like Java. They overreacted to their new found freedom. The result is that between a poor testing story and questionable practices like "monkeypatching" (literally modules overwriting random methods in other modules) the Ruby ecosystem wound up with a lot of nasty gotchas. (There is a lot of, "f you load module A then B, it works, but module B then A and it doesn't.")

Yes, Ruby programmers get up in arms when you say that they have a poor testing story. But ask them whether by default they have actually run unit tests for everything installed on their system, and they have not. Ask them if they could run unit tests and they think they can. But those who I have watched try have found out the hard way how many unit tests were only written for the original author to run in the original environment, and can't easily be run in an automated way. By contrast the default for CPAN is that every module has had its unit tests run on every system it is installed in, and automated smoke tests ensure that modules have had their tests run on a wide variety of operating systems and versions of Perl.

The result is that random Ruby module X is generally less likely to be dependable than random Perl module Y. Which in turn means that in my experience significant Ruby code bases written by competent programmers top out at smaller than Perl, with worse maintenance stories.

That doesn't discount the fact that there has been a tremendous amount of unmaintainable Perl written by incompetent programmers. (Particularly during the wild dot com days.) But "maintainable" is NOT something that Ruby has a good story to tell about.