Hacker News new | past | comments | ask | show | jobs | submit login

> In contrast, Python encourages the creation of monoliths of the type McIlroy criticized.

unfair and gratuitous criticism of python... i have seen and written many small tools you can run using "python -m".




As someone who uses both languages extensively, I disagree.

You are right that Python is great for writing small tools that you can run, just like Perl.

But Python does not lend itself to writing them inline in a command line like was done here. Perl not only does, but has a number of useful features specifically added to fit this common use case. 3 of which were used in this example. (-a for autosplit, -M to load a module, and -e to have the code passed as an argument on the command line rather than having to have it saved to a file.)

Secondly, Perl lends itself to being used as a "better shell" while Python does not.

What I mean is that anything that can be written in bash can be trivially rewritten in Perl, and the program that you get tends to be substantially more maintainable if the bash script is at all complex. In such a rewrite there usually isn't a good reason to change the structure of the program and make it into a single Perl program.

By contrast Python has focused on the "One True Way" to do things, and the plumbing work for calling external commands is just verbose enough that a Python rewrite of a bash script is not necessarily better than the bash script. And furthermore it is much more likely that the Python rewrite of the bash script is much better rewritten as a Python script.

The result is that for someone who lives on the Unix command line, Perl integrates into their world better than Python does. If you have never lived on the Unix command line, the objections may sound silly. But spend months typing commands and doing the extra steps that Python requires Every Single Time will get old.

(This is historically not surprising. Perl 1 was focused on generating text reports. Perl 2 moved into being a sysadmin tool. Perl wound up as a web language because it is what all of the sysadmins recommended for text manipulation to people writing early CGI scripts.)


Perl's big win for one-liners is braces syntax. Interestingly, there are already projects to add braces syntax[1].

Two of the three Perl features are also Python features, namely -m to run a module and -c to run code on the command line.

Regarding Perl being a better shell, there are modules like `doit` and `invoke` that make Python far better than perl for managing jobs, precisely because they make forking off jobs super easy.

But now that you mention it... I want to write a module to make python one-liners easy.

[1]: https://pypi.org/project/brackets/


Can you show an example of using doit and invoke to fork off jobs in Python? I’m pretty sure Perl has had similar functionality for some time.


Yeah, perl borrows backticks from bash[3], so it's giving you syntax to do it directly, and it's long had strong support for opening a process using a very intuitive syntax.

Python's subprocess module works quite well, but gets extremely verbose[4] as you try to do anything more complex than "run a command and get the output" and has some nasty gotchas[2].

I forget the invoke syntax, but doit[1] is basically a make replacement so calling the shell is pretty easy:

    def task_something():
        return {'actions': ['ls foo/', 'rm -r foo']}
And you can use outputs from one task as inputs for another, it tracks what's been done, etc.

[1]: https://pydoit.org/

[2]: https://docs.python.org/3/library/subprocess.html#subprocess...

[3]: https://perldoc.perl.org/5.30.0/perlop.html#qx%2f_STRING_%2f

[4]: https://docs.python.org/3/library/subprocess.html#popen-cons...


How can one do something like fork/exec in python? That's what I was thinking of when you mentioned "forking off jobs".

There are a number of different ways to launch an external process from Perl, I think this StackOverflow answer summarizes them quite well:

https://stackoverflow.com/a/800105

I'm an experienced Perl user, but I'm not as familiar with Python. In addition, I'm not really using Perl for sysadmin stuff, so I tend to try to keep stuff "within" Perl. As an example, I'd rather use the File::Find module than use backticks to invoke `find`. This has really nothing to do with functionality - I'm almost always on Linux, and the syntaxes are similarly hairy - it's just that usually you get more powerful functionality using the Perl functionality.

(edit rearranged paragraphs)


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?


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.


How does Ruby compare to Perl and Python for these tasks?


Ruby is about equal to Perl as a language for interactive command line usage, and both are better than Python.

Comparing RubyGems to CPAN, CPAN is about 2x as large, has a better infrastructure, better testing, and is generally better.

Comparing CPAN to PyPI (the Python version), they are about the same size, PyPI has a worse testing story, has more up to date modules, is growing faster and seems to be of similar quality. If you want write a system that integrates with a recent standard, support from Google, or to use something like machine learning, Python is the clear winner.

Adding JavaScript, I consider node.js to have the worst command line story, worst repository system, but it is extremely popular.

I personally use Perl for command line stuff and Python otherwise. I use JavaScript when I have to (and sadly I have to a lot). It is rare for me to bother with Ruby. But I learned Perl first, and have written more in Perl than the others combined.

Does this answer your question fully?


Perl starts up really, really fast though, so invoking it repeatedly in a pipeline is more practical than with a Python program for that reason.




Consider applying for YC's Fall 2025 batch! Applications are open till Aug 4

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: