Hacker News new | ask | show | jobs
by gwd 1487 days ago
> 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.

3 comments

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.