[Although I haven’t seen an official notice besides a git commit that reverts the changes, by popular outcry these changes won’t be in v5.28. It’s not that they won’t happen but they won’t be in v5.28. People who depend on Perl should stay vigilant. My advice in the first paragraph stands—change is coming and we don’t know what it is yet.]

Perl v5.28 might do away with when —v5.27.7 already has. Don’t upgrade to v5.28 until you know you won’t be affected by this! This change doesn’t follow the normal Perl deprecation or experimental feature policy. If you are using given-when , stop doing that. If you aren’t using it, don’t start. And everyone should consider if a major change like this on such short notice is comfortable for them. It’s not a democracy but you can still let the core developers know which way you want your favorite language to go.

There are several knock-on consequences with the removal of when since so many broken features from v5.10 were entangled with each other. This is related to smart matching. I won’t go into the simplified smart matching and you can read the p5p thread for yourself. Blame Sawyer for kicking the hornets’ nest!

Remind yourself about when . You have to use it in something that topicalizes (sets the current element to $_ ). You can have multiple when blocks but the first one that runs its block stops that iteration because it has an implicit break at the end unless you use continue . You can have code between the when blocks. With no comparison operator in the condition it uses an implicit smart match against $_ (the topic):

use v5.10.1; for( $ARGV[0] ) { when( $_ ) { say "$_ is true"; continue } when( not $_ % 2 ) { say "$_ is even"; continue } when( 137 ) { say "Number is 137"; continue } when( @array ) { say "In array branch" } }

You could rewrite this with if but notice how ugly that last if condition is. A smart match against an array smart matches the topic against items in the array. If one of those is true the smart match is true. The grep checks every element and returns a count; the smart match can stop midway. You could fix that with first from List::Util (a core module) but it’s still a bit uglier:

