Hacker News new | past | comments | ask | show | jobs | submit login
Why Perl? (two-wrongs.com)
141 points by susam on April 20, 2023 | hide | past | favorite | 198 comments



Years ago Larry Wall presented a graph of programming languages with the axes labeled "whipupitude" and "manipulexity". Perl excels at both. It's still my go-to for tasks requiring a lot of text manipulation, or with just a bit too much complexity to be a shell script. Perl code does look odd at first, but it gets an unfair rap on that point - there are plenty of popular languages that are hard to mentally parse without some background.


I love these terms. I find it delightful when he, and others, have fun with language in this way. It's the same feeling I got when learning Perl and discovering constructs like unless/until, because _of course_ those exist. Breaking from the norm and enjoying the freedom and flexibility of language that is so often overlooked.


Years ago I coined the phrase “Perlaphobia”, the fear that Perl will come back into my life again and again, and every time it happens I have to relearn it all over again almost from scratch.

Still happens about every five years, although I am reaching for Python more and more in those situations.

What always kills me is the weirdness of the basic data structures, array/stack function calls, and the truly impressively weird ways Objects are done.


> What always kills me is the weirdness of the basic data structures, > array/stack function calls, and the truly impressively weird ways > Objects are done.

Well, Perl 5 has scalars, arrays and dictionaries -- just like Python. Unlike Python, however, Perl function arguments are always implicit/variadic by default (and stored inside the implicit "@_" variable). This can be a benefit or a curse depending on the context. Furthermore, Perl 5 does support both "call by value" and "call by reference". This distinction can confuse programmers coming from more modern languages where usually everything is a scalar reference. But you have to keep in mind Perl was invented in the 80s and put great emphasis on compatibility. Changing calling conventions would have broken many modules.

edit:

Regarding objects: The object system is rather simple, it's just many Perl hackers invented their own object systems on top of that. Basically, a Perl class is just a module. An object is just a reference to a dictionary that got the class name attached by applying the "bless" operator:

  package Foo;

  sub new {
    my ($class) = @_;
    my $object = {};

    bless $object, $class;
  }

  sub do_stuff {
    my ($self) = @_;

    # do stuff

    return $self;
  }

  my $obj = Foo->new();
  $obj->do_stuff()->do_stuff();

That's about it! Well, you also have inheritance using "use base ..." and you can bless other fundamental types which usually is not a bright idea. Many other object oriented languages make object orientation unnecessarily much more complex (looking at you C++).


Or my favorite:

    package Foo {
        use MooseX::Extended;

        sub do_stuff ($self) {
            # do stuff

            return $self;
        }
    }

    my $obj = Foo->new;
    $obj->do_stuff->do_stuff;


All true. But you have to factor in all the historical baggage, things like the weirdness of Files, introduction of references,etc.

It all just ends up feeling deeply weirds and unique compared to other languages. Hence the need to relearn it every time I touch it.


I worked briefly at a shop that maintained a complex outsourced project by Yahoo (some ad bidding optimizations pipeline).

As it turns out, they used Perl, one of the few sanctioned languages at Yahoo.

The coding style handed over from the client forbade every other thing that Perl fans tell you that make the language warm and endearing to them; you were allowed to use about a few of the sigil variables, all the data structures were to be used in their "object reference" form, because it sidestepped the "contexts" functionality of Perl, which was to be avoided at all costs.

I remember the tedium of having to maintain your own stacktrace, because all you got was a the `$@`, `$!` and `$?` variables, which contained precisely the last of various types of error encountered during execution within the process. If you encountered errors while performing error handling, the original error would be lost, so you had to keep a backup.

Edit: man, the contexts, the fans sweared by them, making analogies to natural language; I'm sorry to sound elitist, but they often came across as enthusiastic amateurs rather than people with a formal background in Computer Science. They claimed that things like passing an array to a place where an integer is expected to get the length was richness, not insanity.


> I remember the tedium of having to maintain your own stacktrace

With Carp::confess you get the stack trace easily when throwing an exception. It's been a core module for ages.

Of course, Perl lacks a flexible condition system like Common Lisp. So all you got is an exception object you can try to handle but no restart handlers you can use to go back down the stack trace. But that's a common limitation of almost all languages supporting exceptions natively.


I worked at Yahoo, and it was Perl and PHP. Sheer madness.

Their were some talented folks but I'd like them more to cowboys - git'r done instead disciplined engineers.

Lots of production applications that had the code quality of your typical hacky side project.

I once had a debate with my manager about classes/OOP in PHP5. He didn't like it because it usually meant having separate files and includes per class, and he likes to have all code for a PHP page in a single pane in Vim. "But Kenny it's all in one file, everything I need to work on is right here!"

I still laugh about that.


> Lots of production applications that had the code quality of your typical hacky side project.

We laugh about it now, but that's why we end up with things like this:

https://www.nytimes.com/2017/10/03/technology/yahoo-hack-3-b...


I'm also shock that in Perl you can alter your return type based on the type of variable the caller is putting your result in.

https://perlmaven.com/wantarray

That always appeared as madness to me. Why would you make things that cryptic to understand?


If a Perl script is written and maintained by just one person, or a few people who can agree with each other, then features like that are not a problem: you just agree not to use them. They are, however, an argument for not using Perl for a big project that lots of people will work on.


> I'm also shock that in Perl you can alter your return type based on the type of variable the caller is putting your result in.

You can do that in Java, if I understand that feature correctly.

For example, it's possible to write a method that returns a generic type over whatever type you're trying to assign to, e.g.:

    static <T> List<T> listOfAnything() { return (List<T>) new ArrayList(); }
Which can be used like this:

    List<String> stringList = listOfAnything();
Or by letting the compiler infer the type from the return type of a method:

    List<Integer> listOfInts() { return listOfAnything(); }
This is not just some esoteric feature... it's quite commonly used by, for example, deserialization libraries and functional programming.


That trick "works" in Java because, for compatibility reasons (Java didn't have generics originally), the generic type is erased by the compiler. Your example compiles to:

    static List listOfAnything() { return (List) new ArrayList(); }

    List stringList = listOfAnything();

    List listOfInts() { return listOfAnything(); }
The generic type isn't monomorphised or even reified; within your method, you don't have access to the generic type T "passed" by the caller. If you need it, you have to pass it explicitly, as commonly used by deserialization libraries:

    static <T> T deserialize(String input, Class<T> cls) { ... }
Which can be used like this:

    MyStruct result = deserialize(input, MyStruct.class);
Note that the deserialization library has no way of knowing the type of the variable the caller is putting the result in, the caller had to pass it explicitly. This is because what the Java compiler actually generated from the code above was something like:

    static Object deserialize(String input, Class cls) { ... }

    MyStruct result = (MyStruct) deserialize(input, MyStruct.class);


It's possible for the deserialization library to know the type from the payload itself, but of course it has to "happen" to coincide with what's being cast to. You don't need to pass the Class object at all.


Generics are awesome. They allow you to do partial typing. You don't specify the exact type but you constrain the output type based on the input type. So you have functions that can operate on many types but still have strong typing.

Wantarray is not a generic implementation. It's closer to reflection. You can detect the type of variable the caller is putting your functions result in. Then you can branch your program based on the variable type that the caller wants. I guess this is similar to type inference but not exactly as it's not part of the type system. For example, if they want an array return the amounts of each transaction in an array if not return the sum of the transaction amounts.


Those are all the same underneath. Perl's scalar / array duality is a bit more of a difference.


And that well-studied for of polymorphism is entirely unlike having the callee knowing if the caller expects an array or an it, and changing the result.


wantarray() is a sensing operation that allows a type of transparent function overloading: Oh you wanted just a scalar? OK.

Python's ordered arguments mixed with out of order labeled arguments is worse IMO: Tell me arguments in this order. Or not... I mean, you could just tell me which they are. Wait, I got two of these... F*ck this, I quit


Isn't Python's mixing rules very simple?

(1) Un-named arguments come before any named arguments and should be passed in order (this is familiar to programmers in almost any mainstream language).

(2) Named arguments can then follow, in whatever order.


Yes, they not complicated, and I imagine it's a non issue for most.

The interface is awkward however in that in other languages you would overload the function or pass a data structure, or reference of one, to manage additional optional parameters when you didn't want the extra arguments explicitly listed.

Python is a popular language and there are a ton of contributors who have developed third party packages. Unfortunately, these are not always well written or maintained and it can be easy to stumble across a bad one when looking for useful things. It's never fun to debug code in an unfamiliar language.


Yes but if you want to know an arrays length you can just put it in a scalar. So you consume some API and want to get the length of the result. You put the array result into a scalar variable. Then what this is not the length?


The API documentation should reflect that the result is context sensitive. Not reading that is a good way to get burned despite the language.

Perl is well known for it's multitude of idiosyncrasies, this is one of the reasons why it can be frustrating to programmers who have better experience in more modern or rigidly structured languages.


That particular API would have been much better had it been documented.


If only there was some well written book about Learning Perl, or well written documentation in the form of manual pages (see perldata).


That doesn't cover this particular third party API.


*nix applications also can alter thier output based on where it's going, e.g. to a pipe or to a file.


That's actually a good point. It seems to work well in that context. I'm not sure I have an entirely rational reason for liking it in one context and not the other.


I don't like it! :-D Of course, now I expect it so don't get bitten anymore.


As a Perl developer, I never once used that feature. It does make some sense in the context of how Perl's own operators work, making them "do the right thing" for different cases. But for user code... not needed.


This branch of comments has decent gripes.

I adopted the contextual thinking fairly easily so it was not an issue for me but having worked with so many languages since perl I can see why this would be annoying to others. It's not the most unfortunate aspect though.


It's not so bad when you know what is going on but when you first hit something like that it's hard to figure out what is going on. Basically violating the Principle of least astonishment

https://en.wikipedia.org/wiki/Principle_of_least_astonishmen...


Perl also flagrantly violates the Principle of Least Nausea, with all its emetic Syntactic Syrup of Ipecac.

https://en.wikipedia.org/wiki/Syrup_of_ipecac


PHP's string datatype (in the C code) had a length field in addition to the actual bytes (probably still has), so the idea is not always bad (if most of what you do is string manipulation, so len() is O(1) and not O(n)) but I get your point, that's hidden deep in the language for perf reasons, not in user code :P


No, that's fine, this is more like the `len()` function being called implicitly if the array is being passed to where a "scalar" value is expected.

Like here:

    sub some_function($) {
        my $some_var = @_;
        print("$some_var\n");
    }

    my @arr = (1, 2, 4, 7);
    some_function(@arr);
This prints the length of the array.


I can't seem to convince myself to use Perl anymore for serious applications, but I do still whip it out occasionally for essentially the "shell scripts with sane control flow" use case.

IMO it is still mostly unmatched in that area. Most other languages, while just as capable, require far more line noise to interact with streams and use regexes. I admit though I have studiously avoided learning awk and sed over the years.


I've had a good time using zx (and some Deno takes on it). It's amazing how little is needed to make JS pretty handy for scripting. https://github.com/google/zx

I'd love some day to have the power-shelly dream of an object oriented platform. But I don't want to renounce all the cli tools I know & love & switch to a strange new platform to get it.


If only power-shell was a better shell. How do you start a cli program which is not in PATH? Good luck.


You write the path to it, relative or full, just like in other shells

    c:\temp\program.exe


Now try it with a path which contains whitespace.


For those that are genuinely curious,

  & "C:\Program Files\Vendor\AwesomeVendorProgram.exe"
(yes - PS is definitely chock full of idiosyncrasies)


"c:\program files\my user name\foo bar baz.exe"

???

tab completion generally works on space-filled path/names too, at least in the last 10 years or so, when working in windows worlds.


PS interprets that as a string and echoes it.

  PS C:\Users\me> "C:\Program Files\PuTTY\plink.exe"
  C:\Program Files\PuTTY\plink.exe


I don't know what's different about your PowerShell -- I am running PS 7.2, but I type and tab complete the path to the binary and it auto prepends the ampersand for me. Embarrassingly, I never even paid attention before now, it "just works".

My actual experience is pretty much identical to bash and zsh. There's not really any additional cognitive load. Maybe the commenters in this thread aren't used to normal *NIX shells? I don't have any experience with fish or oh-my-zsh.


Oh yes, tab completion adds an ampersand automatically on mine as well. I was just pointing out that literally quoting a pathname to an executable by itself doesn't achieve the desired outcome.


Tab completion does not add it in mine.

PSVersion 7.3.3


That's really weird and I have no idea why it wouldn't be working for you.

I even went as far as to spawn the ancient version of powershell included with Windows and pwsh 7.3.4 without a profile and tab completion adds the ampersand. I do import the PSReadLine module though in my profiles so maybe that is providing the functionality and I was wrong about loading an empty profile.


This is the way I still (occasionally) use perl. I used it back in the CGI days, but even to this day it's excellent for regex-type operations (even just called as a one-liner in a bash script).

I learned enough awk to get by, but if you actually want to do advanced processing it can be even more inscrutable than perl, which can do everything awk can and a lot more.


I do exactly that but with ruby


Ruby works great for this, but is unfortuantely not installed on many systems -- but this isn't just bad luck, I think it's a consequence of the fact that ruby code written two years ago has a pretty good chance of not running on the recent version; and code written for the recent version without thinking about backwards compat also has a good chance of not running on ruby of two years ago...

Means as a language it's not suitable for "have it installed on every system and then just throw code at it that will work, and keep working" like Perl. Even if you could convince all the distro maintainers to include it, you'd never have the version you want/need. Which would be different for different scripts, and you'd have to be constantly updating all your routine maintenance scripts you just wanted to put there and have them keep working -- which with Perl you could.

I wish ruby were more about backwards and forwards compat, but it isn't.


I don't think I have ruby on any system I administer, but perl is almost always there.


dpkg requires perl, so perl is around .deb systems even if perl itself is not directly used.


Sadly Perl has fallen on hard times. I think the Perl 6 debacle is mostly at fault.

As it stands, unfortunately CPAN is full of rotting modules. While it may be a maintained and usable language still, that puts a huge damper on any non-trivial development, because at any time something important might turn out to be broken or unmaintained, or without an API at all.


> Sadly Perl has fallen on hard times. I think the Perl 6 debacle is mostly at fault.

I agree hard times. Hubris is at fault.

Perl did too much and reached for the stars. Its happy place was a sane job control language. A niche Python is filling.

I have used both, Perl extensively, Python when I must. Perl is much better, but being better is not enough.

Perl did "everything". Python was "object orientated". People wanted the shiny "object orientated" and, sadly wisely, did not want a language that could do anything and everything.

I blame Larry Wall, the genius, both for Perl's success, and Perl's failure. If only I could fail so brilliantly!


Python ruined Perl for me. As soon as I convinced my self that pass-by-object-reference really was that simple, and I didn't have to deal with pass-by-sigil-maybe, I never looked back.

Write a Python function that writes an object's string representation to a file:

  def write(obj): open('/tmp/foo', 'w').write(str(obj))
Call it on an integer:

  write(123)
and it works. OK. But what if I want to call it on a list of strings?

  write(["spam", "eggs"])
That was too easy. I know - let's see if we can write a dict of tuples to sets of ints!

  write({(1,2):{3,4,5},('spam','eggs'):{6,7,8}})
That freaking worked? And I didn't have to change the function to accept a hashref? You just pass an object... and it passes the object?

At first, I thought I had to be missing something, like maybe it was impossible to do trickier things because they made the simple things so easy, but no. It just turned out that some of Perl's design decisions increased my cognitive load way more than strictly necessary. That's clearly not true for everyone, but it sure was for me. The first day I wrote Python was the last day I wrote Perl.


> At first, I thought I had to be missing something,

Well, Data::Dumper is included in core Perl ...

    use v5.12.0;
    use warnings;
    use autodie;
    use Data::Dumper;
    
    sub logit {
        open state $log, ">>", 'c:/tmp/foo';
        print $log Dumper(@_)
    }
      
    logit(123);
    
    logit(["spam", "eggs"]);

    logit({"(1,2)"=> [3,4,5],"('spam','eggs')"=> [6,7,8]});


    # even logging multiple objects at once ...
    logit(
          123,
          ["spam", "eggs"],
          {"(1,2)"=> [3,4,5],"('spam','eggs')"=> [6,7,8]},
         );

NB: Perl has neither tuples nor sets, but there are workarounds.

And I opened the filehandle only once. And for append not overwrite like you did.


> I agree hard times. Hubris is at fault.

I don't think it was so much hubris as bad communication.

Perl 6 was understood to be that: Perl 6, a definite successor to Perl 5. But besides being very, very late it turned out not to truly be Perl 6, but a new, incompatible, Perl-ish language.

I think the decision to rename it to Raku was a good one, but came too late. By then the world had already moved on.

Done early enough I think it'd have fixed things. It'd have created the clarity needed to understand that Perl 5 wasn't going away, and that it was pointless to wait for a successor.


I suppose, the parent comment was referring the Three Virtues of a great programmer: https://thethreevirtues.com/

Bad communication isn't one of those (although, given the prevalence of bad communication in the industry, one might assume it is ...).


> Its happy place was a sane job control language

maybe that was your happy place for Perl, but it certainly wasn't mine or that of lot of Perl users I've known over the years.

  #!/bin/perlish
  while (<>) {
    /* regex match */
    /* do some stuff, with variables or the file system or whatever */
  }
Awk theoretically is a close match for this basic structure, but Perl is closer, most of the time.


Yes.

I mispoke. "A happy place" I shold have said

I never learnt awk or sed bedcause I knew Perl.

That loop, often in a command line invocation `perl -e 'while(<>){chomp;......}'`

My point is its happy place was not application programming, gui systems. AS I commented elsewhere here processing every Apache hook.

Pythin suffers the same problem. It too is brilliant at the little jobs, yet there are many GUI junk piles written in it, just as happened with Perl back in the day


Perl offer auto looping : perl -n or perl -p. Typically one-liners are `perl -n -e 's/foo/bar/g'` or similar.


> Perl did too much and reached for the stars. Its happy place was a sane job control language. A niche Python is filling.

> I have used both, Perl extensively, Python when I must. Perl is much better, but being better is not enough.

> Perl did "everything". Python was "object orientated". People wanted the shiny "object orientated" and, sadly wisely, did not want a language that could do anything and everything.

I don't know what kind of Python you've tried using, but it seems you got some defective ancient 2.x version. Python is exactly the kind of language that should be replacing Perl, simply because it's the best glue language out there right now, with modules that are actively being maintained and developed.

And, as a cherry on top, actually has human-readable syntax.


> Python is exactly the kind of language that should be replacing Perl, simply because it's the best glue language

When tabs and spaces have different syntactic meaning, I am suffering quite a bit of revulsion.

I have to do it, but I want to control my own white space for my own purposes.

It comes down to taste, I guess. I am not wrong, but neither am I correct


> I think the Perl 6 debacle is mostly at fault.

I don't think it has anything to do with it. Perl 5 is an old language. Period. And Javascript came to inherit Perl's position as a "web glue language". These days JavaScript is an okayish language to use in this case.

Raku fka "Perl 6" is out and alive: https://www.raku.org/

It turned out to be a very powerful programming language but lacks the large niches Perl 5 (the web) or Python (machine learning) catered to.


> Perl 5 is an old language. Period.

That's an odd way of looking at it. C is an old language. C++ is an old language. Java is an old language. Nobody is arguing against them because they're "old".

Moreover, just because something is old doesn't mean you throw it away. How many newer languages have come, and gone, just in the time since Perl hit its peak?


Perl 5 had a certain niche. That niche has been filled by other languages (mostly backend JS these days).

C lives off its niche as being the lingua franca for programming low level interfaces. Java lives in its corporate niche and C++ mostly in game programming and large desktop applications.

Perl 5 has become an orphan. It’s a programming language nobody needs any more and, hence, shares the fate of many other obsolete languages that may be cool but are unpopular.


It's a beautiful & succinct language to write in.

When you know it & it's various implicit various implicit variables, you feel enormously powerful, are able to make really beautiful use of the bountiful context Perl leaves out for you. It's heady & compelling in a way almost nothing else ever has been for me.

Pass by sigil is weird but everything being named symbols is a powerfully simple concept, that opens interesting roads.

But gee it sure is nearly impossible to read after. Rebuilding the context of how everything fits together, remembering each little rule you've taken advantage of is a trying puzzle indeed.

Sidenote, it's a long far off hope (lots of the base deb tools are Perl), but I hope someday we can run a Debian system without Perl, that we end up with more mature replacements eventually. It being everywhere is the authors #1. In general they try to present practical sensible reasons. But so few are language specific concerns, are context but not really talking "Why Perl" itself, why Perl the language. The seductive heady weird ambiance of Perl is so unique, is a much less structured & clear "why".


Perl is a write-only language.


Translation:

I am not a competent $language programmer. You will not understand my poorly written code.

In this case, language="perl".

perl is not special in this regard.


Perl is meant to be written and read intuitively.

Which is a bad decision, in every language you're going by intuition 95% of the time, it's when a piece of code works in an unfamiliar way that you reason from first principles, and then having clear and rigid rules to fall back on gets you out of the rut more quickly. Perl's design makes this harder for purportedly giving you more tools to write code that looks about right.


I believe the longstanding joke goes, 'Perl is a Worn language, write once read never'


Check PangZero of Frozen Bubble.


The part of the telecoms platform I maintain and develop at work is written entirely in Perl. It does incredibly well in every involved aspect, and with a higher-performing and more compact codebase compared to what would've been the outcome with Python, but I'm wary of my eventual departure from the employer because of how hard it is to find Perl people these days. As much as I love Perl I cannot say it's a future-proof choice and an absolute benefit to my employer.


If you pay a million dollars a year in salary, you'll have all the perl engineers you want.

If you pay "market rate", you'll have some good engineers and some desperate engineers, with the ratio slowly trending in the negative direction over time.

Point is, that's definitely a solvable problem, but only if you watch out for hard-to-quantify externalities.

Anyway, if the salaries have to keep going up to keep high quality engineers, the economics of rewriting and/or deleting legacy code start being a lot more straightforward.


I agree. there is rarely (if ever) a shortage of talent. there is (almost) always a shortage of desire to acquire said talent.

like most things, it's a money problem.


I agree with the author on just about all the advantages of Perl. However, I think that python actually now shares the same advantages since almost everybody is using Python 3.x. Perl's greatest strength was its regex library and string handling and Python has stolen everything it could from Perl's regex language and most of its string handling so the advantages of Perl are much diminished now. Python is showing signs of being an absorbing language - like English - any great words that are developed in another language, are stolen by English pretty soon afterwards ..


> Python has stolen everything it could from Perl

It hasn't.

In python, regex's are an effing library.

In perl they're built into the language and can be summoned in a much more concise and efficient (metric:code clarity) way than python will ever manage as long as the bloody 'import re' will be required.


I'm confused about the compatibility X for Python. A few years ago, sure, but for an article published a month from now? You write python3 and it's installed everywhere.


Python's dependency hell due to changes between versions in both modules and core is so bad there's even a python dependency manager hell of chosing which env wrapper or containerization you're going to use because the system python sure as hell won't work. And if you do have the gall to update a system python package system stuff will break. Whereas with perl the system libraries will work, no need for containers.

Python's popularity hurts it for use when you want compatibility. Containerizations can only mitigate this so much.


If you write to the (very extensive) standard library, though, none of this is an issue.


Bullshit, Python breaks compatibility between minor releases all the time. The script you wrote for 3.8 has high chance of being broken on 3.11.


Really? I've written a lot of python, though less recently, and this doesn't sound familiar at all. What's in 3.8 but not 3.11?


Just forget all about all that virtual environment crap, globally install a modern version of Python in a Docker container, and take full advantage of its latest features.

I couldn't remember the title of this memorable talk, but ChatGPT could:

Q: In which talk by David Beazley does he recommend writing new Python code that takes full advantage of the language's new feature, without worrying about making it backwards compatible?

A:

David Beazley is a well-known Python expert who has given several talks on various aspects of the language. However, one of his talks that emphasizes the importance of taking advantage of new features in Python, without worrying about backwards compatibility, is "Python 3 Metaprogramming".

In this talk, which was delivered at PyCon 2016, Beazley highlights the benefits of using Python 3's new metaprogramming features, such as type annotations, function annotations, and asynchronous programming. He argues that these features can make code more concise, readable, and maintainable, and that developers should not be afraid to use them, even if it means breaking backwards compatibility with older versions of Python.

Beazley's message is clear: by taking advantage of new language features, developers can write more efficient, expressive, and scalable code, without worrying about the limitations of older versions of Python.

Q: Give me a link to that video.

A:

Sure! Here's the link to David Beazley's talk "Python 3 Metaprogramming" at PyCon 2016:

https://www.youtube.com/watch?v=sPiWg5jSoZI

I hope you find it informative and helpful!

Q: What are his arguments for not worrying about backwards compatibility?

A:

David Beazley's main arguments for not worrying about backwards compatibility in his talk "Python 3 Metaprogramming" are:

1. New language features can make code more expressive and efficient: Python 3 introduced several new language features, such as function annotations, type annotations, and asyncio, that can make code more concise, expressive, and efficient. By using these features, developers can write cleaner, more readable code that is easier to maintain and debug.

2. Older versions of Python can be managed through virtual environments and package managers: Developers can use tools such as virtual environments and package managers to manage different versions of Python and dependencies. By isolating different versions of Python and packages, developers can ensure that their code works correctly on different platforms and environments.

3. The community will eventually move to newer versions of Python: As more developers adopt newer versions of Python and start using the latest language features, the community will gradually move away from older versions of Python. This means that eventually, the majority of users will be using newer versions of Python, making backwards compatibility less of an issue.

4. Code refactoring tools can help with compatibility issues: There are several tools available that can help with code refactoring and modernization, such as 2to3, which can automatically convert code from Python 2 to Python 3. By using these tools, developers can make their code compatible with multiple versions of Python without having to sacrifice the benefits of newer language features.

Overall, Beazley's argument is that developers should not be afraid to use the latest language features in Python 3, even if it means sacrificing backwards compatibility with older versions of Python. By doing so, developers can write cleaner, more efficient code that is better suited to modern software development practices.


globally install a modern version of Python in a Docker container

You lost a bunch of people right there. There's a significant difference between "open a terminal" and "install Docker, create a container, configure the latest version of Python."


They certainly lost me. I'd rather write Bash than fool around with Docker. IMO "just Dockerize it!" is a smell.


Perl is mostly forwards and backwards compatible (or less generously it has frozen). Python is backwards compatible, but continues to add new features, and some packages are rather enthusiastic about adopting these features quickly, and ending support for older versions of Python. It isn't as bad as other language communities (I'm looking at you Rust), and I would have at least given it an asterisk, but it certainly isn't as stable as Perl.


