Hacker News new | ask | show | jobs
by codeflo 1488 days ago
I’ve written a nontrivial anount of Perl code in my life, admittedly almost none in the last decade. For all its obvious flaws, I always liked the language, and am happy to see it getting attention and moving forward.

Having said that, I think this might be too fine-grained.

First, opting in to an experimental feature could be a one-liner, “use experimental feature ‘try’” or similar. There’s no point in punishing your valuable beta testers beyond that with a second line that’s entirely redundant with the first one.

The larger problem is the versions. This basically requires someone to update their script headers all the time if they want to keep getting new features. Probably not much of a problem currently, but might be if releases get more frequent. I personally like the “edition” concept of Rust a lot better: get over with all necessary breaking changes in one swoop, but then begin a new (hopefully long) era of backwards compatibility. That makes it easier for users to maintain their code, is probably easier to implement, and also easier for users to learn, since there are fewer sets of rules.

Lastly, I hope they also focus on tooling around installation. One paradoxical problem with modernizing Perl is its historic success: every variant of Linux or Unix already comes with an ancient version of it. I know many experienced Unix people hate this trend, but there’s a reason some of the most actively evolving language ecosystems install more and more of their binaries into the user’s home directory. Maybe that’s already the case for Perl, I wouldn’t know.

All that said, I’m not following Perl that closely anymore. These are just some really quick observations about very complex topics. I don’t claim to know nearly as much as the people who made these decisions, and it’s great to see that things are happening.

7 comments

> The larger problem is the versions. This basically requires someone to update their script headers all the time if they want to keep getting new features. Probably not much of a problem currently, but might be if releases get more frequent.

But to use that new feature they'd need to modify their code anyway, so this isn't really an issue in practice, is it?

> I personally like the “edition” concept of Rust a lot better: get over with all necessary breaking changes in one swoop, but then have a new (hopefully long) era of backwards compatibility.

How is this any different from having a repeat of the python2->python3 fiasco (which, AFAIK, Perl developers are trying to avoid)? Making piecemeal (if needed) changes is much easier than having to update a ton of code and that is even more important when that code wasn't touched for a long time.

EDIT (i put it here since i already got three replies on the same thing): i understand that you can mix two different files with different "editions" but it still makes it hard to update these files themselves.

> How is this any different from having a repeat of the python2->python3 fiasco (which, AFAIK, Perl developers are trying to avoid)?

AFAIUI you can mix Rust 2015, 2018, and 2021 crates; so a developer can update their own crate to 2021, while not having to completely re-write the dependencies which are still Rust 2015. With Python 2 -> 3, my understanding was that everything had to be updated recursively.

That said...

> I personally like the “edition” concept of Rust a lot better: get over with all necessary breaking changes in one swoop, but then have a new (hopefully long) era of backwards compatibility.

What they describe actually sounds somewhat similar:

> At some point in the future, the PSC may decide that the set of features, taken together, represent a big enough step forward to justify a new baseline for Perl. If that happens, then the version will be bumped to 7.0. If this happens, Perl 7 will still be backwards compatible with Perl 5 by default – you'll have to put use v7; at the top of your code to use all the new features. Think of use v7 like Modern::Perl and similar modules.

So the 'use <feature>' is going to be similar to Rust's "nightly unstable features", but actually being stable; and 'use vN' is going to be like Rust's Editions.

It's just that they don't think they've accumulated enough features to release a new Edition yet.

Your last two paragraphs describe Rust’s process differently than I would in comparison to this suggestion.

First, significant new language features are introduced all the time, even in stable, all of them enabled by default (indeed, there’s no way to turn them off).

Nightly’s #![feature(…)] is strictly for experimental stuff that is buggy and/or will change until stable release. I’m sure you know this, but all of those are intended to be backwards compatible! I think that’s a big difference.

Incompatible changes in Rust never happen with “features” (as you know, stable doesn’t even have those), but only with “editions”. The goal of an edition is to carve out a large chunk of future design space, like introducing some keywords for planned features, or rarely, fixing really annoying inconsistencies that require a breaking change. They feel a lot more proactive (we want to do this, we need an edition) than retroactive.

Yeah, the crucial trick is that Rust is a single language but the Editions system lets people keep older syntax in source code, knowing it will be transformed into the single abstract syntax of that language.

Rust editions are not versions of the language, they're just syntax.

New features of the language in a new library or compiler version work fine in all editions unless they require syntax which isn't in your chosen edition.

