相关的有用内容:
Perl僧侣对函数式编程的抨击
高阶Perl
C2.com函数式编程定义
在计算机科学中,如果一种编程语言将函数视为一等公民,则称其具有一等函数。具体而言,这意味着该语言支持将函数作为参数传递给其他函数,从其他函数返回它们作为值,并将它们分配给变量或存储在数据结构中。
所以在Perl中:
my $print_something = sub { print "Something\n" };
sub do_something {
my ($function) = @_;
$function->();
}
do_something($print_something);
结论:本地支持
在数学和计算机科学中,高阶函数(也称为函数形式、函数或函数子)是执行以下至少一项操作的函数:
参考这篇perlmonks文章:
在Perl术语中,我们经常将它们称为回调、工厂以及返回代码引用的函数(通常是闭包)。
结论:本地支持
在Perl FAQ中,我们有关于什么是闭包?
的问题:
闭包是一个具有精确但难以解释含义的计算机科学术语。通常,在Perl中,闭包被实现为具有对其自身范围外的词法变量的持久引用的匿名子例程。这些词法变量神奇地指向在定义子例程时周围存在的变量(深度绑定)。闭包最常用于编程语言中,其中函数的返回值可以是函数本身,就像在Perl中一样。
在文章
Achieving Closure中可能会更清楚地解释这一点。
sub make_hello_printer {
my $message = "Hello, world!";
return sub { print $message; }
}
my $print_hello = make_hello_printer();
$print_hello->()
结论:本地支持
在纯函数语言和本页面的上下文中,模式匹配是一种分派机制:选择正确的函数变体进行调用。受标准数学符号启发。
分派表是最接近的近似值 - 本质上是匿名子例程或代码引用的哈希。
use strict;
use warnings;
sub do_it {
print join( ":", @_ );
}
my $dispatch = {
'onething' => sub { print @_; },
'another_thing' => \&do_it,
};
$dispatch->{'onething'}->("fish");
因为它只是一个哈希,你也可以添加代码引用和匿名子例程。(注意-与面向对象编程有些相似)
结论:解决方法
在纯函数式语言中,任何更改现有值的分配(例如 x := x + 1)都是不允许的。在函数式编程中,分配被弃用,而使用单一分配,也称为初始化。单一赋值是名称绑定的一个示例,并且与本文中描述的分配不同之处在于它只能在变量创建时执行一次;不允许后续重新分配。
我不确定perl是否真正做到了这一点。最接近的近似可能是引用/匿名子例程或者常数。
结论:不支持
等到最后一刻才评估表达式,特别是为了优化可能不使用表达式值的算法。
Perl 5中惰性求值技术的示例
再次回到
Higher Order Perl(我与这本书没有关联,只是它似乎是该主题的关键文本之一)。
核心概念在于 - 在perl中创建一个'链接列表'(使用面向对象技术),但在您的'结束标记'嵌入代码引用,以评估是否到达那里。
结论:解决方法
垃圾回收 “GarbageCollection(GC),也称为自动内存管理,是堆内存的自动回收。”
Perl通过引用计数来实现这一点,当不再引用时释放资源。请注意,在函数式编程中可能会遇到某些问题,特别是循环引用,这在
perldoc perlref
中有所涉及。
结论:本地支持
类型推断
类型推断是分析程序以推断某些或所有表达式的类型,通常在编译时进行。
Perl隐式地将值转换为需要的格式。通常情况下,这足够好,您不需要对其进行干预。偶尔需要通过显式数字或字符串操作来“强制”该过程。经典的方法是添加0或连接空字符串。
你可以通过使用
dualvars
来重载标量以执行不同的操作。
结论:原生支持
尾调用优化(或尾调用合并或尾调用消除)是尾递归的一般化:如果一个函数在返回之前做的最后一件事是调用另一个函数,那么它应该安全地直接跳转到第二个函数的开头,让它重复使用第一个函数的堆栈帧(环境)。
为什么Perl如此害怕“深递归”?
它会工作,但如果递归深度>100,则会发出警告。您可以通过添加以下内容来禁用此功能:
no warnings 'recursion';
但是,显然你需要对递归深度和内存占用略加谨慎。
据我所知,没有任何特定的优化方法,如果你想以高效的方式完成这样的任务,可能需要将递归展开并进行迭代。
Perl支持尾调用。可以查看goto ⊂符号,或者查看由Sub::Call::Tail
提供的更简洁的语法。
结论:本地支持
列表推导是许多现代函数式编程语言的一个特性。在一定的规则下,它们为生成列表中的元素提供了简洁的表示法。列表推导是concat、map和filter函数的语法糖组合。
Perl有map
、grep
、reduce
。
它还能处理范围和重复的扩展:
my @letters = ( "a" .. "z" );
所以你可以:
my %letters = map { $_ => 1 } ( "A" .. "z" );
结论:本地支持(List::Utils
是核心模块)
...不行,我还是对这些有困难。它要么比我理解的简单得多,要么比我理解的复杂得多。
如果有人有更多的东西,请加入或编辑此帖子或......什么的。我对涉及的一些概念仍然很模糊,所以这篇文章更像是一个起点。