Perl does add new features, but if your program has use v5.30; at the top, and a library has use v5.22;, or the other way round, it will work.


Python isn't actually everywhere by default, but neither is perl (but perl at least is usually named perl, while python may commonly be python or python3). Neither is consistently in the same location and shebang issues are pretty common. If script portability is actually a concern, /bin/sh is still the best way to go.


#!/usr/bin/env perl

is the usual way to fix this. Far more common is running into UTF-8 problems, but using the usual -CSDL and the UTF-8 open default handles the issues.


Is it available in windows by default?


No, but then neither is perl. On windows you've got powershell, batch, VBScript and JScript pre-installed.


Is perl? That's an honest question/honestly surprises me.

But honestly installing anything like that (without WSL probably - haven't used it recently) on Windows is painful, it's not python's fault, it's just a different paradigm. Run with a different environment variable for example.


Last install of Windows 11 I did (triggering) Perl was installed by default


It is not installed by default on any of the systems I work with. We have around 10 office staff that all use windows, and 2 windows servers. No Perl by default on any of them.

To the best of my knowledge you must install one of two main distributions of Perl for Windows. https://www.perl.com/article/downloading-and-installing-perl...

You can also use WSL.

Edit: It sounds like, from other comments, that Perl comes with Git Bash as well.


Are you sure it is "installed by default" or it happens to be inside WSL? Because WSL is not the default.


I believe not now but Perl 5.004 was installed on Window NT (3.5 or 4) by default. That made the case for its use on project that could not afford the IBM AIX or Silicon Graphics systems we were using at the time.

We used Netscape Fasttrack as the server.


Wait what no?! NT4 was released in 1996. And Microsoft touching Open Source without ten foot poles back then also feels wrong.


Perl was used as part of the Windows XP build process, if you know where to look. It might have been used in NT4 as well.


Sure, but it's not "installed by default" in either of them.


I wonder if that was ever considered as a possibility at Microsoft. They had proven the camel was capable with Win32 stuff in their build process.

Maybe it was considered technically by some of the programmers, but swiftly quieted by PMs.


I'm sorry but my windows doesn't have Perl by default either perhaps I misunderstood your comment :)


You probably have it if you have Git Bash installed. Perl is a dependency of Git IIRC.


The first versions of git were written in Perl (with some small speed sensitive parts written in C).


Then it's not by default right? I must have git installed !


It was a simple question. Author claimed it’s found everywhere, but if it’s not installed by default im not going to find it in enterprise environments


Eugh, no, they've just got a little thing so you'll go to the microsoft store to download python when you search for it from the start menu, seem to recall it giving me some cryptic hell with making pip difficult to find. Bastards.


Is Perl?


No, but Perl at the very least is available on the latest versions of Mac OS. Python is not. So as far as "being bundled with the latest OSes" goes, Perl beats Python.

NOTE: I am (probably mistakenly) assuming that Perl is still bundled in most Linux distros by default.


Python is available by default in macOS. Not latest version python, but available. (Both 2 & 3 I think, or maybe they've dropped 2 now.)


A minor update of macOS Monterey[1] removed /usr/bin/python, but /usr/bin/perl still exists. Xcode's Command Line Tools will install Python 3, but I do not count as being bundled by default with macOS. Unfortunately, I can't find any Apple documentation to prove this. You'll just have to check with a fresh install of macOS Ventura yourself (or, at your own risk, uninstall Xcode and/or the Command Line Tools)

[1] https://developer.apple.com/documentation/macos-release-note...


(Ouch, a minor update!) Oh ok, I stand corrected. I don't currently have any macOS machines.


Perl does not die easily because of the way many of us learned it. We started to used it for sysadmin automation (prehistoric DevOps) and then the early Web showed up and we used it for that too.

After 15 years (much more the 10,000 hours of use) it was hard to forget. And that over 15 years ago. Once you have it in your brain it does not go away easily.

I teach Python but I still think in Perl.


Comparing Python to Perl ( assuming equal experience with both ):

If you are a good programmer, you will write good Perl and Python code. If you are a bad programmer, you will likely write terribly horrendous Perl code and slightly less horrible Python code.


If you are an excellent programmer, you will write excellent Perl and good Python code. The Python language limits your ability to write excellent code, which also limits your ability to write horrendous code.


Great username. Where do you stand on this topic? :-)