Rust 2015 edition is only restricted to the syntax from 2015, all the features of today are available unless they're gated off somehow by syntax. For example the "async" keyword didn't exist in Rust 2015, so, you won't be using that from 2015 edition even today. But even though in 2015 you certainly couldn't go around evaluating u32::checked_div() in a constant, it works just fine in Rust 2015 edition today, because it's not gated by syntax.

> the Editions system lets people keep older syntax in source code

Perl 'features' are lexically scoped, and could be applied in a finer-grained style, if you like. Shutting something off locally is done pretty commonly (e.g. to silence an ignorable warning).

The Perl devs have a deprecation cycle to remove mis-features, even if that breaks backwards compatibility. They don't, as far as I know, make much effort to line that up with major version changes[1], it's more a matter of making sure there's a long period of warning.

[1] The difficulty of course, was that for a long time the language now known as Raku was squatting on the next major version, "6", hence the need to jump to "7" to avoid confusion with Raku.

In fact, it is much more similar to how people expected the Haskell's extensions to work when standardizing the language than anything from Rust.

Anyway, on practice they didn't work like that.

> With Python 2 -> 3, my understanding was that everything had to be updated recursively.

You can mix "Python 2" and "Python 3" code, but the problem is (was) that the semantics in Python 3 surrounding string handling changed so much that in reality this was tricky to accomplish, and Python's dynamic untyped nature didn't help either.

But it was definitely possible to write libraries that worked with Python 2 and 3; I've made a few. It was pretty tricky though, and often led to bugs.

Python is dynamically and strongly typed. It's definitely not untyped.
The use pragma is scoped.
For all the buzz about python3 fiasco, we're pretty much migrated now and py2 gets dropped from supported versions and system repositories. Perl devs would be in a better situation with a "fiasco" like that. Ruby went through its own big breaking changes at least 2 times before as well. So... if people have good reasons to stay, a big change won't drive them away.
> For all the buzz about python3 fiasco, we're pretty much migrated now and py2

Python 3.0 was released in 2008, the fact that 14 years later 2.7 is still widely available (and often the default python, e.g. in my openSUSE Tumbleweed system here) means that the "buzz" was more than warranted.

Also of course things would migrate, it isn't like there was any choice on that matter (and projects like Tauthon that tried to provide a choice had several "Pythonistas" attacking it).

> it isn't like there was any choice on that matter

There was another choice. This is what I mean: however bad you think py2->py3 was, people are using py3 now unless they've got really good reasons not to and are prepared to suffer. When it came to perl5/6, it turns out over time most people choose "neither".

SUSE didn't update the link like others did so it's not really that py2 is the default, but python2 was always named python. It's going away anyway: https://www.suse.com/releasenotes/x86_64/SUSE-SLES/15-SP3/in...

The “neither” choice happened with Python 2/3 as well. The current re-emergence of Python as a machine learning/data science languages is basically a new trend. Long before that, before the Python 3 transition, there was a significant amount of buzz around everything from web frameworks to desktop GUI applications. The way I remember it, almost all of that attention was killed during the transition, when people tried Python and found a significantly lacking and confusing ecosystem.
"The current re-emergence of Python as a machine learning/data science languages is basically a new trend"

This new trend is about a decade old by now. Pandas was released in 2011, numpy in 1995. Google released Tensorflow to the public in 2015.

it was a trend made possible by numpy and scipy being built for a decade before the phrase 'deep learning' was coined. it had just the right mix to blow up: easy to read, easy to write, batteries included.

it wasn't inevitable, but it was damn likely.

> there was a significant amount of buzz around ... desktop GUI applications

As someone who is still supporting multiple desktop GUI applications in python, what did they pick instead? I'd love move off Python, but nothing else seemed to have the proper maturity.

> There was another choice.

Only if you count "not making a choice" (ie. staying with Python 2) as a choice. But this isn't really practical since everything else is pushed towards Python 3.

> Perl devs would be in a better situation with a "fiasco" like that.

Well, the hang-up in the roll out of "Perl 6" (now, Raku) gave people ammunition to shout about how "Perl is dead", but the central trouble was a lot of people wanted to spread that word. Myself, I think the success of a weirdo outsider language was making some insiders very upset, and they were fighting back any way they could.

Supporting older, variant behavior isn't really causing problems for the devs, from what I hear, when it does they go after it with the deprecation cycle.