for( $ARGV[0] ) { if( $_ ) { say "$_ is true" } if( not $_ % 2 ) { say "$_ is even" } if( $_ == 137 ) { say "Always true branch" } my $value = $_; # doubled $_! if( grep {$_ == $value} @array ) { say "In array branch"; next } #if( first {$_ == $value} @array ) { say "In array branch"; next } }

The job of when is now decomposed into two new keywords: whereso and whereis . Good luck explaining these in a way that anyone in your code review will remember. The keywords can still change and there’s no hardcore insistence on them. However, the words we normally use in speaking (“if” and “when”) are either taken or banished. I have my own suggestion later.

The whereso always tests its expression for a simple true or false. It does not impose any smart matching. Instead of an implicit break it has an implicit next (which is the same thing). break is banished with when because we never needed it (even if it was a C keyword):

use v5.27.7; no warnings qw(experimental); my @array = qw( 1 3 7 137 ); for( $ARGV[0] ) { whereso( $_ ) { say "$_ is true"; continue } whereso( not $_ % 2 ) { say "$_ is even"; continue } whereso( 137 ) { say "Always true"; continue } whereso( @array ) { say "In array branch" } }

In that last whereso the test is the number of elements in the array. It’s just an array in scalar context. If there’s at least one element its true. If I don’t want that I’m back to the ugly grep . Perl solves that ugly grep with a confusing (so far) smart match. I think many people would be satisfied with a new comparator in (as in Python) that evaluated to true or false if $_ was in the list. I don’t think we need it but it’s a request (and use) I see often.

I don’t like this keyword and I think most of the people who chimed in on the p5p thread hated it in the same way. “whereso” is an existing English word although I can’t recall if I’ve ever heard it in a modern context, I don’t think I could properly construct a sentence with it, and my spellchecker doesn’t recognize it. Perl 6 also uses so to boolify something; there’s a tenuous connection between the colloquial “so” as a logical connector and it’s use in Perl 6. I think it’s too clever for its own sake and sure to annoy the workaday programmer. I’m not sure how whereso is better than if other than the implicit next . But the keyword is not set in stone and I’m betting it will change before v5.28.

The smartmatching version is whereis . Now the array test checks if $_ is an element of the array. In the 137 case it checks that the value is exactly that:

use v5.27.7; no warnings qw(experimental); my @array = qw( 1 3 7 137 ); for( $ARGV[0] ) { whereis( $_ ) { say "$_ is true"; continue } whereis( not $_ % 2 ) { say "$_ is even"; continue } whereis( 137 ) { say "Is 137"; continue } whereis( @array ) { say "In array branch" } }

Notice that this works without explicitly enabling an experimental feature although I do get experimental warnings. I think this is an oversight because it reuses the switch feature name which is loaded automatically when you use (not require ) v5.10 or above. It should get a new feature name but I’m guessing that the wide-ranging scope of the change can’t co-exist with the old ways. I’m not happy that this hasn’t gone through the formal experimental feature process.

Perl v5.27.7 has an experimental feature that unexpectedly loads. I could turn off the switch feature ( no feature qw(switch) ) but I have no way to get back to its old behavior. This is quite unfriendly and breaks the social contract and comfort that perlpolicy was supposed to provide to enterprise users. This trust, once broken, will be almost impossible to regain. And, it’s easy to foresee future changes to this feature because that’s more probable that it will miss something or users won’t like it simply because so many new features have had that outcome.

I quite admire Python’s Enhancement Proposals and the visibility they give to the wider community. Hat tip to Leon Timmermans for posting on blogs.perl.org about the already merged change. Perhaps part of perl5porter’s policy for experimental changes should include fully fleshed out discussions posted somewhere (manywheres) that have a wide audience beyond core developers. Making the workaday programmer pay attention to the minutiae of daily perl5porters to catch these things isn’t reasonable. However, remember what Mark Jason Dominus said about the Perl 6 RFC process: serious applicants only!

Perl (either current flavor) make us think we could have natural language programming (even if we didn’t) and now new language features try to be linguistically clever even though that’s one of the biggest complaints about my favorite language. The debacle of given and its lexical $_ (removed in v5.24) pushed that a bit too far with implied magic and inadequate testing.

As part of this change given is now just a loop that happens to run exactly one time. Even though the keyword v5.10 chose was not switch (as in C), that’s how people seem to pronounce given . The language people want to use and what Perl actually uses doesn’t match.

I’ve already written that people should use for instead even though p5p fixed the topicalizing bug that led to that advice. With this shift in the language we should get rid of given too. It’s likely at the same spots you’ll already have to modify with this change.

As long as anyone tries to be clever with the natural language words most people are not going to remember which one smart matches. Many other interesting words are already functions in modules ( whereis in Unix::Whereis, where in MooseX::Types and PDL, and with in various modules). The core developers could have long conversations and eventually settle on something that they like, but all those conversations will have to be replayed for each programmer on their first encounter with the new words. We shouldn’t settle for words we like; we should use words our audience will like and understand.

I’m in the camp that thinks the keywords should mostly explain themselves. Why not call the one that smart matches smartmatch and let if with an explicit loop control do the rest? I’m sure I’ll remember which one of these does what:

for( $ARGV[0] ) { if( $_ ) { say "$_ is true"; next } smartmatch( @array ) { say "In array branch" } }

Not only that, this reads better in English. It’s an imperative sentence that tells me exactly what to do. Heck, even a smartif will do. This could be a new feature with a new name that doesn’t disturb the deprecated when , break , and given that would disappear v5.32. That’s a lot more than five months notice of code breaking changes.

If your system automatically upgrades to the latest perl, I suggest that that you separately install the perl you want to use and target that (Item 110. Compile and install your own perls.). I’ve written about Choose the right perl version for you (which I might have to update to recommend not using v5.28) and I’ve noted that Apple recommends that you don’t use their distributed perl. It’s easy to compile a development version so you can test these things on your code base before major changes make it into a maintenance release. I’ve also explained how to tell the different between maintenance and development releases.