Your vote ratio reflects the relative fewer excellent programmers to weigh in on your point.

Majority: Python is pretty, perl is line noise.

Minority: Simple isn't easy, succinct is expressive.


My two favorite languages: Perl and Go. Both have very simple one file deployment, but my favorite use of Perl requires no file deployment, just one-liners on the command line.


How's that true with Perl since the interpreter is still needed? In that case the same could be said about Ruby, Python, et al.


If you work on Linux or MacOS, you can generally count on the interpreter being present. Even minimal installs of Linux tend to include Perl. Python might be as ubiquitous, but Ruby certainly isn't.


It might, but you better be sure it is the right version.


If he's mainly using it for one-liners, how version dependent can it be? (I suppose it may depend on how long a line he's willing to type...)


Depends on what is being called on that line.

https://perldoc.perl.org/perl#History


Seconded. I just wrote a script to generate Terraform code to create a VM in the company vSphere clusters, only needing host name and IP address (optional flags for meme/cpu/etc). Description of datacentres, subnets, etc as YAML in the DATA section, works out all the right VLANs.

Works out of the box on everyone’s Mac.


Currently I am doing the coding for a prospective startup in Perl. Mojolicious plus DBIx::Class are quite powerful, though I wish the latter was better documented. A ‘how to do join tables without incurring hairloss’ tutorial is a must for every ORM.