Yes, but in some domains (for example bioinformatics) py2 is still a requirement for many packages. It really hasn't gone away. Ruby was far more elegant in its upgrades and nearly everyone upgraded their packages because the needed changes were far more minor. I have code from ruby 1.8.7 that still works with ruby 3.x.
> EDIT (i put it here since i already got three replies on the same thing): i understand that you can mix two different files with different "editions" but it still makes it hard to update these files themselves.

It does not, though? You have to update the entire file (really crate) at once, but that’s really not much of a challenge as it’s near exclusively syntactic, and syntactic changes are easy to make, just fix compiler errors.

I feel like you didn’t go through the Python migration yourself and just go off of the echoes you got from it, but the issues in the Python migration were not “updating code is hard”. It was really the easiest part, and could mostly be done mechanically (which incidentally `cargo fix` provides for when migrating between editions).

The challenges of the Python migration was:

- You had to wait for all your dependencies to be updated before you could migrate yourself, commonly this was mixed with API updates while at it especially at the start, this is not an issue in Rust because there is no dependency between crate editions, I can use edition 2018 and depend simultanously on edition 2015 and edition 2021 crates.

- Many changes were semantic in nature, there was no way to check them statically, instead they were runtime changes (in types or behaviour), which made ensuring they were correct a lot more challenging; editions do not cover or allow for this.

The Python migration wilfully included fixes to long-standing semantics issues of the language (though whether all were improvements, or whether they went far enough remains a matter of debate), and this as well as the incompatibility are what made it an issue.

If it had been entirely syntactic and a per-package or per-file thing it would have been much less of an issue (not an entirely non-issue as things like library contents are a runtime concern in python, but still…). And that’s what rust editions are.

Think about applications, not one-off scripts. It should be easy to always stay on the latest language version, with good tooling to migrate your code, and importantly, the ability to do it piece by piece. (Python 3 was all-or-nothing for the entire ecosystem.) Also, many migrations are trivial in practice, like renaming an identifier to avoid the new keyword.

What this gives you is high confidence that when inserting a few lines somewhere, that fancy new for loop simply works. No need to scroll to the top if the file and remember which exact release of the 27 in the last year introduced the feature.

> It should be easy to always stay on the latest language version

With perl you can upgrade your language version whenever you like, and do it reasonably safely, because there's a lot of emphasis on backwards compatibility.

Perl may actually have a "always gimme the latest features" option, but I don't know what it is, because things like that aren't really that popular in the perl world-- we want old code to keep working the way it always has.

Yes i know, in fact i thought about it when writing that line but i thought it'd be obvious that the issue still remains, especially if said files are too big. It might be easier but you are not really solving the problem as well as opting in to the new functionality when and if needed.
I hope we can agree that Python 3 was qualitatively different because all of your libraries had to migrate first.

Now, your new argument depends on how hard it is to migrate a single file. If that’s sufficiently easy, you simply do it. Migrating to the last Rust edition, I had to fix maybe a handful of things in an entire crate; most files didn’t have to be touched at all.

Certainly, Python 2 to Python 3 was harder due to all the dependencies and having to convert the entire program.

