Perl 5.41.7 adds short-circuit list predicates and scalar field writers
Experimental any/all operators avoid evaluating unnecessary predicates, while native classes gain generated setters with explicit return semantics.
A program asking whether a list contains a matching value does not need every matching value. Perl 5.41.7 adds experimental any and all operators that express that distinction. They return a boolean and can stop testing elements once the result is known. The same snapshot extends experimental classes with generated writers for scalar fields.
Max Maischein released the snapshot on 20 December, according to the release history. The release notes explain that the predicates draw inspiration from the same-named functions in List::Util. Implementing them as core operators changes how the testing block runs, as well as making the spelling available directly through features.
I find the predicate addition relevant to the short text-processing programs for which I still choose Perl. A condition that asks about existence should read as that question. It should not imply that the program needs to collect or count every match when the decision is already available.
Any stops after a successful predicate
The function reference in the release says any sets $_ locally to each element and evaluates its block. It returns true when at least one element makes the block true. Once that happens, the operator does not consider later elements.
use v5.40;
use feature 'any';
my @labels = ('', 'ready', '');
if (any { length $_ } @labels) {
say "At least one label is non-empty";
}
This example targets the development interpreter that supplies the feature. The use v5.40 declaration does not make any available in an actual 5.40 interpreter. The explicit feature declaration requests the experimental operator introduced by this snapshot, and its use can emit the corresponding experimental warning.
The documentation compares this conditional use with grep, while pointing out the short-circuit difference. That difference is observable if the predicate changes state or performs work. Code cannot assume that a block will run once for every input element when the operator's purpose is to stop after determining the answer.
All stops after a failed predicate
The release notes describe all as testing whether every element makes the block true. A failed predicate determines a false result immediately. There is no need to test the remainder to establish that the entire list does not satisfy the condition.
The useful symmetry is in the decision being made. An existence test needs one success, while a universal test needs one failure to disprove it. Neither operator is a suitable way to promise side effects on every element. That is a consequence of their documented control flow, independent of the convenience of the syntax.
The notes also say that the core implementation avoids an additional subroutine call frame for invoking the testing block. This distinguishes the operators from the library functions that inspired them. The claim is about the implementation mechanism. It does not supply a numeric speedup for an arbitrary workload.
Code choosing the new operators is also choosing an experimental dependency. Their appearance in a development snapshot is an opportunity to inspect the semantics while they are under development. It should not be described as a stable addition to the June interpreter merely because the example starts with a 5.40 version declaration.
A writer assigns and returns the instance
Native classes gain the :writer field attribute. The class reference specifies that the generated method takes exactly one argument, assigns it to the field and returns the invocant object. The default name prefixes the field name with set_ after removing its sigil.
use v5.40;
use feature 'class';
class Point {
field $x :param :reader :writer;
}
my $point = Point->new(x => 20);
$point->set_x(60);
say $point->x;
The example deliberately uses the experimental class system. Its generated writer is equivalent to a method that assigns the incoming scalar and returns $self. That return rule is part of the interface. A caller receives the instance, which differs from a setter designed to return the old value or the new field value.
An attribute argument can select a custom method name. The reference gives the form :writer(write_x), making naming explicit without requiring a handwritten assignment method. Generation handles the straightforward case, while custom methods remain necessary when mutation requires other logic.
Scalar fields define the current boundary
The writer attribute currently applies only to scalar fields. Applying it to an array or hash field produces a fatal compile-time exception. The documentation mentions possible future relaxation, but those additional writers are not part of the snapshot's delivered behaviour.
That restriction is useful to retain in an explanation because the reader attribute already supports non-scalar fields. The two attributes do not have identical applicability merely because they are related accessors. Assigning one scalar argument has a defined meaning that does not automatically specify how a list-shaped writer should behave.
I prefer generated accessors when their semantics are as explicit as these. They save repetitive code, but the return value and accepted field kinds remain visible in the reference. For a class with more complicated mutation rules, an ordinary method can state those rules directly instead of relying on an accessor attribute to imply them.
The predicates and writers address different repetitive patterns. A predicate asks the interpreter to stop a search when its boolean answer is known. A writer asks it to generate a specified assignment method. Both additions remain attached to their experimental features, with enough concrete behaviour documented for module authors to evaluate them in the development series.