Mojo covers a lot of what you’d expect from modern web application development, and it does so with finesse. I hope it gets more attention. It seems many unfairly still associate Perl web development with a hodgepodge of bad CGI scripts.


DBIx::Class::Helpers and DBIx::Class::Candy are nice layers on top.


Perl is a great language for getting things built. Amazon was originally built on Perl.


While I don't agree with the author's opinion on Perl I'm in awe of their design. I love the look of their personal site.

Perl is only ubiquitous in the Linux/Unix world. Try running it on Windows. You have to install some half working package.

I have a strong dislike for Perl as I worked with it for many years. Much of that is that I knew nicer tools existed and I wanted to use them but some was they syntax. I hate the terse syntax and the gotchas.

Issues like this https://stackoverflow.com/questions/7515029/cant-turn-off-bu....

If you are new to Perl what is $|=1; going to mean to you?

Then there is the fun of "Wide strings" https://stackoverflow.com/questions/9299941/perl-unicode-wid...

You of course have to know the operators in Perl. There is a good reference https://perldoc.perl.org/perlop but I remember before I found that page in the docs I was lost.

Then there is the use of references. Do I need a \% here or just a % no wait I need a \$. It's not that hard but it's a friction I got sick of.

Yes all languages have their warts but I did not like Perl's even after almost a decade of working with it.


What companies are still using Perl on the backend?

I know FastMail does. IMDB was in Perl before Amazon acquisition, and was told was rewritten in java over several years. Any other interesting mentions?


Athena Health's entire backend is/was in Perl as of the mid 2010s (note: I didn't work there, only interviewed once).


PACER -- the system that runs electronic dockets and service for all federal courts runs on perl.


CPAnel is popular with shared hosting and is predominantly Perl. Companies like godaddy and eig as well as thousands of shares host still use this. Certainly a shrinking market but it has a number of years in it. Apache spamassassin is written in Perl. Other than those I rarely ever see a Perl project and if I do it was originally written in 2000.


Booking.com is known for using perl



I am not permitted to name them but there is a large company that is heavily involved in the movie industry that uses perl+Oracle quite heavily in ways I never imagined to give Hollywood execs a lot of real time data.


Fastly does -- most of its configuration management and distribution is handled by Perl applications, and the VCL templates used for most customer boilerplate is driven by Template Toolkit.

I don't want to name names, but a few prominent Perl contributors work there (yours truly included).


Any company using Proxmox [1]:

   $ dpkg -l|grep -i proxmox|awk '/perl/ { print $2}'
   libproxmox-acme-perl
   libproxmox-rs-perl
   libpve-apiclient-perl
   libpve-cluster-api-perl
   libpve-cluster-perl
   libpve-common-perl
   libpve-guest-common-perl
   libpve-http-server-perl
   libpve-storage-perl

 [1] https://proxmox.com/


A lot of OpenSuse's infrastructure has decades old perl pieces still doing part of the work of important services.


I found this and read some of the code a while ago. Was very surprised it was in Perl, but makes sense I guess.


craigslist is the first one that comes to mind


perfect


perlfect


Not strictly "backend," but Amazon, AFAIK, still runs large portions of their infra tooling on Perl.


www.spareroom.co.uk

Slashdot

The Register

BBC iPlayer, at least originally

Also I'm sure someone recently wrote a text-based MMO in Perl but I forget the name of it



Large parts of the ziprecruiter website are still powered by perl.


Yahoo used it a lot, but I'm not sure if they still do.


duckduckgo?


