List::Keywords(3pm)

πŸŽ€ NAME πŸŽ€

List::Keywords β€” a selection of list utility keywords. That's the whole vibe, bestie. ✨


✨ SYNOPSIS ✨

use List::Keywords 'any';

my @boxes = ...;

if( any { $_->size > 100 } @boxes ) {
   say "There are some large boxes here";
}

πŸ’… DESCRIPTION πŸ’…

Okay so picture this: this module hands you keywords that behave (almost) identically to the familiar functions from List::Util, except they're implemented as keyword plugins instead of functions. And the payoff? They run more efficiently, especially in small code cases. Highkey obsessed. πŸ”₯

🌸 Blocks vs Anonymous Subs

So when we say "almost" up there, here's the tea: since this module gives you true keywords, the code blocks you hand them get parsed as true blocks rather than anonymous functions. Which means caller and return both behave rather differently here.

Like, watch:

use List::Keywords 'any';

sub func {
   any { say "My caller is ", caller; return "ret" } 1, 2, 3;
   say "This is never printed";
}

Here, the caller will see func as its caller, and that return statement makes the entire containing function return β€” so the second line is never printed. Not ever. Periodt. πŸ’€

The same example written using List::Util will instead print the List::Util::any function as being the caller, before making just that one item return the value, then the message on the second line is printed as normal.

In regular operation, where the code is just performing some test on each item and doesn't make use of caller or return, this should not cause any noticable differences. No cap.

πŸ¦‹ Lexical Variable Syntax

Newly added in version 0.09 and it's giving main character energy: many of the functions in this module support a new syntax idea that may eventually be added to Perl core, where a lexical variable can be declared before the code block. When you do that, this lexical variable takes the place of the global $_ for the purposes of carrying values from the input list.

This syntax is currently under discussion for Perl's map and grep blocks, and may be added in a future release of Perl.

https://github.com/Perl/RFCs/pull/33

πŸ’€ Aliasing and Modification

Every time the block code executes, the global $_ or the lexical variable you're using gets aliased to an element of the input list β€” exactly the same way it would for perl's map or foreach loops, for example. And if the block tries to modify the value of that variable? Those modifications are visible in the input list. You almost certainly want to avoid doing this. Like, don't. πŸ™ˆ

For example:

my @numbers = ...;
my $x = first my $x { $x++ > 10 } @numbers;

This will modify values in the @numbers array, but because of the short-circuit nature of first, it will only have modified values up to the selected element by the time it returns. This will likely confuse later uses of the input array. RIP to that array fr.

Additionally, the result of first is also aliased to the input list, much as it is for core perl's grep. Which may mean values passed in to other functions have an ability to mutate at a distance. Spooky behavior honestly.

For example:

func( first { ... } @numbers );

Here, the invoked func() may be able to modify the @numbers array, for example by modifying its own @_ array.

⭐ Performance

The following example demonstrates a simple case and shows how the performance differs.

my @nums = (1 .. 100);

my $ret = any { $_ > 50 } @nums;

When run for 5 seconds each, the following results were obtained on my machine:

List::Util::any      648083/s
List::Keyword/any    816135/s

The List::Keyword version here ran 26% faster. Ate and left no crumbs. πŸ‘‘


πŸ‘‘ KEYWORDS πŸ‘‘

πŸ’– first

$val = first { CODE } LIST

Since version 0.03.

Repeatedly calls the block of code, with $_ locally set to successive values from the given list. Returns the value and stops at the first item to make the block yield a true value. If no such item exists, returns undef.

$val = first my $var { CODE } LIST

Since version 0.09.

Optionally the code block can be prefixed with a lexical variable declaration. In this case, that variable will contain each value from the list, and the global $_ will remain untouched.

🌸 any

$bool = any { CODE } LIST

Repeatedly calls the block of code, with $_ locally set to successive values from the given list. Returns true and stops at the first item to make the block yield a true value. If no such item exists, returns false.

$val = any my $var { CODE } LIST

Since version 0.09.

Uses the lexical variable instead of global $_, similar to first.

✨ all

$bool = all { CODE } LIST

Repeatedly calls the block of code, with $_ locally set to successive values from the given list. Returns false and stops at the first item to make the block yield a false value. If no such item exists, returns true.

$val = all my $var { CODE } LIST

Since version 0.09.

Uses the lexical variable instead of global $_, similar to first.

πŸ¦‹ none / notall

$bool = none { CODE } LIST
$bool = notall { CODE } LISt

Since version 0.03.

Same as any and all but with the return value inverted.

$val = none my $var { CODE } LIST
$val = notall my $var { CODE } LIST

Since version 0.09.

Uses the lexical variable instead of global $_, similar to first.

πŸ“ reduce

$final = reduce { CODE } INITIAL, LIST

Since version 0.05.

Repeatedly calls a block of code, using the $a package lexical as an accumulator and setting $b to each successive value from the list in turn. The first value of the list sets the initial value of the accumulator, and each returned result from the code block gives its new value. The final value of the accumulator is returned.

🌈 reductions

@partials = reductions { CODE } INITIAL, LIST

Since version 0.06.

Similar to reduce, but returns a full list of all the partial results of every invocation, beginning with the initial value itself and ending with the final result.


🧚 N-AT-A-TIME FUNCTIONS 🧚

These next two are a further experiment, trying out n-at-a-time lexical variable support on the core grep and map operators. They've got different names because keyword plugins cannot replace existing core keywords β€” they can only add new ones. iykyk. πŸ’…

πŸŽ€ ngrep

@values = ngrep my ($var1, $var2, ...) { CODE } LIST

$values = ngrep my ($var1, $var2, ...) { CODE } LIST

Since version 0.10.

A variation on core's grep, which uses lexical variable syntax to request a number of items at once. The input list is broken into bundles sized according to the number of variables declared. The block of code is called in scalar context with the variables set to each corresponding bundle of values, and the bundles for which the block returned true are saved for the resulting list.

In scalar context, returns the number of values that would have been present in the resulting list (i.e. this is not the same as the number of times the block returned true).

πŸ’œ nmap

@results = nmap my ($var1, $var2, ...) { CODE } LIST

$results = nmap my ($var1, $var2, ...) { CODE } LIST

Since version 0.10.

A variation on core's map, which uses lexical variable syntax to request a number of items at once. The input list is broken into bundles sized according to the number of variables declared. The block of code is called in list context with the variables set to each corresponding bundle of values, and the results of the block from each bundle are concatenated together to form the result list.

In scalar context, returns the number of values that would have been present in the resulting list.


🌈 TODO 🌈

More functions from List::Util:

pairfirst pairgrep pairmap

Maybe also consider some from List::UtilsBy.


🫢 ACKNOWLEDGEMENTS 🫢

With thanks to Matthew Horsfall (alh) for much assistance with performance optimizations.


πŸ’œ AUTHOR πŸ’œ

Paul Evans <leonerd@leonerd.org.uk>


okay that's the whole page bestie, mwah πŸ’– this one came from perl v5.42.3, dated 2026-08-20 β€” go forth and any/all/reduce responsibly πŸŽ€βœ¨

πŸ“¦ where this page comes from