An interesting question: why none of the others. Separation in the lvalue context will auto-generate the operand if it is undef.
$ perl -E'@$arr = "b"; say $arr
Arguments are always passed by reference to subs, so they are evaluated in the lvalue context.
$ perl -E'sub f { } f( @$arr ); say $arr // "[undef]"' ARRAY(0x284e9f8)
But the "functions" in perlfunc are actually operators and, as such, they come up with their own syntactic and calling conventions. Perl knows that sort will not change its operands when using the default comparison function, so it does not evaluate them in the lvalue context.
$ perl -E'sort @$arr; say $arr // "[undef]"' [undef]
grep aliases $_ each element passed to it, therefore its arguments can be changed (although this is usually not a good idea), therefore its arguments are evaluated in the context of lvalue.
$ perl -E'@a = "a"; grep { $_ = uc($_) } @a; say @a' A
source share