Hacker News new | past | comments | ask | show | jobs | submit login
Perl 5.38 (perl.org)
176 points by thatwasunusual on July 3, 2023 | hide | past | favorite | 125 comments



I'm learning perl right now and I'm bewildered at how could I overlook it for such a long time.

With all its quirks and strange design decisions (especially compared to elegant languages like ML or Scheme), it has it's own killer features I missed from other scripting languages so much, such as the ability to embed a shell command in backquotes and get its output easily.

Also the notion of context is pretty good, allowing to write a far shorter code, even sigils contribute to that naturally (in languages like bash they feel like a useless burden).


Context is something you have to learn to be careful with but used judiciously is often quite neat.

Sigils are great once you realise they're conjugation, i.e. $ -> the, @ -> these, % -> the pairs of, hence

  $foo # the value of foo
  $foo{bar} # the bar value of the hash %foo
  @foo{qw(bar baz)} # the bar and baz values of the hash %foo
  %foo(qw(bar baz)} # the bar and baz pairs of the hash %foo
    # i.e. the last one returns (bar => $bar_value, baz => $baz_value)
(and similarly @foo[1,2,3] for 'these values of the array @foo')

I tend to prefer using p3rl.org/IPC::System::Simple and/or p3rl.org/Capture::Tiny and/or p3rl.org/IPC::Run3 over backticks, and p3rl.org/Path::Tiny over File::Spec (or p3rl.org/Mojo::Path if I'm in a Mojo(licious) app).

Note that for scripts where you don't want to deal with dependencies there's p3rl.org/App::FatPacker which will bolt pure perl deps (which all of the above are) onto the front of your script so you can still deploy a single file, p3rl.org/App::plx for managing a self-contained environment and p3rl.org/Object::Remote for when you don't want to need a script on the far side at all, just the ability to ssh to it and run -some- sort of perl binary.

(I've made quite a lot of effort over the years to minimise the number of times I hear the words "but I can't use CPAN" and them actually be true ;)

Plus for bigger stuff p3rl.org/Mojo::IOLoop and/or p3rl.org/IO::Async (the two event systems co-operate fine in a single process) with p3rl.org/Future::AsyncAwait turns out to be really handy.

(I wrote p3rl.org/Parallel::Map as a wrapper around p3rl.org/IO::Async::Function plus the fmap_ functions in p3rl.org/Future::Utils so I can drop fork based limited parallelism into the middle of a script without having to think about the event loop code underlying the implementation)


Where were you when I was learning Perl? That was the best description of context I've ever seen.

Context was one of those subjects where it's a little tricky but the way it was explained to me made it a complete nightmare to understand.


I picked up perl about 18 months ago and I never really found context hard to understand at all. Not trying to boast- just not really sure what people find hard about it.


The first thing is that it's a little like pointers where it's not too hard but there are a lot of explanations of it that create mystification rather than knowledge.

Stuff like this: https://www.perlmonks.org/?node_id=738558

> There is a way for a user-defined function to have its arguments in a scalar context, but that's seldom used, often discouraged, and outside the scope of this tutorial. Most of the time, subs' arguments are in list context.

> Perl's built-ins don't follow this rule at all. Example 10 does not do what's intended.

If that's your first introduction to context you may find it confusing.

From another one I dug up (might have been bot generated, just thought it was funny): Perl has a concept called context. Context means context, and there are the following two contexts.

The second thing, and this may have been more true in the days of yore when I was learning Perl is that there wasn't much consistency in how context was used. Combined with refs, this creates some painful mental overhead when working with multiple libraries in a project. Do I pass credentials as a list, a reference to a list, a specially formatted string, etc? It's not the end of the world but it adds up.


Perl, like Tcl, comes from the Walter Bishop Era of IT, where things were apparently batshit crazy at times but they managed to do things we now fail to replicate :D

Now, much effort is spent in making sure that a single team member cannot get weird ideas and do too much on their own.


Heh. I literally just tabbed away from watching an episode of Fringe[1] to check HN. I didn't expect to walk right into a Walter Bishop reference.

You make a good point though: what do you do with somebody like Walter who is simultaneously A. batshit crazy and B. a genius? I guess the Fringe approach of having people (Astrid, Peter, etc) to "babysit" him most of the time is one approach, but it probably doesn't scale. And one slip-up could result in... well, the end of the world in the fictional case. Hopefully nothing quite so dramatic is at stake here in our real (??) world.

Just don't let the crazy guy keep a cow in the office...

[1]: https://en.wikipedia.org/wiki/Night_of_Desirable_Objects


We must live in the Walternate universe where it takes a million lines of Java to do next to nothing at all.


You're outdated.

Now the new fashion is having a bazillion of YAML files, describing Kubernetes containers full of WASM modules, replicating application servers on the edge.

Apparently it is super cool.


ingy is batshit insane (and great fun to collaborate and/or drink with) but even he didn't expect text templated turing complete YAML to happen.

helm does still (last I checked) allow you to use your own transform script rather than the template engine so for private helm charts you can use https://yglu.io with data in environment variables to get less fragile templating if you can get away with doing it that way.


You're outdated. Today the fashion is to rewrite with millions lines of Rust of which at least 90% are boilerplate to keep the compiler happy.


I find Rust a bit hard to follow (having not studied it in any great detail) but a good deal of that boilerplate either avoids common problems in code or allows you to explicitly say "yes I know I'm doing something dangerous".

However for a while you're right people may have gotten a little bit carried away with "RIIR" - but I cannot fault someone for being enthusiastic :)


Well, when the pair of Rust Witnesses come by in suit and tie to testify to the power of their language and to ask you to move to that language, you're supposed to kidnap them and make them write the program and boring boilerplate for you.


At least you can do Hello world ??


And I often find pleasure in reading tcl/perl communities. So far from the mainstream and trends, yet full of funny surprises.


I recommend to use qx instead of backquotes. Much more readable because with some fonts backquotes are almost invisible.

https://perldoc.perl.org/perlop#qx/STRING/


I use `use IPC::System::Simple` (with `qw/system capture/` where appropriate) whenever I need to call out to a shell - it's the external process equivalent of `use strict`


If you end up doing web development, check out Mojolicious:

https://mojolicious.org/


> such as the ability to embed a shell command in backquotes and get its output easily.

Unless thing have changed in the last 20 years - and they might well have! - that was also a very error-prone tool.

For example, filenames may have spaces in them, but most don't. Experience shows that people forget about that possibility during development and testing. But backticks parse the string after interpolation, causes the spaces to be interpreted as distinct terms.

Here's an example using backticks to call md5sum to compute the MD5 of the empty file "test.txt":

  % touch "test.txt"
  % perl
  $fname = 'test.txt';
  $a = `md5sum $fname`;
  print("Got: $a\n");
  ^D
  Got: 8b8db3dfa426f6bdb1798d578f5239ae  test.txt
Looks good, right? Now try it with "test me.txt":

  % touch "test me.txt"
  % perl
  $fname = 'test me.txt';
  $a = `md5sum $fname`;
  print("Got: $a\n");
  md5sum: test: No such file or directory
  md5sum: me.txt: No such file or directory
This leads to all sort of fun (in the sarcastic sense) when people use variable names with shell metacharacters:

  % touch 'test.txt|echo hello'
  % perl
  $fname = 'test.txt|echo hello';
  $a = `md5sum $fname`;
  print("Got: $a\n");
  Got: hello

There are ways to avoid this, but as the FAQ points out at https://perldoc.perl.org/perlfaq8#How-can-I-call-backticks-w... , the solution is to avoid using backticks. (The example there is of passing an arbitrary search string to grep, without dealing with shell expansion.)

You might be interested to know Julia's take on the same operation. It parses the backtick-quoted string itself (without a shell), and handles interpolation in a shell-like way, with awareness of the underlying variable (eg, string, or enumerating a list or Cartesian product of strings). The result is a Cmd object, which can be passed to other functions to describe how to use or process the Cmd.

See https://docs.julialang.org/en/v1/manual/running-external-pro... .


  use IPC::System::Simple qw(capture);
  
  my $md5sum = capture(md5sum => $fname);
(discovering this exists is the tricky part, of course, but once you know it exists it works nicely)


I'd like to fat comma shame you for this, but I've done the same on occasion, so meh. The thing that irks me about it is that it appears as if the function takes a hash on first read, and I'll happily cargo cult the call style until I finally read the docs for capture, in this case. I don't know, would you put this in prod for other devs to maintain?


I tend to use it consistently to mean "the thing on the left hand side of this is a name", where in this case it's the name of a program.

The commonest case is absolutely the name of a hash key, but it's well worth learning to read it as "is a name of -some- sort" rather than this is a hash because there's a lot of other cases where it's used for different sorts of names, and that's been considered pretty standard for quite a while now.

Examples:

- DBIx::Class column and relationship definitions use it for the name of the thing (and if you generate your DBIx::Class code from the database schema using DBIx::Class::Schema::Loader that's what you're going to get).

- Moo/Moose/Mojo::Base code uses it in has() calls for the name of the attribute, and in before/after/around modifiers for the name of the method being wrapped.

- Mojolicious::Lite and Dancer2 both use it to separate the route name and the route handling subroutine when defining your app's routes.

- Code that can take a method name as the first argument, such as Mojo::Promise, curry.pm, Mojo::Base/Object::Tap's ->tap, and many others, are usually written with the method name followed by => as well.

I could think of more but I think that's quite sufficient to show that it's idiomatic at least in applications perl written using the common greenfield Web Framework(s), Object System(s) and ORM tooling of the time for at least the past 15 years.

I might not put it in production for non-perl-writing -sysadmins- to understand and maintain but for anybody whose job title is developer or who wants to be able to write perl code larger than a single file, I'd much rather teach them how => gets used for names in general since they're almost certainly going to run into it All The Damn Time in documentation, examples, libraries and the application code itself.


> For example, filenames may have spaces in them, but most don't.

This happens in shell scripts as well, and which is why ShellCheck has a warning for it:

* https://www.shellcheck.net/wiki/SC2086

Even with something like find … | xargs … can trip people up if they're not expecting it. It's certainly why GNU (?) added -print0 / -0, but find … -exec … \; works just as well.


That's a bit of a tradeoff though. If you expect that backticks pass things to the shell unchanged, like Perl does, you know what's happening. And as you mention, Perl offers other ways to skip passing to the shell and set args directly.

Julia's approach of parsing things in backticks does remove some footguns, but it also means you have to do things like this:

  julia> run(`echo hello \| sort`);
Else the pipe character is interpreted as a plain argument.


That just echoes "hello | sort", the backtick execution in Julia is only for single commands. For pipelines, there's the `pipeline` function, like so:

      run(pipeline(`echo hello`, `sort`))


Ah, yeah, I had misread the docs there. Though I imagine it creates that unexpected for beginner's thing where `ls | sort` comes back with "no such file |" or similar. Basically, I'm saying there is a place for an interface that does pass a single string to the shell, and an interface where you specify args explicitly.


FYI one of the things I like about Julia is that it also can execute shell commands via backquote syntax, in a very nice way (e.g. interpolating arrays just works). E.g. try

    files = split(read(`ls`, String))
    firsttwo = files[1:2]
    run(`ls -l $firsttwo`)
and this does the right thing even if you have a filename with spaces in it. or this


> I'm learning perl right now and I'm bewildered at how could I overlook it for such a long time.

perl is really great at what it's great at. I say that's anything with a substantial need for text manipulation and regex handling and/or anything with a lot of interaction with other CLI tools. There is no other language that makes such tasks as quick and painless as perl. It's a wonderful tool in the toolbox. Not one I use most often but when it's needed, it's awesome to have.


It's an odd critter, but it gets the job done. There are a few pitfalls, such as list flattening, but in my experience, once you are aware of them, they are not hard to avoid.

If you are new to Perl, I highly recommend reading Damien Conway's Perl Best Practices. Even if you end up not picking up all the suggestions, it is worth thinking about them and the problems they try to address.


  the ability to embed a shell command in backquotes and get its output easily
Aside from that being a gigantic footgun, you can do this in Ruby, PHP, and in POSIX shells but not in Javascript or Python.


Never knew you can do it in Ruby too, thanks for sharing. I’ve missed that from python a lot.


So I firmly believe that using shell expansion in your scripts is a horrid idea no matter what the syntax. But while you're thinking about backticks and ruby:

Much like a modern POSIX shell you can also use the more ergonomic %x (e.g. %x{echo true} %x(echo false).

Backticks will perform string interpolation before execution just like a normal double quoted string.

Backticks are simply a method, so you can redefine that on any object.


Not sure why you think python can’t do this. I do it all the time.


I'm reasonably sure you don't "embed a shell command in backquotes" all the time in Python (and I don't think this is pedantry; the specific ease of this syntax was the claimed benefit, not just the ability to shell out in some way).

Backticks were an alias of `repr` in Python 2.x:

    $ python2.7
    Python 2.7.6 (default, Nov 13 2018, 12:45:42) 
    [GCC 4.8.4] on linux2
    Type "help", "copyright", "credits" or "license" for more information.
    >>> foo="this is foo"
    >>> `foo`
    "'this is foo'"
And it went away in 3:

    $ python3
    Python 3.11.3 (main, Apr  5 2023, 15:52:25) [GCC 12.2.1 20230201] on linux
    Type "help", "copyright", "credits" or "license" for more information.
    >>> `ls`
      File "<stdin>", line 1
        `ls`
        ^
    SyntaxError: invalid syntax


How? I only know of subprocess.


Doubtful.


Do make sure that 100% of the input is from trusted sources because if not, writing secure Perl programs is extremely hard. The tainting system helps but doesn’t solve the problem.


Taint mode is something I've never got along with, but for running external programs p3rl.org/IPC::System::Simple lets you make all the shell injection risks go away (and can be used in a script destined for p3rl.org/App::FatPacker so you're still deploying a single file).

Writing secure anything is extremely hard, but 'avoid backticks, single-arg system, and 2-arg open like the plague' tends to reduce the hardness in perl back to something reasonable similar to the hardness of doing it in other languages.

(at least it's not shell ... arghsob)


The main highlight of this release is the new OOP system: https://perldoc.perl.org/5.38.0/perlclass


Oh no, perl code is going to be hard to understand now


It’s always been a write-only language.


Was it really not possible to make that a shorthand for the existing structure with blessing variables? Having two object systems may make things too confusing.


This was brought up a few times. There were several issues with that approach.

* `bless` and `class` aren't topologically equivalent: you can't twist and warp one into the other

* We've seen small, incremental steps get beaten to death by bike-shedding every step

* Sometimes it's hard to see the big picture when you're looking at the individual details

It's that first point that's really the killer here. Perl used `bless` and `@ISA` ("we have methods" and "here's where to find them") and that was all.

You want state? Figure it out.

You want encapsulation? Figure it out.

You want to work around MRO bugs? Figure it out.

You want to know if something in the symbol table is a subroutine or a method? Figure it out.

You want composition? Figure it out.

Much of what we wanted just couldn't be easily done building on a broken foundation, but there's so much excellent work out there which already solves these problems for class-based OO, we decided to take advantage of what others have already learned.


Thanks. I admit I haven't often used Moose et al., or any Perl OO system, except in a project that was set up by someone else in which I only occasionally added a method.


The prior "object system" was just a way to stuff things into the symbol table. I'm hand waving here, but the point is it that the scope of that system ended at "calling a method on an instance of a class" and there was nothing beyond it unless you rolled that all yourself:

    abstract classes
    derived classes / polymorphism
    attribute type constraints
    delegation
    encapsulation
    composition (roles)
    immutable state
    and so on
And many people did roll their own, which resulted in Moose (Moo, et al) on CPAN, which have evolved to be some of the best in class (ha) object system frameworks and features across any language.

Now the plan is to get that into the core, and this is the first step.

No serious Perl developer has been using bless for OO for a least a decade, unless they were constrained by micro optimisations and/or not being allowed to use non-core dependencies.


I consider myself a serious Perl developer, working in a Perl shop for the past 15 years. We still prefer using bless and continue to use it in the present day. It so much lighter weight than the M* systems and I prefer the simplicity and speed of it.

All I need is magic structs with methods and that provides it. Throw in a constant array of properties and an AUTOLOAD, and you have accessors if you need it.


> and/or not being allowed to use non-core dependencies

And at least p3rl.org/Moo works with p3rl.org/App::FatPacker because I designed them to play nice with each other.

I once fatpacked an http://p3rl.org/Eval::WithLexicals tinyrepl on the fly mid-conversation for Bruce Momjian of postgresql fame.

He wanted to try a repl with persistent lexicals but his NetBSD install was getting sufficiently long in the tooth he didn't want to risk running CPAN on it - and fatpacking a script I had handy was a lot quicker and more effective in terms of getting him to try something out than trying to convince him to let me walk him through a local::lib setup.


Have you tried Cosmopolitan perl? (https://computoid.com/APPerl/)

Now that APPerl XS support has improved, I want to play again with it again.

Earlier this year, I did fatpack few things in a "dirty" way: by adding them to APPerl.

Still, this gives you a perl.com working anywhere, with all the modules you need, executing by default the payload of your choice.

I had a lot of fun writing a very barebonne webserver (https://github.com/csdvrx/PerlPleBean), along with a few side utils to do mDNS to expose the webserserver on .local (https://github.com/csdvrx/PerlPleBean/blob/main/experiments/...), run perl scripts on uploaded files etc

Someone with your experience could certainly do many more interesting things with APPerl :)


fatpacking bolts the source code untouched onto the front in a way that leaves you a single readable pure perl file - and is limited to pure perl modules as a deliberate decision to keep things simple and clear even if you've never encountered a fatpacked script before. Well, also because trying to pack XS is a freaking nightmare - that way would lie recreating PAR and Audrey's busy being a minister in Taiwan's government so generally not easy for me to consult these days.

Ok, I do actually have a hilariously awful trick that manages to wrap DynaLoader to read from a Base64 encoded .so that's inlined into the fatpack but that was more a "wondering if I could" thing than something I've ever felt the urge to actually use in anger so I've (so far) resisted the siren song of CPANing it anyway because people have an unfortunate tendency to forget that I, too, release things that are terrible ideas sometimes.

(though being able to use XS modules with a single file you squirt over an ssh connection ala Object::Remote without needing to write anything to disk is kinda fun, especially when you do it with DBD::SQLite ;)

APPerl sounds like it could be awesome, App::staticperl is the closest to it I've looked at so far, though since APPerl definitely wants to write to a non-noexec filesystem I wouldn't be surprised if I there are cases where if I had that and a toolchain available I'd end up using it to run Perl::Build to bootstrap a more normal perl and then go from there.

Either way, thank you very much for pointing out APPerl's existence to me. Even if I don't end up using it myself, having it in my mental index of available crazy things will almost certainly eventually result in my suggesting it to somebody else who'll find it the least insane way of getting the results they need :D


> Audrey's busy being a minister in Taiwan's government so generally not easy for me to consult these days.

That must be quite a timesink lol :)

> Ok, I do actually have a hilariously awful trick that manages to wrap DynaLoader to read from a Base64 encoded .so that's inlined into the fatpack but that was more a "wondering if I could" thing than something I've ever felt the urge to actually use in anger so I've (so far) resisted the siren song of CPANing it anyway because people have an unfortunate tendency to forget that I, too, release things that are terrible ideas sometimes.

Actually, I think that could be a great idea for cosmopolitan binaries!

Right now, you have to recompile perl to add the XS you want, and some don't work yet: it all depends on the build tool for the XS module being supported

So could you please tell me more about your trick? (or just link to it, I kinda get the idea but an actual example might help)

> APPerl sounds like it could be awesome

It already is: the perl.com binary is a polyglot zip file, where you can fatpack perl scripts by appending them to the zip file

If you've got 5 min, run perlplebean.com: just be careful, as by default I expose your filesystem for http requests. Just comment out that part if you don't like it (it's meant to make people check and tweak the source)

> APPerl definitely wants to write to a non-noexec filesystem

Yes, perl.com has to be executable :)

But on Linux, you may be able to use ld-loader to run it (like how a .sh script on a nonexec fs can be run as `sh -c file.sh`)

> Either way, thank you very much for pointing out APPerl's existence to me. Even if I don't end up using it myself, having it in my mental index of available crazy things will almost certainly eventually result in my suggesting it to somebody else who'll find it the least insane way of getting the results they need :D

Sure, feel free to get in touch at my nick at outlook.com!

It's a bit strange for me to dig into perl now, while it was "current" more like 20 years ago, but I just love it!


I wasn't saying anyone seriously used that for OO. (There are still uses for tying.) But it would have been nice to have one integrated mechanism, with class syntax for high-level use and bless for low-level access. And maybe with some magic in the high-level syntax that you couldn't access with bless, like actually making members unreachable, that'd be fine. I assume it has been looked into and found to be impossible, but I'd like to know why.


Roughly, because (a) performance (b) the intention to makie it still possible to poke into an object's guts but more obvious that's what you're doing (c) if you really want the class syntax atop a classic blessed reference, p3rl.org/Object::Pad will do that if you configure the :repr (that's basically the cpan testbed for a lot of the ideas that have gone into core and written by the same LeoNerd)


sigh no, the plan now is to get something completely different into core that is fundamentally incompatible with many of the things we like about Moo. It puts up firm barriers between parent and child classes which forces all the interaction to go through methods, resulting in a huge extra API burden for authors reminiscent of Java, especially for constructors. The end result is worse performance, too.


Writing bless() yourself has only ever been advisable for low level code or as an optimisation for a couple of decades and most professional perl programmers are well aware of that.

Generally you'd use one of the M* systems - p3rl.org/Moo or p3rl.org/Mojo::Base or p3rl.org/Moose - the last one having a full metaprotocol, the other two being rather lighter weight but still with enough features to keep you relatively sane.

The new system is actually not that dissimilar to those in terms of the conceptual model even where the names and syntax are slightly different, so anybody who's been writing production OO code in the past ten years shouldn't have that much trouble switching across.


That certainly seems way better than the old way of having to include the inscrutable line noise to construct, fill and then bless a hash reference in every single class, which is what we had to do back when I programmed perl.


Since about 2008-01 or so, using Moose, we've been able to do something like:

    { package Point;
      use Moose;
      has 'x' => (is => 'ro', isa => 'Int', required => 1);
      has 'y' => (is => 'ro', isa => 'Int', required => 1);
      sub as_string {
        my $self = shift;
        return sprintf '(%d,%d)', $self->x, $self->y;
      }
    }
    my $origin = Point->new(0, 0);
    say $origin->as_string;


Moose is one of those things I always mention when people ask what Perl did right.

It wouldn't hurt other languages to have a higher order object templating system.

Other things it did right is the taint flag to keep user supplied data from hitting sensitive functions by way of the type system. (In Rust you can declare your own type to achieve this, and it's actually enforced.)

The unicode system was actually decent in ways nothing else is, at least until the Go and Rust generation. Python 3 wasn't nearly as complete despite being more than a decade later.

If people ask what Perl did wrong, the dereferencing syntax is at the top of my list. Not having multidimensional arrays as a first class type probably did more to scare people away than anything else.


After the first deref, deref is assumed. Given:

  my $aref = [1,2,[3,4,5,[6,7] ] ];
You can do

  print $aref->[2][3][1];
which yields:

  7
Or

  my @array = (1,2,[3,4,5,[6,7] ] );
  print $array[2][3][1];
  7


And in the new class syntax, when it's done, that's (roughly):

    class Point {
        field $x :param :reader;
        field $y :param :reader;

        method as_string() {
            return "($x,$y)";
        }
    }
    my $origin = Point->new( x => 0, y => 0 );
    say $origin->as_string;
I know which of the two I'd rather write :)

The main limitation is that we don't have the `isa => 'Int'` check. That's largely because adding types is something for the entire language, not just this new syntax, so it had to be delayed.


This is just the start of adding it in. They are adding the foundational things and then will be incrementally fleshing it out.


Perl is such an interesting language. It's the first language I learnt seriously (pity me) and despite its quirks and failings, it was always a huge amount of fun.


Larry Wall was a genius.


He's still alive.


Why did Perl never maintain its popularity?


Because PHP (heavily inspired by Perl, but not as well thought out) came with all the glue to directly use it to generate web pages. Then came Ruby (also inspired by Perl, but with a more mainstream syntax, and nicer in some ways), and Ruby on Rails conquered that space even more. Also, Python came along which is indeed a bit more suitable for larger projects needing structure.

Meanwhile, Perl was being badmouthed by people who couldn't handle its flexibility and thought it was unreadable and unmaintainable. But that wasn't the main issue, after all PHP was worse in those two respects, yet it flourished.


Ruby is very cool as an easier, shinier, more ergonomic and elegant Perl but the lack of block-based lexical scoping with compile time checking (use strict + my, duplicated as "use strict" and let in ES6, much to my happiness when using javascript) and the fact that while Ruby's core OO is much easier to use than bless() it's horrifyingly limited when you're used to Moose/Moo means I've always bounced off it when I've tried to learn.

Perl's sheer flexibility means there's a gulf between baby perl and good complex perl during which the developer doing the learning tends to make a complete mess (I definitely did this for a while) and some people never get past that stage so a lot of pre-existing perl code is awful and much though I love perl myself the language is definitely at least partially to blame.


Many of us wrote our own 'php' in those times. Just some (fast)cgi blurp that read a vanilla perl file and wrapped it (via Apache pre-script/post-script) in the tooling to get the $_GET/$_POST, print "Content-Type: text/html\n\n", set/get cookies etc and returned the output of the script as something like XML. We stuck with Perl for a long time because of cpan and it was, especially then, a much better language when used in the right way. It was often abused (and I still do, because slightly complex scripts are still really easy to do in perl), but so was php. So I'm guessing the ease of php deployment if you didn't have access to the Apache of the server running would be a big thing.


I was there during the transition. Even rewrote a site from perl to PHP.

For newbies, not having have to write the "magic" string,

  print "Content-Type: text/html\n\n";
before being able to output anything probably felt quite friendlier and being able to mix HTML into the code, though it's not a good practice.

And the PHP standard library has quite a few things built in and combination of MySQL as LAMP was the hot word then, so I guess that's how it got traction and perl was gone from the web development.

I do like the Unix heritage of perl though. It does make you feel like a hacker when it feels the language has the shell syntax half baked in.


    print $q->header();
From CGI is better in most cases. Modern web development with perl is lots of fun with Mojolicious:

https://mojolicious.org/


The CGI module is no longer shipped with Perl (as of 5.22)

https://metacpan.org/pod/CGI::Alternatives


And nobody starting web dev now with perl should even consider it. Modifying an existing script that otherwise 'just works' sure. In my various other posts here I've recommended Mojolicious.


You saying nobody starting web dev should use CGI.pm? Or CGI in general? Because CGI itself has its uses even today. It's much easier to understand and get off the ground than something like Mojo or Plack (I've used them all), and has its strengths compared to the others.

However, if you are saying no one should use CGI.pm, then I agree. That module is a bloated mess. Much more efficient ways to use CGI without that thing.


CGI.pm, it's in response to the CGI::Alternatives post above.


PHP is "worse" in these respects when compared to other mainstream languages, yes - we can probably grant that, although it's not as bad as it once was.

Perl is just one big game of code golf. There is absolutely an entire era of developers who looked at that and ran far away (and I do not blame them at all).


> Perl is just one big game of code golf.

With respect that's just not true.


"one big game of code golf" would probably be a decision by the author, wouldn't it? I know a person or two who could fall into that category, but it's hardly the fault of the language.


No, this is specifically a comment on the syntactical choices often found in Perl codebases and the penchant for brevity that is common in that community.


I think the other problem was that Perl 6 came out and was totally incompatible with previous versions. Python did something similar with 2->3 and it caused huge problems.


That was later though. Interest in Perl was already declining a bit then. And the problem was more that the design and implementation of Perl 6 (now Raku) took extremely long, and attention to Perl 5 suffered from that, as Perlistas thought Perl 6 would be the Next Great Thing.


Perl 5 -> 6 was much more comprehensive than Python 2 -> 3. Perl 6 is almost a completely new language.


Not "almost", it is a completely new language with a passing ressemblance and IIRC was by and large advertised as such from the get go; the name "Perl" was kept as it was a spiritual successor, which they realised made it confusing so they changed it to Raku.

Perl 5 and 6/Raku have as much in common than Perl 5 and Ruby have.


IIRC was by and large advertised as such from the get go

It was not. For many years it was advertised as the next version of Perl (with the intent being perhaps a Perl 5.10 release and then no more major releases with the 5 version number), then years later a "sister language", and then finally now (but not retroactively) a "completely new language in the Perl family".


Hmm, that's not what I recall.

Very early (2000) the goal was for Perl 6 to be a rewrite[0]. There's no way this would have been a 5.x, especially given how the Perl 5 parser works and the class of warts that were aimed to be addressed:

> Perl 6 To Be Complete Rewrite (But Not What You Think)

> Perl 5 will not be abandoned, but will primarily be concerned with bugfixes both major and minor.

> The meeting for members of the perl5-porters mailing list was the result of an earlier, smaller meeting of Wall, Nathan Torkington, Chip Salzenberg, and others who basically decided that Perl needed to be fixed in certain ways, and that a rewrite was the best way to do it.

Quickly, being free from backwards compatibility gave room to try stuff out, and given the length of that design process, this resulted in features that they found out could be immediately useful if backported in some way to Perl 5:

> First, Perl 5 isn’t going anywhere. If anything, the rate of patches and changes to the code has increased. Cleanups from Ponie and the Phalanx project continue to improve the design and implementation, and new features from Perl 6 are making their way into Perl 5.

> Second, the opportunity to do the right thing without fear of breaking backwards compatibility opened up a lot of possibilities for impressive new features.

Granted, there's the following bit in the 2000 post:

> have a clear and automated migration path, which may include a backward compatibility mode

But back then (ca 2002-2005) I was only a Perl apprentice and a very junior developer yet it still struck me that the discussions highlighted differences that were expansive and fundamental enough that "next version of Perl" meant Perl 6 would be to Perl 5 what e.g Mac OS X† was to macOS 8/9 and (in retrospect since that happened only later) significantly different in class from e.g Python 2 to 3 or MRI to YARV.

That was my perception of it anyway; probably they weren't entirely clear what was the actual goal, hence a lot of bits were open to interpretation, and it got refined and bounced back and forth around a general baseline direction over 5-10 years.

[0]: https://developers.slashdot.org/story/00/07/19/203221/larry-...

[1]: https://www.perl.com/pub/2006/01/12/what_is_perl_6.html/

† which had classic mode to run the previous one's apps


Yes, this was my case, I started with Perl and then I moved to PHP.


>> Why did Perl never maintain its popularity?

It is usually installed by default on most Unix and Linux systems. It also rides along with most MinGW-based toolkits like Git for Windows. If you do software development, there is a good chance you might have Perl installed and not even know it.

Some people like to make fun of it despite its wide-spread use and utility. Most of them probably know little to nothing about Perl and have not written or maintained any Perl code. There is a good chance that they are using Perl code without knowing it.


Amazon.co.uk was built in Perl and Booking.com is still a Perl shop.


>> Amazon.co.uk was built in Perl

Yes. All of the Amazon retail web sites used Perl Mason running on Apache mod_perl:

https://metacpan.org/pod/Mason

http://www.masonhq.com/htmlmason


IIRC, early Perl was missing little things like named function arguments. So a lot of perl code was really inscrutable. I think “scrutability” is a huge driver of adoption… it’s why HTML and JavaScript became popular - and I reckon it’s why Perl burned out. It’s certainly the reason I never adopted it.

Well, that and CPAN…


I wouldn't say its "missing" named function arguments. Treating arguments and return values as lists is very powerful. Perl is very Lisp-like in that aspect.

Also, CPAN is considered one of Perl's strengths. How did CPAN cause Perl to burn out?


In terms of arguments, there's no reason that Perl couldn't have had named arguments and still passed lists around behind the scenes. But the lack of arguments really makes it hard to understand what those arguments are supposed to be. The question is why Perl didn't continue to dominate the scripting landscape and I simply offer this as one possibility.

My recollection of CPAN - and we are talking a really long time ago now - but it was just very much the same kind of dependency hell that we now have with NPM. In fact now that I mention it, I think there are strong comparisons to be made between Node and Perl. CPAN was great until it wasn't, and after a while - in my experience - it was mostly not great.


> early Perl was missing little things like named function arguments

It's still missing those :)

(To be clear for people unfamiliar with Perl, it probably will never have them, because it doesn't need them. In Perl, all functions effectively have a single parameter of array type. The standard convention is to assign each array entry to a variable at the start of your function definition, and the names of those variables then effectively act as parameter names. But that's just a convention and you can do something else if you want.)


I know cygx already replied, but to be clear, function signatures have been available in Perl since 2015. They were added (as experimental) in 5.20, and are now enabled by default with `use v5.36` or later.

All new features must now go through an experimental phase after the smartmatch debacle. Signatures stayed in experimental status a little longer than most new features due to an unfortunate change with respect the order of function signatures and function prototypes. Provided you weren't using prototypes (which you almost never need) then they've been largely stable since 2015.

Most distro's under current support ship with at least Perl 5.24, so you can use them almost anywhere.


Nowadays, sub signatures can be enabled via

    use feature 'signatures'
which is implied by

    use v5.36


"Unrolling @_" is still a Perl ritual.


<ok, let's see..>

@_

@_____

@________

<wow, this thing is long>

_____________

<success!>


I've made a presentation about it in 2013[1]. Back in 2000, when Perl was riding high and 13 year old, Larry Wall announced "Perl 6". However Perl6 (now Raku) was hugely ambitious and not production-ready until 2015 ...

So for the best part of the naughties, people said things such as "don't bother learning Perl 5, Perl6 is coming"... Then the 2010s came and people got on the RoR and PHP and Python trains in the meanwhile instead.

https://www.slideshare.net/eflorac/perl-presentation-2013-pa...


Back in 2000, when Perl was riding high and 13 year old, Larry Wall announced "Perl 6".

Rinding high is something of an overstatement: The Big Thing at the time was Java, and PHP was already chewing away at Perl's market share. Some people thought the writing was an the wall, hence the mug-throwing incident that launched the Perl6 effort...


From my perspective (over a decade of Perl programming now doing Go):

  * It has no concurrency primitives that are anywhere close to other popular languages
  * Tooling is good and works but is archaic, slow, and cumbersome
  * The community hasn't positioned itself to be anything other than lightweight backend services and small webapps (smaller than rails)
  * The community isn't really all that inviting or fun to be around
Basically Perl offers me nothing that Go doesn't. I'm just as fast in Go as Perl and it's much easier to get stuff done. It's sad because it has some really good features that I miss but I just rewrote a final project from Perl to Go and am never looking back.


> It has no concurrency primitives that are anywhere close to other popular languages

I can switch between writing async/await based $other_language and

  use Mojo::Base -signatures, -async_await;
for my p3rl.org/Mojolicious code and keep all the same concurrency based patterns just fine. Trivial example of the sort of code I can write given that 'use' line:

  async sub url_body ($self, $url) {
    my $tx = await $self->ua->get($url);
    return $tx->res->body;
  }
It's fair enough if you prefer go's lightweight threading plus channels CSP model but async/await is IMO a perfectly reasonable approach.

(the -async_await feature flag is powered by p3rl.org/Future::AsyncAwait which works fine with p3rl.org/Future and p3rl.org/Future::Utils as well as p3rl.org/Mojo::Promise in a single process - and since p3rl.org/Mojo::IOLoop and p3rl.org/IO::Async will share an event loop I often find myself using things based on both since it's all await-able)

p3rl.org/App::cpanminus plus p3rl.org/Carton (or my p3rl.org/App::plx) doesn't tend to be archaic or cumbersome to me (classic CPAN.pm, sure, but since cpanminus and plx are both distributed as p3rl.org/App::FatPacker bundled script s via github you can bootstrap them without ever loading CPAN.pm) - I generally find it less of an aggravation to deal with than most other languages' approaches (go's isn't bad at all, but e.g. virtualenv is very much not my cup of tea).

As for slow, the main thing that makes installation from CPAN slower is that our tooling tends to run tests by default - I'm aware that these days "verifying your dependencies actually work at install time" has gone out of fashion in favour of faster installs, but if you're happy with that trade-off pretty much everything has a 'notest' flag available.


Far too late to edit now but I'd note that Future::AsyncAwait is implemented using only public APIs - it adds the keywords using the pluggable keyword API that was added in 5.14 and 5.16 (though while code written against the 5.14 version continues to work AFAIK given we're on verion 38 of perl5 now I wouldn't bother even looking at it except out of historical curiosity).

So, basically, adding new keywords to perl via CPAN is a first class citizen and has been for over a decade now and we've gotten pretty good at it in that time (see also http://p3rl.org/Object::Pad - which has acted as a proving ground for a lot of the ideas that have gone into Cor - for another good example) and while I wouldn't at all object to F::AA eventually migrating into being a core feature, from a user POV it would just mean a slightly different 'use' line and maybe a few percentage points' speedup.

As such, I personally believe that while I understand that some environments have unfortunate issues with having dependencies, every other reason I've heard articulated for treating a keyword module as an inferior bolt-on as compared to a core keyword has proven unsupported in actual use.

Generally I code to (a) core perl only, mostly for one-liners embedded in shell scripts and occasionally for really small stuff, (b) pure perl dependencies only so I can easily deploy a single file with App::FatPacker or no file at all with Object::Remote, and (c) this project is best done using XS stuff and I'm willing to accept the trade-offs.

I'd note that Future::AsyncAwait itself sits in an interesting middle-ground because with a little help from my http://p3rl.org/Babble source transformer (needs more documentation though the current release manager has improved a lot of things over the 'just enough to do what I needed at the time' I originally released) I wrote http://p3rl.org/PerlX::AsyncAwait which rewrites most F::AA using code successfully to pure perl for fatpacking, at the cost of you ending up with an implementation that's mildly bizarre at first look and will be substantially slower on microbenchmarks.

(I say 'most' because I presume there's at least one bug and I'm certain that F::AA has added support for additional perl syntax constructs since that I've not gotten around to going back and adding yet, but so far in the situations where I want a fatpacked async/await using script badly enough PerlX::AsyncAwait has worked well -enough- overall that I've yet to feel the need to give it an overhaul even if I'm happy to admit it would probably benefit from one)


Yay, more bolt-ons. Like I said, I left all this behind.


Comparing Go to Perl is apples to oranges.


I got the impression back then that Ruby on Rails ate a lot of Perl's use cases. And the Perl 6 thing probably didn't help either. And it might have acquired a bad reputation due to the fact you can easily write really terrible code in it.


It was always easy to write unmaintainable code in. As time went by other languages caught up with the things Perl did well (dependency management with a large base of libraries available, automated tests that you could have confidence in because they ran by default as part of installing any package, lightweight syntax that makes easy things easy, easy to make available in a shared hosting environment), whereas Perl's biggest problem was inconsistency which was essentially impossible to fix (except with a big rewrite of the whole language, which they did try, but...).


> As time went by other languages caught up with the things Perl did well

except regex handling which is still somehow way more awkward in other languages.


For me, Perl’s tight syntax let you get a lot of stuff done but lacked the consistency of simpler, more verbose languages better suited to multiplayer teams.


One possible factor is the cost of backwards compatibility.


I couldn't find this info: is this work sponsored / requested by some company, or were the two authors adding this just because they care?


Ovid led the specification effort and did all the boring writing it up stuff because he wanted it to exist, Stevan Little (author of Moose) originated the idea but got distracted by real life before he got it finished, a bunch of us (including me quite a bit and even Damian Conway briefly) with a shitload of OO system design experience consulted and suggested and gave feedback.

LeoNerd (Paul Evans) I believe did a bunch of the code for both p3rl.org/Object::Pad (which was significantly an on-cpan prototype for this work) and the 'class' feature on his own time and also a bunch of it via sponsorship, though I'm less confident of the details there because since I can't write C to save my life I spent my tuits on the design and cat herding side and just assumed LeoNerd would get it right.

(the same approach worked out pretty well during the period he was doing dev work for me at https://shadow.cat/ too and we still keep an open contract with him in case we run into a LeoNerd-shaped problem, he is Just That Good IMO)


Which "two" authors?

Perl continues to flourish into its fourth decade thanks to a vibrant community of users and developers. The following people are known to have contributed the improvements that became Perl 5.38.0:

Alex, Alexander Nikolov, Alex Davies, Andreas König, Andrew Fresh, Andrew Ruthven, Andy Lester, Aristotle Pagaltzis, Arne Johannessen, A. Sinan Unur, Bartosz Jarzyna, Bart Van Assche, Benjamin Smith, Bram, Branislav Zahradník, Brian Greenfield, Bruce Gray, Chad Granum, Chris 'BinGOs' Williams, chromatic, Clemens Wasser, Craig A. Berry, Dagfinn Ilmari Mannsåker, Dan Book, danielnachun, Dan Jacobson, Dan Kogai, David Cantrell, David Golden, David Mitchell, E. Choroba, Ed J, Ed Sabol, Elvin Aslanov, Eric Herman, Felipe Gasper, Ferenc Erki, Firas Khalil Khana, Florian Weimer, Graham Knop, Håkon Hægland, Harald Jörg, H.Merijn Brand, Hugo van der Sanden, James E Keenan, James Raspass, jkahrman, Joe McMahon, Johan Vromans, Jonathan Stowe, Jon Gentle, Karen Etheridge, Karl Williamson, Kenichi Ishigaki, Kenneth Ölwing, Kurt Fitzner, Leon Timmermans, Li Linjie, Loren Merritt, Lukas Mai, Marcel Telka, Mark Jason Dominus, Mark Shelor, Matthew Horsfall, Matthew O. Persico, Mattia Barbon, Max Maischein, Mohammad S Anwar, Nathan Mills, Neil Bowers, Nicholas Clark, Nicolas Mendoza, Nicolas R, Paul Evans, Paul Marquess, Peter John Acklam, Peter Levine, Philippe Bruhat (BooK), Reini Urban, Renee Baecker, Ricardo Signes, Richard Leach, Russ Allbery, Scott Baker, Sevan Janiyan, Sidney Markowitz, Sisyphus, Steve Hay, TAKAI Kousuke, Todd Rinaldo, Tomasz Konojacki, Tom Stellard, Tony Cook, Tsuyoshi Watanabe, Unicode Consortium, vsfos, Yves Orton, Zakariyya Mughal, Zefram, 小鸡.


I'm guessing they mean the two folk listed in the AUTHORS section of the `perlclass` page:

https://perldoc.perl.org/5.38.0/perlclass#AUTHORS


this the repository of initial draft:https://github.com/Ovid/Cor

after they proposed this, people debating around this in long time.


Time to get perlbrew'ing!


  perlbrew install 5.38.0 -Dushrplib
  cd ~/wdir/my-new-project; git init; plx --init 5.38.0
<3


Sadly, Strawberry Perl remains stuck on Perl 5.32.1.1 "Released: Jan 24 2021"

https://strawberryperl.com/



Wishing that the development of this whole Class feature would be done quickly, and that people use it for OO more often.


Perl 7 plan has been abandoned?


The original perl7 plan never got past the RFC stage for multiple reasons.

The current intent is to get things like the new class syntax (plus a number of other features, the exact list of which escapes me right now) shaken out and stabilised and then release a perl7 where 'use v7;' gives you the new baseline set of features while still being able to be /usr/bin/perl without breaking e.g. the PostgreSQL and OpenSSL and etc. build systems.


See "What happened to Perl 7?" from the Perl Steering Council in May last year: https://blogs.perl.org/users/psc/2022/05/what-happened-to-pe...


I presume this statement from May 25 is still valid: https://blogs.perl.org/users/psc/2022/05/what-happened-to-pe...


Discussed on HN back then:

https://news.ycombinator.com/item?id=31515787 (237 comments)


No official download of sources/binaries available yet


Incorrect, the source has been released: https://metacpan.org/release/RJBS/perl-5.38.0


This is big :)




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

Search: