Perl的哪些特性使其成为函数式编程语言?
灵感来自: 我发现: 它让我对Perl是一种函数式编程语言的断言感到好奇。现在,我明白了函数式编程是一种技术(很像面向对象) 但是,我发现了以下列表:Perl的哪些特性使其成为函数式编程语言?,perl,functional-programming,Perl,Functional Programming,灵感来自: 我发现: 它让我对Perl是一种函数式编程语言的断言感到好奇。现在,我明白了函数式编程是一种技术(很像面向对象) 但是,我发现了以下列表: 一类函数 高阶函数 词汇闭包 模式匹配 单一任务 惰性评估 垃圾收集 类型推断 尾部调用优化 列表理解 一元效应 现在我非常熟悉其中一些: 例如,垃圾收集就是Perl引用计数,并在不再需要时释放内存 词法闭包甚至是FAQ的一部分:-这里可能有一篇更好的文章: 但是我开始对其中一些有点模糊,比如列表理解,我认为这是指map/grep(List:
- 一类函数
- 高阶函数
- 词汇闭包
- 模式匹配
- 单一任务
- 惰性评估
- 垃圾收集
- 类型推断
- 尾部调用优化
- 列表理解
- 一元效应
map
/grep
(List::Util
和reduce
?)
有人能帮我填空吗?上面哪一项Perl可以轻松完成(有没有简单的例子)以及有没有失败的例子 相关的有用信息:
在计算机科学中,如果一种编程语言将函数视为一等公民,那么它就被认为具有一等函数。具体来说,这意味着该语言支持将函数作为参数传递给其他函数,将它们作为其他函数的值返回,并将它们分配给变量或将它们存储在数据结构中
因此,在Perl中:
my $print_something = sub { print "Something\n" };
sub do_something {
my ($function) = @_;
$function->();
}
do_something($print_something);
判决:本地支持
在数学和计算机科学中,高阶函数(也称为函数形式、函数或函子)是至少执行以下操作之一的函数:
- 将一个或多个函数作为输入
- 输出一个函数
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是否真的能做到这一点。最接近的近似值可能是引用/匿名sub,或者可能是常量
判决:不支持
等待到最后一个可能的时刻对表达式求值,尤其是为了优化可能不使用表达式值的算法
再一次,回到(老实说,我与这本书无关——它似乎只是这个主题的关键文本之一)
这里的核心概念似乎是——在perl中创建一个“链表”(使用面向对象的技术),但在“结束标记”处嵌入一个代码引用,如果您做得够多,就会进行计算
结论:解决办法
垃圾收集(GC),也称为自动内存管理,是堆内存的自动回收
Perl通过引用计数来实现这一点,并在不再引用时释放它们。请注意,这可能会对函数式编程时(可能!)更可能遇到的某些事情产生影响
特别是-本手册中包含的循环参考
结论:本地支持
类型推断是对程序的分析,通常在编译时推断某些或所有表达式的类型
Perl会根据需要隐式地来回转换值。通常情况下,这样做效果很好,您不需要去处理它。有时,您需要通过执行显式数字或字符串操作来“强制”进程。通常,这是通过添加0或连接空字符串来实现的
通过使用,可以重载标量以在中执行不同的操作
结论:本地支持
尾部调用优化(或尾部调用合并或尾部调用消除)是尾部递归的一种推广:如果例程在返回之前做的最后一件事是调用另一个例程,而不是在跳转和添加堆栈帧之后立即执行弹出堆栈帧并返回调用方,简单地跳到第二个例程的开头应该是安全的,让它重新使用第一个例程的堆栈帧(环境)
它会起作用的,但是它
use strict;
use warnings;
sub do_it {
print join( ":", @_ );
}
my $dispatch = {
'onething' => sub { print @_; },
'another_thing' => \&do_it,
};
$dispatch->{'onething'}->("fish");
no warnings 'recursion';
my @letters = ( "a" .. "z" );
my %letters = map { $_ => 1 } ( "A" .. "z" );
sub check_config {
my ( $class, $obj ) = @_;
my $separator = ' > ';
# Build message from class namespace.
my $message = join $separator, ( split '::', $class );
# Use provided object $obj or
# create an instance of class with defaults, provided by configuration.
my $object = $obj || $class->new;
# Return a Function.
return sub {
my $attribute = shift;
# Compare attribute with configuration,
# just to ensure it is read from there.
is $object->config->{$attribute},
# Call attribute accessor so it is read from config,
# and validated by type checking.
$object->$attribute,
# Build message with attribute.
join $separator, ( $message, $attribute );
}
}
sub check_config_attributes {
my ( $class, $obj ) = @_;
return sub {
my $attributes = shift;
check_config( $class, $obj )->($_) for (@$attributes);
}
}