DVK*_*DVK 39 perl loops map semantics
回答这个问题时,我意识到我不确定Perl是否map可以被视为循环?
一方面,它像循环一样嘎嘎叫/走路(O(n)工作,可以通过等效循环轻松地重写,并且符合常见定义="一系列不断重复的指令").
另一方面,map通常不在Perl的控制结构中列出,其中循环是其中的子集.例如http://en.wikipedia.org/wiki/Perl_control_structures#Loops
所以,我正在寻找的是一个正式的理由来确信一方与另一方.到目前为止,前者(它是一个循环)对我来说听起来更有说服力,但我对我从未在Perl循环列表中提到的"map"这一事实感到困扰.
Car*_*ers 30
map是一种比循环更高层次的概念,借鉴了函数式编程.它并没有说"从头到尾一个接一个地对这些项目中的每个项目调用此函数",它说"在所有这些项目上调用此函数".它可能被实现为一个循环,但这不是重点 - 它也可能是异步实现的 - 它仍然是map.
另外,它本身并不是一个真正的控制结构 - 如果在其实现中使用循环的每个perl函数都列在"循环"下会怎样?仅仅因为使用循环实现某些东西,并不意味着它应该被认为是它自己的循环类型.
pil*_*row 26
不,从我的角度来看,它不是一个循环.
(perl)循环的特征是它们可以被打破(last)或恢复(next,redo). map不能:
map { last } qw(stack overflow); # ERROR! Can't "last" outside a loop block
Run Code Online (Sandbox Code Playgroud)
错误消息表明perl本身不会将评估的块视为循环块.
Eri*_*rom 19
从学术角度来看,可以根据地图的定义来制作两者.如果它总是按顺序迭代,那么foreach可以通过map使两个等价来模拟循环.映射的一些其他定义可能允许执行列表的顺序执行(在线程之间划分工作甚至是单独的计算机).foreach构造可以做同样的事情.
但就Perl 5而言,map总是按顺序执行,使其等效于循环.表达式的内部结构map $_*2, 1, 2, 3导致以下执行顺序操作码显示map内部构建为类似while控件结构:
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
Run Code Online (Sandbox Code Playgroud)
Cha*_*ens 12
该map函数不是Perl中的循环.这可以通过失败可以清楚地看到next,redo和last里面map:
perl -le '@a = map { next if $_ %2; } 1 .. 5; print for @a'
Can't "next" outside a loop block at -e line 1.
Run Code Online (Sandbox Code Playgroud)
要在a中实现所需的效果map,必须返回一个空列表:
perl -le '@a = map { $_ %2 ? () : $_ } 1 .. 5; print for @a'
2
4
Run Code Online (Sandbox Code Playgroud)
我认为转换是类似构造的更好名称map.它将一个列表转换为另一个列表.类似的功能map是List::Util::reduce,但它不是将列表转换为另一个列表,而是将列表转换为标量值.通过使用单词转换,我们可以讨论这两个高阶函数的共同方面.
也就是说,它通过访问列表中的每个成员来工作.这意味着它的行为很像循环,并且取决于您对"循环"的定义是否合格.注意,我的定义意味着此代码中没有循环:
#!/usr/bin/perl
use strict;
use warnings;
my $i = 0;
FOO:
print "hello world!\n";
goto FOO unless ++$i == 5;
Run Code Online (Sandbox Code Playgroud)
Perl实际上在其文档中定义了单词循环:
loop
A construct that performs something repeatedly, like a roller
coaster.
Run Code Online (Sandbox Code Playgroud)
根据这个定义,它map是一个循环,因为它反复预先形成它的块; 但是,它还定义了"循环控制语句"和"循环标签":
loop control statement
Any statement within the body of a loop that can make a loop
prematurely stop looping or skip an "iteration". Generally you
shouldn't try this on roller coasters.
loop label
A kind of key or name attached to a loop (or roller coaster) so
that loop control statements can talk about which loop they want to
control.
Run Code Online (Sandbox Code Playgroud)
我认为调用map循环是不精确的,因为next它的亲属被定义为循环控制语句而它们无法控制map.
这只是玩文字.描述map为类似循环是一种非常有效的方式来介绍某人.甚至文档也map使用foreach循环作为其示例的一部分:
%hash = map { get_a_key_for($_) => $_ } @array;
is just a funny way to write
%hash = ();
foreach (@array) {
$hash{get_a_key_for($_)} = $_;
}
Run Code Online (Sandbox Code Playgroud)
这一切都取决于上下文.当你试图让他或她理解这个概念时,将某人的乘法描述为重复加法很有用,但你不希望他或她继续这样想.你会希望他或她学习乘法规则,而不是总是转换回加法规则.
FMc*_*FMc 11
你的问题转向了分类问题.至少在一种解释下,询问是否map循环就像询问是否map是"循环"的子集.以这种方式框架,我认为答案是否定的.虽然map和Loop有许多共同点,但是有很多不同之处.
next和last,而map不是.map是返回值; 有循环,而不是.我们在现实世界中一直遇到这样的关系 - 彼此有很多共同点的东西,但它们都不是另一个的完美子集.
-----------------------------------------
|Things that iterate? |
| |
| ------------------ |
| |map() | |
| | | |
| | --------|---------- |
| | | | | |
| | | | | |
| ------------------ | |
| | | |
| | Loop| |
| ------------------ |
| |
-----------------------------------------
Run Code Online (Sandbox Code Playgroud)