Remix.run Logo
superkuh 3 hours ago

Perl's "decline" saved it from a fate worst than death: popularity and splitting into dozens of incompatible versions from added/removed features (like python). Instead Perl is just available everywhere in the same stable form. Scripts always can just use the system perl interpreter. And most of the time a script written in $currentyear can run just as well on a perl system interpreter from 2 decades ago (and vice versa). It is the perfect language for system adminstration and personal use. Even if it isn't for machine learning and those kinds of bleeding edge things that need constant major changes. There are trade-offs.

This kind of ubiquitous availablility (from early popularity) combined with the huge drop-off in popularity due to raku/etc, lead to a unique and very valuable situation unmatched by any other comparable language. Perl just works everywhere. No containers, no dep hell, no specific versions of the language needed. Perl is Perl and it does what it always has reliably.

I love it. The decline was a savior.

amiga386 3 hours ago | parent | next [-]

Perl's binary brings with it the ability to run every release of the language, from 5.8 onwards. You can mix and match Perl 5.30 code with 5.8 code with 5.20 code, whatever, just say "use v5.20.0;" at the start of each module or script.

By comparison, Python can barely go one version without both introducing new things and removing old things from the language, so anything written in Python is only safe for a a fragile, narrow window of versions, and anything written for it needs to keep being updated just to stay where it is.

Python interpreter: if you can tell "print" is being used as a keyword rather than a function call, in order to scold the programmer for doing that, you can equally just perform the function call.

zahlman 2 hours ago | parent | next [-]

> By comparison, Python can barely go one version without both introducing new things and removing old things from the language

Overwhelmingly, what gets removed is from the standard library, and it's extremely old stuff. As recently as 3.11 you could use `distutils` (the predecessor to Setuptools). And in 3.12 you could still use `pipes` (a predecessor to `subprocess` that nobody ever talked about even when `subprocess` was new; `subprocess` was viewed as directly replacing DIY with `os.system` and the `os.exec` family). And `sunau`. And `telnetlib`.

Can you show me a real-world package that was held back because the code needed a feature or semantics from the interpreter* of a 3.x Python version that was going EOL?

> Python interpreter: if you can tell "print" is being used as a keyword rather than a function call, in order to scold the programmer for doing that, you can equally just perform the function call.

No, that doesn't work because the statement form has radically different semantics. You'd need to keep the entire grammar for it (and decide what to do if someone tries to embed a "print statement" in a larger expression). Plus the function calls can usually be parsed as the statement form with entirely permissible parentheses, so you have to decide whether a file that uses the statement should switch everything over to the legacy parsing. Plus the function call affords syntax that doesn't work with the original statement form, so you have to decide whether to accept those as well, or else how to report the error. Plus in 2.7, surrounding parentheses are not redundant, and change the meaning:

  $ py2.7 
  Python 2.7.18 (default, Feb 20 2025, 09:47:11) 
  [GCC 13.3.0] on linux2
  Type "help", "copyright", "credits" or "license" for more information.
  >>> print('foo', 'bar')
  ('foo', 'bar')
  >>> print 'foo', 'bar'
  foo bar
The incompatible bytes/string handling is also a fundamental shift. You would at least need a pragma.
0xDEAFBEAD 3 hours ago | parent | prev [-]

The Python approach seems better for avoiding subtle bugs. TIMTOWTDI vs "there should be one obvious way to do it" again.

cedilla 3 hours ago | parent | prev | next [-]

What incompatible versions of pythons do you mean? I'm entirely unaware of any forks, and the youngest version I have to supply at the moment is 3.9, which is over 5 years old and available in all supported platforms.

superkuh 3 hours ago | parent [-]

Try to run any random python program of moderate dep use on your python 3.9 system interpreter without using containers. Most likely you'll have to use a venv or the like and setup a special version of python just for that application. It's the standard now because system Python can't do it. In practice, pragmatically, there is no Python. Only pythons. And that's not even getting in to the major breakages in point version upgrades or the whole python 2 to 3 language switch.

zahlman 2 hours ago | parent [-]

> Most likely you'll have to use a venv or the like and setup a special version of python just for that application.

Using venvs is trivial (and orders of magnitude more lightweight than a container). And virtually every popular package has a policy of supporting at least all currently supported Python versions with each new release.

You need to set up a venv because of how the language is designed, and how it has always worked since the beginning. Python doesn't accommodate multiple versions of a package in the same runtime environment, full stop. The syntax doesn't provide for version numbers on imports. Imports are cached by symbolic name and everyone is explicitly expected to rely on this for program correctness (i.e., your library can have global state and the client will get a singleton module object). People just didn't notice/care because the entire "ecosystem" concept didn't exist yet.

I have at least one local from-source build of every Python from 3.3-3.14 inclusive (plus 2.7); it's easy to do. But I have them explicitly for testing, not because using someone else's project forces me to. The ecosystem is just not like that unless perhaps you are specifically using some sort of PyTorch/CUDA/Tensorflow related stack.

> It's the standard now because system Python can't do it.

Your system Python absolutely can have packages installed into it. The restrictions are because your Linux distro wants to be able to manage the system environment. The system package manager shouldn't have to grok files that it didn't put there, and system tools shouldn't have to risk picking up a dependency you put there. Please read https://peps.python.org/pep-0668/, especially the motivation and rationale sections.

> major breakages in point version upgrades

I can think of exactly one (`async` becoming a keyword, breaking Tensorflow that was using it as a parameter name). And they responded to that by introducing the concept of soft keywords. Beyond that, it's just not a thing for your code to become syntactically invalid or to change in semantics because of a 3.x point version change. It's just the standard library that has changes or removals. You can trivially fix this by vendoring the old code.

keepamovin 3 hours ago | parent | prev [-]

My language learning trajectory (from 10 years old) was 8086 assembly, QBASIC, C, Perl, Java, MAGMA, JavaScript/HTML/CSS, Python, Haskell, C++, vibe coding

pomatic 3 hours ago | parent [-]

How old are you now? Mid fifties here. And 'vibe coding' in what exactly - it is not of interest from a programming perspective, but from a 'what does the AI know best perspective'? I've followed a similar, but not identical trajectory and now vibe in python/htmx/flask without needing to review the code in depth (NB internal apps, not public facing ones), with claude code max. Vibe coding in the last 6-8 weeks now also seems to make a decent fist of embedded coding - esp32/arduino/esp-32, also claude code.