Perl的哪些特性使其成为函数式编程语言?

Perl的哪些特性使其成为函数式编程语言?,perl,functional-programming,Perl,Functional Programming,灵感来自: 我发现: 它让我对Perl是一种函数式编程语言的断言感到好奇。现在,我明白了函数式编程是一种技术(很像面向对象) 但是,我发现了以下列表: 一类函数 高阶函数 词汇闭包 模式匹配 单一任务 惰性评估 垃圾收集 类型推断 尾部调用优化 列表理解 一元效应 现在我非常熟悉其中一些: 例如,垃圾收集就是Perl引用计数,并在不再需要时释放内存 词法闭包甚至是FAQ的一部分:-这里可能有一篇更好的文章: 但是我开始对其中一些有点模糊,比如列表理解,我认为这是指map/grep(List:

灵感来自:

我发现:

它让我对Perl是一种函数式编程语言的断言感到好奇。现在,我明白了函数式编程是一种技术(很像面向对象)

但是,我发现了以下列表:

  • 一类函数
  • 高阶函数
  • 词汇闭包
  • 模式匹配
  • 单一任务
  • 惰性评估
  • 垃圾收集
  • 类型推断
  • 尾部调用优化
  • 列表理解
  • 一元效应
现在我非常熟悉其中一些:

例如,垃圾收集就是Perl引用计数,并在不再需要时释放内存

词法闭包甚至是FAQ的一部分:-这里可能有一篇更好的文章:

但是我开始对其中一些有点模糊,比如列表理解,我认为这是指
map
/
grep
List::Util
reduce
?)

有人能帮我填空吗?上面哪一项Perl可以轻松完成(有没有简单的例子)以及有没有失败的例子

相关的有用信息:

在计算机科学中,如果一种编程语言将函数视为一等公民,那么它就被认为具有一等函数。具体来说,这意味着该语言支持将函数作为参数传递给其他函数,将它们作为其他函数的值返回,并将它们分配给变量或将它们存储在数据结构中

因此,在Perl中:

my $print_something = sub { print "Something\n" };

sub do_something {
    my ($function) = @_;
    $function->();
}

do_something($print_something);
判决:本地支持 在数学和计算机科学中,高阶函数(也称为函数形式、函数或函子)是至少执行以下操作之一的函数:

  • 将一个或多个函数作为输入

  • 输出一个函数

关于:

在Perl术语中,我们通常将它们称为回调、工厂和返回代码引用(通常是闭包)的函数

判决:本地支持 在perl常见问题解答中,我们有以下问题:

闭包是一个计算机科学术语,具有精确但难以解释的含义。通常,闭包在Perl中作为匿名子例程实现,并在其自身范围外持久引用词法变量。这些词汇神奇地引用了定义子例程(深度绑定)时周围的变量

闭包最常用于编程语言中,在编程语言中,函数的返回值可以是函数本身,就像在Perl中一样

这一点在文章中可能解释得更清楚一些:

判决:本地支持 在纯函数式语言和本页的上下文中,模式匹配是一种分派机制:选择要调用的函数的正确变体。受到标准数学符号的启发

分派表是最接近的近似值-本质上是匿名子项或代码引用的哈希

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);
        }
}