My argument isn't really about migration is about not having to migrate if you don't need the features while not losing anything - by opting in to the new features/changes you can use whatever you want without wasting time on changing your code to do the same stuff just in a different way (unless you decide that this different way is actually better and worth doing, but that'd be your choice and not something indirectly forced on you by the ecosystem you decided at an earlier point in time to rely on).

> How is this any different from having a repeat of the python2->python3 fiasco

A 2018 edition project (declared in the project config) is pinned to that version forever. You would have to switch to a new edition explicitly.

Well that was easy.

Python supported piecemeal changes with backported Python 3 features using the future imports. They were essentially the same thing as what Perl 7 is espousing minus the promise of a breaking cutoff.
IIRC you can mix different editions in a project, and I think backward incompatibilities are also fewer (and detected at compilation)
> How is this any different from having a repeat of the python2->python3 fiasco

Perl already had python2->python 3000 fiasco before python: PERL6

Perl6 was really a different fiasco.

Perl had the could be bytes, could be characters fiasco in 5.8, but they didn't include a bunch of other difficult changes at the same time. 5.8 could be a bit rough around unicode, but 5.10 was pretty solid as I recall, and you can always use bytes; in a scope where you need bytes.

> opting in to an experimental feature could be a one-liner

This exists since 2013. https://metacpan.org/pod/experimental

> Probably not much of a problem currently, but might be if releases get more frequent.

Very unlikely. Perl switched to a yearly release in 2010, it has been in use since and there is no indication for this to change. https://lwn.net/Articles/485569/#:~:text=a%20%22timeboxed%22...

> focus on tooling around installation […] install more and more of their binaries into the user’s home directory

Exists. Wouldn't be Perl if one hadn't the choice between multiple solutions.

https://metacpan.org/pod/local::lib https://perlbrew.pl https://github.com/tokuhirom/plenv https://metacpan.org/pod/perlall https://metacpan.org/pod/App::plx https://github.com/stevieb9/berrybrew

> I’m not following Perl that closely anymore

It is evident.

> This exists since 2013.

Good to know, but maybe it’s not my fault that I assumed an official post by the Perl Steering Committee on perl.org would show the best solution.

> Exists. Wouldn't be Perl if one hadn't the choice between multiple solutions.

That’s great, but you might notice that you’ve given me, who is new to these approaches in Perl, exactly no information on where to start.

> It is evident.

Yes, I was very transparent about the extent and recency of my experience. Luckily, that combative attitude to a mostly interested/positive comment isn’t representative of the Perl community as a whole, or there really wouldn’t be any users left.

> I assumed an official post by the Perl Steering Committee on perl.org would show the best solution

Different people have different opinions on what constitutes "best". The post author is conservative and values compatibility over conciseness.

> no information on where to start

If one doesn't know the difference, then likely local::lib is appropriate. It's already built into the installation tools: https://metacpan.org/pod/cpan#-I https://metacpan.org/pod/cpanm#-l,-local-lib

> combative attitude

The assumption of me wanting to fight comes as a surprise, but you got hold of the wrong end of the stick.

> First, opting in to an experimental feature could be a one-liner, “use experimental feature ‘try’” or similar. There’s no point in punishing your valuable beta testers beyond that with a second line that’s entirely redundant with the first one.

It is. "use experimental 'try';" works already.

> The larger problem is the versions. This basically requires someone to update their script headers all the time if they want to keep getting new features.

This is intentional. The largest strength of Perl is that, barring significant security-type issues, a script written in 1995 will still run with the version of Perl you've installed. If you write a script with "use v5.36", you would change that version only if you intend to modernize the script with features from a newer version, and determine that such features don't break the script. This is harder to determine for some features than others, for example applying the 'unicode_strings' feature to an existing script written without it is rather perilous.

Users do not "want to keep getting new features"; they occasionally decide to make an effort to upgrade the Perl interpreters on their servers and personal machines because they want some new features.

A "use v5.36" directive is going to be very opaque for many users, but it doesn't need to be understood to serve the purpose of determining the minimum Perl version to install in order to run a certain script very effectively.

If user = server administrator writing simple scripts, you are probably right. If user = a team of devs, I don’t agree. You often want to use new language features just to simplify a piece of code, and you don’t want confusing rules around when you can and can’t use them.
What confusing rules? Given the promise of perennial backwards compatibility, the rule that if you want to use a feature you have to upgrade to the appropriate Perl version isn't confusing.

Neither is keeping development environment up to date and letting Perl versions on servers lapse until you install the latest Perl version because you have new Perl scripts requiring new features, or there are urgent security fixes, or you are building a new server or container anyway.

You can't use the new feature without editing code to use the new feature. If you're editing code, bumping the version number at the top is trivial.
>>I know many experienced Unix people hate this trend, but there’s a reason some of the most actively evolving language ecosystems install more and more of their binaries into the user’s home directory.

The future is containers, which is basically increasingly thin images tailored to your application.

These days I struggle to find Perl on many EC2 instance I work on. Its always good to have something like Perl in your installation for some quick scripting work. But most don't have Perl installed.

>> I know many experienced Unix people hate this trend, but there’s a reason some of the most actively evolving language ecosystems install more and more of their binaries into the user’s home directory. Maybe that’s already the case for Perl, I wouldn’t know.

There's https://perlbrew.pl/ and there's cpanm with "use lib".

Seems like they could just lock all of the new features behind a “use x.x” line rather than going feature-by-feature. And they could include “use latest” or similar for people who don’t care about the risk and are fine just fixing things if they break.
No, that is what they are doing. "use v7;" gets you all the new stuff and that will continue going forward. They only listed what "use v7;" is the equivalent of in the article.