1. 38
    1. 20

      When a programmer writes a blog article “Why (language)?”, the answer is always and inevitably: “Because that’s the language that I know.” Everything else is a rounding error.

      Perl is powerful (often, like a grenade). It is ubiquitous. And if you are a one-person show, it may even be usable. But everything else is just lying to one’s self, which makes poor Polonius cry.

      We use the tools that we know. Always has been that way. Always will be that way.

      “The best language to implement ___ in is the one you already know well.”

      1. 33

        Feel free to count this among the rounding errors! I did not know Perl before I made the analysis described and decided to learn it based on those merits. At that time, my Python, for example, was way stronger. (As was my C#, my Haskell, my Lisp, and my R.)

        1. 8

          That is, indeed, surprising. Color me surprised 😊

      2. 3

        But this leaves out how people choose what language to start or continue learning, which I generally assume is what the purpose of these articles is since it’s usually unlikely that they contain much useful information for people who already intimately know how to use the tools they’re talking about.

    2. 9

      How do JavaScript and Python, the 1st and 4th most popular languages in the entire world, have an asterisk next to “ubiquity”? I guess it’s a waste of time to nitpick clearly arbitrary standards in these checkmark feature tables but still, that stood out as being obviously factually incorrect. Perl is way, way down that same list.

      Edit: okay, I see what they mean by ubiquity is “comes pre-installed”. Disregarding that every web browser in the world is a javascript development environment, searching online shows that perl is starting to lose its default install status among newer linux distributions. FreeBSD also intentionally worked to remove it. Seems to still be present on newer versions of macOS, not Windows though.

      1. 12

        Seems to still be present on newer versions of macOS

        It will be a challenge for macOS to stop shipping Perl, since they’ll have to first reimplement their libc’s wordexp which currently uses perl: https://github.com/Apple-FOSS-Mirror/Libc/blob/2ca2ae74647714acfc18674c3114b1a5d3325d7d/gen/wordexp.c#L177-L192

        1. 2

          Ah yeah, the line noise style of C programming where every variable name is abbreviated to be illegible.

          No idea what this does without spending serious time going through it.

      2. 3

        Exactly, with Windows being the most popular desktop environment by far the “it is installed by default everywhere” just doesn’t hold up.

        1. 2

          What would be the most default-installed language if one is interested purely in Windows-based platforms? I don’t use Windows myself but I’m genuinely curious if I’ve missed a more ubiquitous alternative.

          1. 6

            PowerShell, in newer versions of Windows.

            1. 4

              Let’s not bring up the batch language because it is bad.

              PowerShell has come with Windows since 7 sp1.

              Windows Scripting Host has shipped with Windows by default since 98 (was available for 95 but not in the default install) and it comes with VBscript and JScript.

              I believe JScript is a faithful implementation of ES3? ES3 sucks, but it’s a version of ES good enough that you can do all the “JavaScript: the Good Parts” things in it. It’s amenable to structuring data at least.

              I have tried using WSH JScript for some one off task just once to see if it was any good (I think mass renaming mp3 files according to a pattern or something) and I can’t remember anything about the experience other than that a) it worked and b) I think the APIs exposed to it for filesystem and stuff are all synchronous, no callbacks. Seemed reasonable for light accepting.

              1. 3

                You’re conveniently leaving out that every version of Windows shipped with a different version of PowerShell, sometimes SPs were adding a new one and the longer you went back the less features it had. To the point of providing a curl alias that did not behave like curl…

                We tried to replace our batch script for Leiningen with PowerShell but just a few days of testing on all Windows machines I could get a hold of were so sobering that we shelved it.

                It’s a nice idea if you’re operating a fleet of systems with a defined feature set, or are even able to roll out a certain version - but to just hand a random user on the internet a PowerShell script and assume it will work? Nope. Even if that should be better now (who knows?) with just Win10 and Win11 supported, you still have to make them silence the warning that they should not run bad code from the internet.

                I was very surprised about the cool features in PS, way back when they showed it for the first time, but I think to every non-Windows-Admin it will be a niche, if I go by the last.. 15 years or so.

                1. 1

                  Ah, I only mentioned a release timeline for PSH because I wanted to point out that WSH is older and more widely deployed. :)

            2. 3

              I think it starts with an older version of powershell, though.

          2. 2

            Batch still works too. It has loops, conditionals and subroutines. I think that must qualify it as a kind of language. A lot of the concepts that I’ve used in Python and C, I first came across in batch scripts.

            It might be primitive, but you can also execute other programs from batch scripts, so you can make some amazing things happen. You can even add a GUI.

          3. 1

            Windows doesn’t really come with anything “good” installed, unless they recently started installing the latest Powershell. Your best bet is to install Python.

            1. 4

              It comes with a web browser where you can run JS ;-)

        2. 1

          I think Android and iOS both have similar installed bases to Windows these days and I don’t believe either comes with Perl installed either.

      3. 2

        I believe Perl is still used in OpenBSD as part of the build process.


        1. 2

          I don’t think anyone will move to change that anytime soon, either.

    3. 9

      The most important consideration is ubiquity. When throwing out a quick prototype, I don’t want the deployment instructions to start with “First install a development environment.”

      ISTM, that if you want to be able to distribute to arbitrary other computers without installing a dev environment, you want a compiled language with good cross compilation support.

    4. 7

      Honestly, TFA’s not wrong. I’m surprised the CPAN didn’t make the list.

      I learned a little bit of Perl because there was the remnants of a code base that had not yet been ported to the team’s preferred language at my last job. It might be the strangest language I’ve had to approach, but I do admire it for the qualities that the author has described. I sometimes think of continuing to study Perl off to the side.

      1. 6

        I’m a Perl fan, and I appreciate its quirks, but if you look behind the weird syntax with sigils and the tight integration of regexes, it’s just your bog-standard imperative language[1].

        Perl’s blessing (and curse!) is the flexible syntax which enables each programmer to develop their own idioms. That said, I’ve found the documentation to be really good.

        [1] yes I know it has OO now, but it’s taken a lot of hard work to transform a bolt-on to something more polished.

    5. 4

      Tangential question: The font you use on your site, Whitman, is beautiful. When I search for that online, the only place I see to buy it wants to charge thousands of dollars for a self-hosted web license.

      How did you go about using it? Is this a case of “I just downloaded a copy and put it on my site?” If so, I’m definitely not judging, I’m just curious how people go about using web fonts other than Google Fonts.

      1. 3

        I’m crazy enough to pay for typefaces! I don’t remember if I’ve changed anything in this respect (and I should really know the legal status of my site better), but when I launched the site I did have a web license with a foundry that was pretty cheap for low traffic volumes, and they were incredibly lenient about their quotas. I exceeded my license accidentally several times and never got into any trouble for it.

        If you like Whitman, you may also like Fairfield, another strong candidate I looked into before I settled on Whitman.

    6. 4

      What does compatibility mean here? Compatibility with what?

      1. 8

        With itself. “Can I run the same script in a standard install ten years from now and it works?”

        1. 3

          WOW that’s not at all clear from what you wrote. Consider another draft with more detail here. I think it would really help clarify your intent.

        2. 1

          Might want to either asterisk or cross out C#/Java by that metric:

          It would be helpful for sloppy readers like me if your list stated each category name before explaining the property you value, so it’s more clear they tie directly to the chart columns.

          1. 5

            Java’s backwards compatibility is extraordinary (code I wrote 26 years ago still runs without even recompilation), and C# has gotten much, much better at backwards compatibility (10+ years of good compatibility, at least for projects I was involved with).

            Perl has almost reached stasis now, so much less is breaking. But when it was still being augmented, releases would break stuff, including binary compatibility. And a script written only half a decade ago has a fair chance of not working today (e.g. search path changes for security reasons).

            1. 3

              Javascript the language also hasn’t broken backwards compatibility basically but the same is not true of runtime libraries.

          2. 1

            The table columns were meant to mirror the list above – maybe that was unclear. Sorry.

      2. 2

        It’s easier to find a platform that doesn’t run Perl than one that does.


        1. 3

          I like to quip that perl has dropped support for more platforms than $your_language has ever had.

        2. 2

          I think that’s the “ubiquity” column

          1. 1

            This seems correct, my bad!

            1. 2

              Np, your comment made me want to deploy some random extremely uncommon OS lol

    7. 4

      I love using Perl! We switched from PHP at work for certain backend services and scripts, and it’s made maintaining and teaching newcomers much easier. Perl is ubiquitous on Unix-like systems and it’s hands down the best language for quick scripting - it’s a breeze.

    8. 4

      I’m using Kotlin for prototyping. New versions of JVM have startup reduced to sub-second levels, so tools written in Kotlin JVM are perfectly capable of working as small tools. And if not, there’s always Kotlin Native.

      1. 1

        Which versions of JVM? Programming Clojure was always a pain because of the JVM speed.

        1. 4

          Java 18:

          $ time java -cp startuptime-1.0-SNAPSHOT.jar org.example.Main                                        
          Hello world!
          java -cp startuptime-1.0-SNAPSHOT.jar org.example.Main  0.02s user 0.01s system 111% cpu 0.026 total

          Some comparisons:

          $ hyperfine "java -cp startuptime-1.0-SNAPSHOT.jar org.example.Main"          
          Benchmark 1: java -cp startuptime-1.0-SNAPSHOT.jar org.example.Main
          Time (mean ± σ):      24.7 ms ±   1.0 ms    [User: 17.6 ms, System: 10.5 ms]
          Range (min … max):    23.3 ms …  28.7 ms    108 runs
          $ hyperfine "python3 test.py"                                                
          Benchmark 1: python3 test.py
          Time (mean ± σ):      19.3 ms ±   0.8 ms    [User: 15.5 ms, System: 3.8 ms]
          Range (min … max):    18.0 ms …  22.2 ms    131 runs
          $ hyperfine "perl test.pl"                                                  
          Benchmark 1: perl test.pl
          Time (mean ± σ):       1.4 ms ±   0.3 ms    [User: 1.1 ms, System: 1.4 ms]
          Range (min … max):     0.9 ms …   3.2 ms    689 runs
          $ hyperfine "ruby test.rb"                                                   
          Benchmark 1: ruby test.rb
          Time (mean ± σ):      54.0 ms ±   1.3 ms    [User: 45.9 ms, System: 7.8 ms]
          Range (min … max):    52.0 ms …  59.4 ms    48 runs
        2. 1

          JVM startup is a tiny fraction of the Clojure startup time, unless things have changed a lot in the last couple of years.

          1. 1

            They blamed the JVM when I asked why it was taking so long.

            1. 3

              On any computer made in the last decade, the JVM typically takes 100ms or less to start. In contrast, a minimal Clojure program - i.e. literally just nil - takes around a second to run. (At least, it did a couple of years ago, which is when I last used Clojure.)

              If your Clojure program actually does something then it is not unusual for it to take ten seconds to start. That’s a couple of orders of magnitude longer than the JVM startup time.

              I’m pretty sure there used to be something on the Cognitect wiki about this but I don’t know if it’s still around. The problem is that even a minimal Clojure program loads a lot of classes: every Clojure function is implemented as its own Java class and every Clojure program starts by loading at least clojure.core. That’s thousands of Java classes. Once loaded, the classes also have to be initialized and some of them have non-trivial initialization.

              JVM applications are not known for their speedy startup… but that’s compared to native binaries. Normal Java applications still start in a tiny fraction of the time that it takes to start a typical Clojure application.

              However, this isn’t necessarily a problem. If your applications are long-running servers then it’s not a huge problem to wait 30 seconds for them to start. If you develop locally by reloading code into a long-running REPL then you have fast feedback while developing without restarting your application. But it’s definitely not the JVM’s fault that Clojure is slow to start!

              1. 1

                Well nobody in the Clojure community bothered to tell me that it loads thousands of classes. Maybe it’s a dirty little secret.

                I’m unlikely to do much more with Clojure unless I maybe get back into logic programming.

      2. 1

        Or Scala Native, or Graal Native 😉

        1. 1

          True, Graal can even compile Clojure to native code ;)

    9. 4

      I can be confident that a Perl script I write today will run unaltered 10 years from now, modulo external collaborators.

      I think this is one of the most underrated features of languages and their ecosystems.

      It is annoying to do chores just to stay at status quo in a project.

      It also can be a sign of bad architecture when completely is being broken all the time. Don’t get me wrong, everyone does mistakes, but when your API breaks on a regular basis maybe it’s time to take a step back and think things through. It’s hard to get things right at the first time, but thinking about the API and how it will be used in the context of having to break it is something that can and has been done. It baffles me a bit when some framework is released and even as a novice you can see how and why the API will have to be broken.

      Of course there’s the phase of problem space exploration and all of this really depebds on a lot of context. I just sent to point out this is possible and it usually isn’t consideredy as much as other traits. And in certain areas it seems that frequent breakages are considered normal.

      Also don’t get me wrong. I’m on the side of breaking compatibility early if it’s actually necessary, but it should be done in a way to ensure a project with some stability do it’s possible to build upon it without always having to come back to it

      And of course shortly after that comes how important quality documentation of breakage and upgrade paths are.

      Of course stability can come at the price of publicity. People tend to talk a lot more about that new major release than they talk about that thing that flawlessly did its job for 20 years without a hiccup.

      1. 1

        I am really starting to get turned off by projects that break compatibility after an initial exploratory phase. It’s just so rare that the pain of breaking all existing clients is made up for by the nicer (really?) new API.

        1. 3

          I consider it a sign of really bad software engineering. It is sometimes unavoidable. Requirements are never static (you they were, I wouldn’t care about the new version), but if you routinely break consumers then it suggests that you didn’t understand the first set of requirements. If something core to the model has changed (e.g. when LLVM decided to stop encoding pointee types in the type system, for very good reasons) then you expect some churn, but I often see changes that could have trivial compatibility wrappers added and avoided any breaking changes.

          Unfortunately, Google has infected a lot of the open source ecosystem with this mindset. They routinely churn internal things because the have a monorepo and run refactoring tools over all consumers, of an API, but if your API is for external use then this doesn’t work. Open source projects used to be really good at this kind of stability and the older ones (GNU, FreeBSD, and so on) still are, but CADT is a real problem elsewhere.

    10. 3

      I’ve been in a sizeable Perl codebase in the past 5 years and I can say with full conviction: it’s dogshit, it always was dogshit and every such codebase should be deleted or ported to spare other people the misery.

    11. 3

      It is installed by default everywhere.

      Not on RH-based systems/derivatives

      1. 9

        Yes, but apart from Windows, Android, iOS, FreeBSD, RedHat Linux, and Alpine Linux it’s installed everywhere.

      2. 3

        Nor Alpine Linux

      3. 1

        My literally decades-long bet on Debian and dpkg has paid off again.

        1. 2

          Heh yes, well we’ll probably never purge Perl from Debian’s essential packages, but iirc python(-minimal) has joined it, whereas python replaced it in RHEL. Not suggesting one is better than the other, but I think one is better than two.

          1. 1

            Serious question, what would be the rationale for “purging” Perl from Debian?

            1. 2

              Not from Debian as a whole, but from the essential packages. We removed Perl from the FreeBSD base system for a couple of reasons:

              • It’s big. This mattered on things like firewall devices running from flash. Then it mostly didn’t matter. Then containers became a thing and suddenly it did matter again. Putting a copy of Perl in every container just to run a few admin tools is a huge waste.
              • Perl is stable, but people who actually care about Perl often want a newish release. FreeBSD releases are supported for five years, so spew either update Perl through the release (which causes its own problems) or we require people who care about Perl to have two copies installed.
              1. 1

                I’m the first to admit that I know zip about how to construct a Linux for containers, but there’s a difference between “cannot build a distro from source without Perl” and “cannot boot a minimal distro based on Debian at all without Perl”. It’s been a looong time since I looked into the dpkg/deb ecosystem but I’d assume you can use a “big” computer to compile/package a subset of Debian that can then be used in a container. If it’s not possible without including Perl, that makes Debian a bad candidate for container images, but that’s not what Debian was designed to be.

                Circling back to my other comment about OpenBSD, it’s a system that’s been touted as ideal for routers/firewalls/edge systems and it’s been using Perl in its build system since its inception(?)

                The remarks about having an old version of Perl “frozen” in a system is valid. I once managed to wedge an OpenBSD system pretty hard by updating Perl out of order of build world. Fun times.

    12. 2

      First off, I think opinion pieces like this have a place in the world, so thank you @kqr for authoring it and sharing it here. That said, I have some Alternative Opinions in response that I offer in good spirit:

      With a great amount of discipline, Perl scripts can be successfully scaled up into large, complex systems.

      How can anyone possible see this as a selling point? Why not bash? It’s even more ubiquitous and requires even fewer administrative rights.

      Also, I have some bones to pick with @kqr’s views on Python:

      • Not compatible? With what? Python runs on just about every modern platform known to man, including AS400 based mainframe systems and OpenVMS!
      • Not extensible? Python’s ASTs mean you can extend the language and its syntax to a ludicrous degree. Proof point: Hy.
      • Not good for shell scripting? Python has been used in a multitude of organizations across the globe for exactly this purpose. It has superlative subprocess control and very good facilities for interacting with the shell itself where that becomes necessary.
      1. 5

        Not compatible?

        I believe the author means “forward compatibility with itself”. I seem to recall hearing that python may have had a few little issues with old code not working on newer versions…

        1. 2

          I am now aware :) But that wasn’t at all clear as written.

          That said, while it’s true that Python has had major breaking changes from one major language version to the other (notably 2 to 3) this was made incredibly clear.

          This is one of those tough choices in how you choose to evolve your language. Maintain infinite backwards compatibility and wear that strait jacket with pride (as Perl does, to their credit) or be SUPER clear about what’s changing and work INCREDIBLY hard to help the community come along.

          That’s what happened with Python. There are still Python 2 projects out there, but they are rare, and generally not actively maintained with a very small number of exceptions.

          1. 12

            Worth clarifying that Python 3 does not maintain forward compatibility between minor versions.

            1. 3

              Usually, there is an official deprecation period, so you get some prior warning, but yes, there was e.g. a big break at 3.7 when async went from being a special identifier to a true keyword.

      2. 2

        It has superlative subprocess control and very good facilities for interacting with the shell itself where that becomes necessary.

        Although I don’t know Python myself, I’m aware of a relevant library Duct that has a list of “Gotchas, bugs, and platform inconsistencies” that occur in running subprocesses. While Python (it implies) doesn’t protect against these by default, it does have this library that tries to.

      3. 1

        Re shell scripting: Python is very capable of this and I would guess that both Perl and Python have the same features for subprocesses. But the Perl language was designed from day one to provide highly ergonomic syntax level facilities for these things. Ex Perl backticks

        1. 1

          This is an area where we start to get into philosophy :)

          Python generally chooses syntactic regularity (Or as I like to call it ‘un-cleverness’) over “sugar” that lets people use the same syntax they’re used to from other languages.

          So while Bourne shell hackers will see the `` and it will feel familiar, Python chooses the standard funcall() syntax e.g: subprocess.run().

          We could argue infinitely over which is better. I personally think regular syntax is important, but mileage DOES vary :)

          1. 2

            I’m all for Python’s original intent being an allergic reaction to the aesthetic of Perl’s syntax. Python’s syntactic regularity does not shine when it is being assessed for fitness in writing shell-like scripts.

            1. 1

              I think that’s arguable.

              1. 2


    13. 2

      if you want some website feedback, I scrolled to the bottom looking for the first footnote before realizing it was in a light font to the right

      1. 1

        I always appreciate that. That text should have higher contrast. I don’t know what I was thinking. Thanks for letting me know!