One of Larry's purported factors in the design of Camelia (and by extension, Perl 6) was to appeal to 7 year old girls (and by extension, people new to programming in general).
In addition, another design principle of Perl6 was to make it "less Unix centric". Whereas Perl had s///
and tr///
, Perl 6 retains these but adds subst
and trans
, which is friendlier to new programmers, and self-documenting to some degree.
It seems odd, then, that we still have the grep
operator named so. Even in Perl, grep - as in globally search a regular expression and print - bears little resemblance to what it actually does. It's more of a filter, filtering elements out that do not evaluate True to a given expression.
What then would be it's alternative friendly name? Taking into account these design principles...
- Context Sensitive: A term or symbol might do different things in different context
- Maximum reuse: Syntax and concepts are reused wherever possible to minimize the stuff you have to remember
I propose where
.
This make a lot of sense when you consider how similar a grep
expression is to the context that where
is currently used (in defining a subset).
Here's a demonstration to highlight the similarities
> (^10).grep(* %% 2)
(0 2 4 6 8)
> subset Even of Int where * %% 2;
> (^10).grep(Even)
(0 2 4 6 8)
> my Int $even where * %% 2
> (^10).grep($even)
(0 2 4 6 8)
>
Here it becomes very clear. The * %% 2
expression appears directly after both grep
and where
. Contextually they are similar.
We can also give a subset to grep and it does as expected. Conceptually they are almost identical.
Here's some hypothetical code that uses a newly named where
method that aliases grep
.
my @even = @numbers.where(* %% 2)
my @prod = @servers.where(*.status eq 'Production')
my @matches = @data.where(/pattern/)
Please note, I'm not advocating for the removal of grep
at all... I'm proposing an additional nickname for it. One more relevant, logical, and friendly to new (all?) programmers, including 7 year old girls.
This is now a (kind of) fully fledged module in the ecosystem.
https://github.com/0racle/p6-wig
Some prior art on the use of the word where
to filter a list
Powershell
$evens = 0..10 | Where { $_ % 2 -eq 0 }
C#
int[] evens = array.Where(i => (i % 2) == 0).ToArray();
SQL
SELECT v INTO #evens FROM #nos WHERE v % 2 = 0
Haskell
import Data.Array
ary = listArray (1,10) [1..10]
evens = listArray (1,n) l where
n = length l
l = [x | x <- elems ary, even x]
Dart
numbers.where((i) => i.isEven);
Interesting to note, when looking at Filter - Rosetta Code, the only examples that have a grep
operator are UNIX shell, Perl, and Sidef ( a language implemented in perl5 ).
filter
has become a standard of sorts, but it is a misnomer because one does not know if the boolean should apply to what you're keeping or what you're filtering out.my @nums = (^10).filter(* %% 2)
Am I keeping even numbers or rejecting them? This is the natural English thought, to me at least.
my @nums = (^10).grep(* %% 2)
grep
has the same issue asfilter
for me. Compounded by the fact that it isn't even a recognizable English word.For this reason, I like
keep
andreject
.my @nums = (^10).keep(* %% 2)
There is no doubt that
@nums
contain even numbers.my @nums = (^10).reject(* %% 2)
Again, there is no doubt that
@nums
contain odd numbers.Having said that, Perl6's gather/take functionality is fairly similar and quite clear. It's just a very new system to a lot of people.
my @nums = gather for ^10 { take if $_ %% 2 }