There is a very interesting talk [By Rasmus Lerdorf ](https://youtu.be/wCZ5TJCBWMg) on the occasion of the 25th anniversary of PHP.

He addresses the issue of why PHP not Perl became the "winner" on the web. (About ten minutes into the talk)

In his opinion it was due to the Apache modules that build PHP, alternatively a Perl, interpreter into the Apache server

PHP's implementation implemented just enough to make it work (document generation hook), while Perl implemented all bells and whistles, including path translation. This made all the Apache hooks available to the Perl programmer.

On shared servers using a single Apache server and virtual host with several websites running on one Apache server this meant a Perl programmer could hijack the whole server

Hubris


I ask my company this question and the answer is mostly "it's what we used 20 years ago"


That is a good answer.


I love perl, but since it doesn't come installed on alpine docker by default I end up using cut/awk/sed and friends instead. :.(


One very relevant feature is missing, it is like an high level C without with memory corruption related issues, given the language capabilities and standard library.

Many stuff in userspace UNIX would still be fast enough for its tasks if done in Perl instead of C.


For a bit of fun, I'd recommend starting off with an ugly bash script when you just want to hackily and happily get something done, then asking chatgpt to convert it to another language(go? perl? ruby?) It is interesting to see the trade-offs.


Seems fun, let's try it.

> ChatGPT> Rewrite the following as concisely as possible in perl, perl 6, J, Haskell, with no explanation and only code:

    history | awk '{a[$2]++}END{for(i in a){print a[i] " " i}}' | sort -rn | head
Perl:

    `history | perl -ne '/^\s*\d+\s+(\w+)/ && $a{$1}++; END { for $i (sort {$a cmp $b} keys %a) { print $a{$i}." ".$i."\n"; } }' | sort -rn | head`
Perl 6:

    `history | perl6 -ne '/^\s*\d+\s+(\w+)/ && $a{$1}++; END { for $i (sort keys %a) { say $a{$i}." ".$i; } }' | sort -rn | head`
J:

    `head sort |. |:+/ ,.~ [: ~. stdin -: i.0"1 <@:". ]
Haskell:

    `reverse . take 10 . sort . map (\x -> (length x, head x)) . group . sort . map (words) $ lines <$> readFile ".history"`
from https://www.commandlinefu.com/commands/view/604/list-of-comm...


Both of those Perl solutions could be shorter (and probably quicker) in that you don't need the "sort -rn" as you can do that sort directly in Perl.


Something similar to this;

history | perl -ne '/^\s*\d+\s+(\w+)/ && $a{$1}++; END { map { print "$a{$_} $_\n" } splice((sort {$b <=> $a} keys %a),0,10) }'

Oops, just realised it should be sorted by the value and not the key so...

history | perl -ne '/^\s*\d+\s+(\w+)/ && $a{$1}++; END { map { print "$a{$_} $_\n" } splice((sort {$a{$b} <=> $a{$a}} keys %a),0,10) }'

Also noticed that splice() isn't setting wantarray() so you'll need to use direct indexing which is probably easier to write too...

history | perl -ne '/^\s*\d+\s+(\w+)/ && $a{$1}++; END { map { print "$a{$_} $_\n" } (sort {$a{$b} <=> $a{$a}} (keys %a))[0..9] }'


Usually line noise like that is quickly followed by a "Remote disconnected..." message and I have to dial in again.


Sure, the same thing could be said about Chinese logograms if you don't understand it. Personally I prefer the compact symbology, it's somewhat like Lempel-Ziv tokenisation; it's a form of compression.


For comparison, here the answer from Bing AI

Here are the rewrites in Perl, Perl 6, J and Haskell:

Perl:

> perl -e 'while(<>){$a{$F[1]}++}for(sort{$a{$b}<=>$a{$a}}keys%a){print"$a{$_} $_\n"}' <(history)

Perl 6:

> my %h; for lines() { %h{.[1]}++; }; for %h.sort(-*.value) { .say }' <(history)

J:

> echo 'history' | jconsole -e '10 {. /:~ [: >: [: +/"1 [: =/ [: ;: [: >: [: ;: [: cut ;._2 ] ] ] ] ]'

Haskell:

> import Data.List

> import Data.Ord

> import System.Process

> main = do

    h <- readProcess "history" [] []

    let l = map (head . tail . words) $ lines h

    mapM_ print $ take 10 $ sortBy (flip $ comparing snd) $ map (\x -> (head x, length x)) $ group $ sort l


and answers by phind

# Perl perl -e 'print sort { $b <=> $a } map { /^.\s(.)$/; \$1 } <>' <(history | awk '{a[\$2]++}END{for(i in a){print a[i] " " i}}')

# Perl 6 (Raku) perl6 -e 'lines().map({m/^.\s(.)$/; \$0}).sort({-$^a}).say()' <(history | awk '{a[\$2]++}END{for(i in a){print a[i] " " i}}')

# J history | awk '{a[\$2]++}END{for(i in a){print a[i] " " i}}' | jconsole -je 'echo/:~1!:1]fread'''''

# Haskell ghc -e 'interact $ unlines . take 10 . reverse . sort . lines' <(history | awk '{a[\$2]++}END{for(i in a){print a[i] " " i}}')


I was able to try the perl versions and only the chatgpt is working (I have no experience in perl to check myself)


The Haskell one has a bug, it should be "take10 . reverse . sort". And I suspect the second sort isn't needed but I'm not a Haskell programmer so not as sure about this.


> It is installed by default everywhere.

For some values of "everywhere". Pretty sure this is not true on Windows, for example.


For extremely limited values of 'everywhere' which shake its definition.

I don't think a basic Arch Linux installation includes perl. Windows as you say would surprise me. 'the major Linux distributions' (plus I think macOS, perhaps inherited from BSD, no idea) might be fair, but certainly not 'everywhere'.


To my mild dismay, it's not part of the base system in FreeBSD anymore[1]. It is easily installed, of course, but that means #!/usr/bin/perl does not work without manually creating a link.

[1] I think it used to be part of the base system, at least.


Perl was removed from FreeBSD base more than 2 decades ago:

https://bsd.slashdot.org/story/02/05/14/0015234/freebsd-perl...

And this was the right move. It meant that the version of Perl was decoupled from FreeBSD releases, allowed you to choose which version to install, and allowed you to install multiple versions if needed.


One glaring problem with perl in this day and age (apart from pass by value by default) is a lack of built-in generators. Python has them. Javascript has them. Go has goroutines. Bet Rust has some macros or something.

Yes, I’m aware of some rotting modules on CPAN that half-assedly implement them, but given that they exactly bolt it on, they are full of gotchas, like Try::Tiny, with which it’s quite easy to forget that a return statement in the try block will do exactly the wrong thing.


> like Try::Tiny, with which it’s quite easy to forget that a return statement in the try block will do exactly the wrong thing

Try::Tiny does its best without manipulating the parser itself; it's been superseded by Syntax::Keyword::Try (which alters the parser to make flow control work as you'd expect), and in the last few years of releases there is a native `try` keyword right in the language (which can be used in older versions via Feature::Compat::Try, which is a shim on top of Syntax::Keyword::Try in old versions and a no-op in new versions).


Notably missing from the 5 points he makes at the start of the article:

Perl's regexes (unlike python and a swath of other languages) are first class citizens in the language (and not some effing library you have to import, along with its clunky API).

To wit:

    PERL:

        $x = $1 if(/^Line_start[ \t]*([0-9]+)/);

    PYTHON:

        import re
        m = re.match(r'^Line_start[ \t]*([0-9]+)/, line)
        if m:
           x = m.group(1)
The latter is painful.

This is the only reason that still makes me sometimes pick Perl over python when I need to slap together a quick and dirty run-once script to chew thru a big pile of data.

Other than that, as much as I've used Perl over the years and found it extremely useful back in the day (coz it was the best there was at the time), it is a horrible language by modern standards ($ to identify variables, having to tell the compiler that an expr is at an end with a ';', ugh), and it is time to let it Rest In Peace.


The problem is that outside of very trivial or temporary situations, regexes should be named and tested. Especially for scripts that tend to be written, deployed indefinitely, and mostly ignored.

One you have a name and a design where you can test the boundaries of that regex without, say, downloading large files or rearranging the filesystem, you aren't really buying all that much by avoiding some extra library boilerplate.

But I'll admit that native support for regex comes in handy for throwaway scripts.


I am surprised no one has mentioned Perl's miserable signal handling and how working with binary data is clumsy and slow. These two things are what make it difficult for me to promote Perl as a great general language. But when you need to write a minimal amount to code to chew through a bunch of patterned text or such there is nothing better.

It's my still go-to language for quick implementation in a minimal number of lines however.


This article just seems biased, the author likes Perl therefore he/she will pull the strings to his/her side. For me it's just as simple as that.


I have been writing Perl for over 20 years. But these days I use Python more and more.

I found it hard to hire for Perl, so I switched the team over to Python.


What does he mean by a red cross in the Compatibility column for JavaScript? What is javascript incompatible with?


> published 2023-05-26

Hmm…


I’m sure the author will still feel the same way in a month.


I think it's because he is using Perl.


Yep, Time::Piece can access the future. We weren’t supposed to know now but obviously something’s slipped back…


So sad they killed the dev cycle to Perl 6 and that I'm forced to use Python. :( JAPH


IMO it's better to just use TypeScript anywhere that you'd normally use Perl. The type safety helps later on when you revisit old code plus I think it's more productive overall, having used Perl many times in the past.


The Javascript ecosystem (to which Typescript belongs) makes the Perl ecosystem of twenty years ago look modern and streamlined.


Nooooo. Python's the clearest front-runner in the Perl replacement game. I wish it were Ruby, but it's pretty clearly Python. TS changes too fast and requires too many tools, it's not even a serious contender in this category, though I much prefer it to any of the above for large programs.

Python has some semi-decent type hinting, these days. It's not so bad, it'll keep you out of most of the same trouble that TypeScript does.


Typescript is a great remedy when you are forced to use JavaScript. But in a context where you can use any language it makes zero sense. If you want static types just use C# or whatever, otherwise just use Python.


While I see benefits of TypeScript's type system, I think the lack of a special compilation step is a big win for Perl, at least in the author's eyes. (Yes, I know Deno is a thing, but I'm not sure of the extent which the author considered it).


You can run ts-node to execute TypeScript to run it without having to manually compile it first. Although if you have a large TypeScript program with a lot of dependencies or on an older machine, I guess it could take some time. With my own scripts I've only seen it take a few seconds at most.


Slightly easier to start using Type::Tiny[1] than switching languages.

[1] https://metacpan.org/pod/Type::Tiny


Friends dont let friends write perl. Source: The legendary "Perl Jam" talk from the chaos communication congress.

* https://www.youtube.com/watch?v=noQcWra6sbU * https://www.youtube.com/watch?v=RPvORV2Amic

Also I find the "ubiquity" argument very side loped. What I could agree with is "small/self-contained install" (e.g. small single executable available for many platforms). But not sure how well perl fares there.


this reminded me of an article I read a while ago [0] "93% of Paint Splatters are Valid Perl Programs"

[0] https://www.mcmillen.dev/sigbovik/


I wonder why this is dated a month from now?


Damian Conway once wrote a module called Timeline::Curves, if I remember right, that took the program back in time. I’m sure this explains it.


Here's where he explains how he did it: https://www.youtube.com/watch?v=ORjyXcLDd9M


perl script off-by-one mistake, presumably.


But "2023-05-26"?


What is it about these very short articles that HN loves?

(Short, subjective but presented objectively).

Or is it just loved by those who agree with the premise in this case Perl die hard?


The article is clearly presented as a matter of personal opinion with the framing as the answer to the question 'why does the author use Perl so much'.

I liked it because it is interesting to read other people's examined opinions on topics that I am ignorant of.


I like short stories on HN.

The most interesting part are the HN comments, and without reading the story first, it is rude and less interesting commenting.

So short stories are a plus for me!


I like short articles in general, but this one is short and shallow, plus subjective without explanation as you mentioned.

I spent too much time trying to guess at the author's reasons. Why are Python and JavaScript not extensible but R is?


In 2023? For no reason at all.


published 2023-05-26

cool story bro




Consider applying for YC's Spring batch! Applications are open till Feb 11.

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

Search: