It was Django and the people involved with it.
But, shell scripting has already become somewhat of an arcane skill. I think the article nailed that Perl was just too hard to learn for the value it provided to survive. Python is not nearly as, erm, expressive as perl for working in that space, but it is much easier to learn, both in terms of reading and writing. In other words, it encourages broadly maintainable code. Ruby is quite similar (although I think people massively overstate how much the language itself generally encourages understandable semantics)
my @var = @array # copy the array
my $var = @array # return the count of elements in arrayHis point about references is no small thing. Other dynamic languages don’t make users think much about the distinction between references and values at the syntax level. With Perl you needed to use “->” arrow operator frequently if and only if you were using references. So getting at a map inside an array or vice versa had its own syntax vs reading a string in a map or array.
Also it had bolted on, awkward OO on top of the bolted on, awkward params passing. You literally had to shift “self” (or “this”) off a magical array variable (@_).
By default it wouldn’t warn if you tried to read from an undeclared variable or tried to use one in a conditional or assign from one. You had to declare “use strict;” for that. Which wasn’t hard! But these awkward things piled up, a bunch of small cuts. Don’t forget “use warnings;” also, another thing to put at the top of every Perl file.
To the extent its awkward syntax came out of aping of shell and common Unix cli tools, you could maybe see it as cultural issue if you squint.
But any language in the mid 90s was infected with the “rtfm” priesthood vibe the author writes about, because the internet then was disproportionately populated by those sysop types, especially the part that can answer programming language questions on usenet, which is basically where you had to ask back then.
So for example Rails won for technical reasons, it is much more concise with fewer footguns than its Perl equivalents. I was actively coding web stuff in Perl when it came along and early switched. It wasn’t a cultural thing, having choice in Perl was fine (and ruby has sadly never grown much culture outside Rails - it could really use some). It probably did help that it came along in the mid aughts by which time you could ask questions on the web instead of Usenet. And it used YouTube for that first rails demo. So ruby did end up with a less sysopy culture but that had more to do with the timing of its success than the success itself.
Python is a crappy shell scripting language because the syntax around pipe and subprocess is really clunky.
Perl managed to have decent data structures and also have decent syntax around subprocess calls.
But I feel like the Python invoke module gives me everything I need wrt subprocess calls. I basically write any nontrivial "shell script" these days as a Python invoke command.
GvR explicitly describes the motivation behind Python in similar terms (I can probably find a timestamp in that recent documentary for this). But the goal there was to be fully "general purpose" (and readable and pragmatic, more than artistic) while trying to capture what he saw as the good things about shell languages.
And it's changed quite a bit since then, and there are many things I would say with the benefit of hindsight were clear missteps.
We all joke about the hard problems of computer science, but it seems to me that the hard problems of programming language design, specifically (and perhaps software engineering more generally?) include having good taste and figuring out what to do about reverse compatibility.
> I think the article nailed that Perl was just too hard to learn for the value it provided to survive. Python is not nearly as, erm, expressive as perl for working in that space, but it is much easier to learn
The use cases have also changed over time. Quite a lot of developers ended up on Windows (although that pendulum is perhaps shifting again) where the rules and expectations of "shell" are very different. To say nothing of e.g. web development; long gone are the days of "cgi-bin" everywhere.
And that could be one of major reasons why it lost in popularity. It was and still is easy to write but hard to read.
my($f) = `fortune`; # assigns first line of output to $f.
my $f = `fortune`; # assign all output to $f.
Which allegedly got a HS kid in hot water[^1].[^1]: "It's all about context" (2001): https://archive.ph/IB2kR (http://www.stonehenge.com/merlyn/UnixReview/col38.html)
Perl is not that good a language though for practical purposes. The same way, a breadboard contraption is not what you want to ship as your hardware product, but without it, and the mistakes made and addressed while tinkering with it, the sleek consumer-grade PCB won't be possible to design.
Perl lets every developer write Perl in their own idiosyncratic way.
And every developer does.
It makes for very un-fun times when I'm having to read a file that's been authored by ten developers over ten years, each of whom with varying opinions and skill levels.
I guess in 2026, it'll be 11 developers writing it over 11 years. My sincere apologies to those who come after me, and my sincere fuck-you to those who came before me. :)
And that was, paraphrased: make the way you want something to be used be the most concise way to use it and make the more obscure features be wordy.
This could have been the backbone of an entire community but they diminished it to code golf.
Unfortunately, as a former Perl dev, it makes a lot of other environments feel bland. Often more productive yes, but bland nonetheless. Of the newer languages, Nim does have that non-bland feel. Whether it ends up with significant adoption when Rust and Golang are well established is a different story.
Perhaps too, a tool that's been around and in active maintenance for 11 years has been wildly successful.
Especially in a dynamic language like Perl, you wouldn't know that you're passing down an integer instead of a function until the code blows up in a completely unrelated function.
Things that are cheap to check should be checked first unless they are really unlikely. You change the numbers game from trying to make the biggest cleaving lines possible, to smaller bites that can be done rapidly (and perhaps more importantly, mentally cheaply).
Code smells chum the waters. Because where there is smoke sometimes there is fire, and code smells often hide bugs. You get into Tony Hoare’s Turing award speech; either no bugs are obvious, or there are no obvious bugs.
So I end up making the change easy and then making the easy change because we have more code each week so the existing code needs to be simpler if someone is going to continue to understand the entire thing.
Perl doesn’t seem to have figured this out at all.
Idk about Haskell, but I used Erlang which is also purely functional. No matter how long I used it and tried to appreciate its elegance, it became clear this isn't a convenient way to do things generally. But it was designed well, unlike Scala.
This is why Perl was quite fit for the job at the dawn, or, rather, the detonation phase of the Internet explosion in late 1980s and early 1990s, along with Lisp and Smalltalk that promote similar DIY wizardry values. But once the industry actually appeared and started to mature, more teamwork-friendly languages like Java, PHP, and Python started to take over.
Perl was an early dynamic (garbage collected) “scripting language” but no more advanced than its contemporary python in this regard.
It had the weird sigils due to a poor design choice.
It had the many global cryptic variables and implicit variables due to a poor design choice.
It has the weird use of explicit references because of the bad design choice to flatten lists within lists to one giant list.
It actually was the one thing you said it wasn’t - a good practical general language at least within web and sysadmin worlds. At least until better competitors came along and built up library ecosystems.
This is not a general defense of Perl, which is many times absolutely unreadable, but this example is perfectly comprehensible if you actually are trying to write Perl and not superimpose some other language on it.*
With a team where everybody wrote it in a similar style, Perl did perfectly well. Mod_perl was fast. I liked Perl.
Then Django came out, and then Numpy, and Perl lost. But Python is still so incredibly slow....
It's essentially complaining about using feature wrong on purpose, because the person that made mistake never learned the language.
my($var1, $var2...) is a way to multi-assign variables from an array.
and that makes perfect sense when you look at it. Perl have no multiple returns, but if you need a function that returns 2 variables it is very easy to make it work with:
my ($bandwidth, $latency) = speedtest($host)
Perl's feature for returning different type depending on caller is definitely a confusing part but my @lines = `fortune`
returning lines makes perfect sense for the use case (you call external commands to parse its output, and if you do that you generally want it in lines, because then you can just do foreach my $line (`fortune`) {}
and it "just works".Now you might ask "why make such shortcuts?". Well, one of big mistakes when making Perl is that it was also aimed as replacement for sed/awk for the oneliners, so language is peppered with "clever short ways to do stuff", and it's a pleasure to use in quick ad-hoc oneliners for CLI.... but then people try to use same cleverness in the actual code and it ends up with the unreadable mess people know Perl for.
the fact you can do
my ($first_line, $second_line, ...) = `fortune`
is just the feature being.... consistent in its use "when you give it array, it will fill it with lines from the executed command"you gave it array, and it just did what it does with arrays.
I'm fine with that: to program in Perl you need to be able to follow manuals, man pages, expert answers, - and even perl cookbooks, or CPAN or web searches. It's a technical tool. The swiss army chainsaw. It's worth it.
Shell had to do this because of shell reasons, like how you need spaces where you shouldn't. Perl post-dated C by over a decade, so there was no reason for goofy argument unpacking.
It is, however, a significant language. It has left a mark and influence on the culture and industry of programming. Nothing to sneeze at.
If you go to learn Haskell, you will find that it has a lot to say about functional programming that Erlang did not teach you. You will also find that you've already gotten over one of the major hurdles to writing Haskell, which is writing with immutable values, which significantly reduces the difficult of swallowing the entire language at once and makes it relatively easier. I know it's a relatively easy path because it's the one I took.
But yes, no contest that the world has been on a simplicity binge. Python won by pushing simplicity and by having giant software corporations choosing it (and not complaining about the line noise nonsense). If you want to go into programming professionally, for now many years, you need python.
I don't know that I would put Javascript in the same bag. I mean, it's the other way: it looks simple and it isn't.
But python, yes, python won because it looks simple and google pushed it.
Many other languages now have to reckon with the python supremacy. This is not specific to perl / raku. It will take work for anything to replace python.
Even C gets it's fair share of flack for how it overloads * to mean three different things! (multiplication, pointer declaration, and dereference)
How do you figure?
The essence of FP is functions of the shape `data -> data` rather than `data -> void`, deemphasizing object-based identity, and treating functions as first-class tools for abstraction. There's enough dynamic FP languages at this point to establish that these traits are held in common with the static FP languages. Is Clojure not an FP language?
> It takes more than just having immutable values to be functional, and forcing users to leave varibles as immutable was a mistake, which Elixir fixes.
All data in Elixir is immutable. Bindings can be rebound but the data the bindings point to remains immutable, identical to Erlang.
Elixir just rewrites `x = 1; x = x + 1` to `x1 = 1; x2 = x1 + 1`. The immutable value semantics remain, and anything that sees `x` in between expressions never has its `x` mutated.
> Erlang code in practice is just imperative code written with immutable values, and like a lot of other modern languages, occasional callouts to things borrowed from functional programming like "map", but it is not a functional language in the modern sense.
I did a large amount of Scala prior to doing Erlang/Elixir and while I had a lot of fun with Applicative and Monoid I'm not sure they're the essence of FP. Certainly an important piece of the puzzle but not the totality.
I think this was one of those things people just repeated, rather than having concrete examples from experience. It's like people saying a Toyota Corolla is better than a Honda Civic. Is it really? Or are they really just two different forms of the same thing? They both get you to the grocery store, they're both very reliable, small cheap. Having a preference is not the same thing as one actually being superior to the other.
So @_ was a response to that issue, given Perl was about being dynamic and not typed and there were no IDEs or linters that would type-check and refactor code based on function signatures.
JS had the same issue forever and finally implemented a rest/spread operator in ES6. Python had variadic from the start but no rest operator until Python3. Perl had spread/rest for vargs in the late 80s already. For familiarity, Perl chose the @ operator that meant vargs in bourne shell in the 70s.
It has so many great pieces of advice that apply to any programming task, everything from naming variables, to testing, error handling, code organization, documentation, etc, etc. Ultimately, for timeless advice on programming as a profession the language is immaterial.
array var = array # copied
int var = array # length
or var = array # copied
var = array.to_i # length
is less subtle to me but I can't put my finger on why.Once languages came along that did okay regexes and good hash tables along with getting other stuff decent, Perl just got pushed aside.