DEV Community


Discussion on: We Don't Need No Stinking map() or filter()

augiedb profile image
Augie De Blieck Jr.

I learned this one time when digging into the source code for the Elixir language. The Enum module there has map(), filter(), and reduce() -- but both map and filter are defined as reduce functions.

You can see it over here:

I wouldn't be surprised if every other language does the same, now that I think about it.

So, yeah, write the code that reads the best for the sake of future coders, and the language will take care of simplifying the rest for you. ;-)

b2gills profile image
Brad Gilbert

Perl 6 doesn't do it this way, because it can't do that easily.

If you tried to implement map with reduce it would hang before producing a single value when called on an infinite sequence.

my @a = (0..Inf).map( *² ); # infinite sequence of all squared values

.say() for @a.head(20); # prints first twenty squares
# sequence of only twenty squared values
my @b = (0..^20).reduce: { @_.head(*-1).Slip, @_.tail² }

.say() for @b; # prints the same twenty squares
# doesn't stop until it is killed or runs out of resources
my @c = (0..Inf).reduce: { @_.head(*-1).Slip, @_.tail² }

.say() for @c.head(20); # never gets to this line of code

You could maybe find a way to pass upwards the number of values to produce:

my @d = (0..Inf).reduce: {
  last if @_ > 20; # stop early

  @_.head(*-1).Slip, @_.tail²

.say() for @d;

The thing is that iteration is done using an object based protocol, so map and grep just return an object with the appropriate functionality.
(Most of the time this is abstracted away so you don't need to know how it works.)

Perl 6 is a functional language while also being a procedural language.
So it can't always make the same sort of guesses about what you mean that pure functional languages can make.

jdsteinhauser profile image
Jason Steinhauser Author

I'm just now digging into Elixir/OTP, and I'm actually kind of amused to see that 😀 thanks for pointing that out!