While answering this question, I came to realize that I was not sure whether Perl\'s map
can be considered a loop or not?
On one hand, it quacks/walks l
map
itself is generally implemented using a loop of some sort (to loop over iterators, typically), but since it is a higher-level structure, it's often not included in lists of lower-level control structures.
From an academic standpoint, a case can be made for both depending on how map is defined. If it always iterates in order, then a foreach
loop could be emulated by map
making the two equivalent. Some other definitions of map may allow out of order execution of the list for performance (dividing the work amongst threads or even separate computers). The same could be done with the foreach
construct.
But as far as Perl 5 is concerned, map
is always executed in order, making it equivalent to a loop. The internal structure of the expression map $_*2, 1, 2, 3
results in the following execution order opcodes which show that map
is built internally as a while
-like control structure:
OP enter
COP nextstate
OP pushmark
SVOP const IV 1
SVOP const IV 2
SVOP const IV 3
LISTOP mapstart
LOGOP (0x2f96150) mapwhile <-- while still has items, shift one off into $_
PADOP gvsv GV *_
SVOP const IV 2 loop body
BINOP multiply
goto LOGOP (0x2f96150) <-- jump back to the top of the loop
LISTOP leave
map is a higher-order function. The same applies to grep. Book Higher-Order Perl explains the idea in full details.
It's sad to see that discussion moved towards implementation details, not the concept.
Your question turns on the issue of classification. At least under one interpretation, asking whether map
is a loop is like asking whether map
is a subset of "Loop". Framed in this way, I think the answer is no. Although map
and Loop have many things in common, there are important differences.
next
and last
, while map
is not.map
is its return value; with loops, not so much.We encounter relationships like this all the time in the real world -- things that have much in common with each other, but with neither being a perfect subset of the other.
-----------------------------------------
|Things that iterate? |
| |
| ------------------ |
| |map() | |
| | | |
| | --------|---------- |
| | | | | |
| | | | | |
| ------------------ | |
| | | |
| | Loop| |
| ------------------ |
| |
-----------------------------------------
I think map fits the definition of a Functor.
Here is a definition of map as a recurrence:
sub _map (&@) {
my $f = shift;
return unless @_;
return $f->( local $_ = shift @_ ),
_map( $f, @_ );
}
my @squares = _map { $_ ** 2 } 1..100;