简体   繁体   English

Perl的哪些功能使它成为一种函数式编程语言?

[英]Which features of Perl make it a functional programming language?

Inspired a little by: https://stackoverflow.com/questions/30977789/why-is-c-not-a-functional-programming-language 灵感来自: https//stackoverflow.com/questions/30977789/why-is-c-not-a-functional-programming-language

I found: Higher Order Perl 我发现: 高阶Perl

It made me wonder about the assertion that Perl is a functional programming language. 这让我对Perl是一种函数式编程语言的断言感到疑惑。 Now, I appreciate that functional programming is a technique (much like object oriented). 现在,我欣赏函数式编程是一种技术(很像面向对象)。

However I've found a list of what makes a functional programming language : 但是我找到了一个函数式编程语言的列表:

  • First Class functions 头等舱功能
  • Higher Order Functions 高阶函数
  • Lexical Closures 词汇封闭
  • Pattern Matching 模式匹配
  • Single Assignment 单一作业
  • Lazy Evaluation 懒惰的评价
  • Garbage Collection 垃圾收集
  • Type Inference 类型推断
  • Tail Call Optimization 尾调用优化
  • List Comprehensions 列表理解
  • Monadic effects 单子效应

Now some of these I'm quite familiar with: 现在其中一些我很熟悉:

Garbage collection, for example, is Perl reference counting and releasing memory when no longer required. 例如,垃圾收集是Perl引用计数,并在不再需要时释放内存。

Lexical closures are even part of the FAQ: What is a closure? 词汇封闭甚至是FAQ的一部分: 什么是封闭? - there's probably a better article here: http://www.perl.com/pub/2002/05/29/closure.html - 这里可能有更好的文章: http//www.perl.com/pub/2002/05/29/closure.html

But I start to get a bit fuzzy on some of these - List Comprehensions, for example - I think that's referring to map / grep ( List::Util and reduce ?) 但是我开始对其中的一些感到有点模糊 - 例如List Insrehensions - 我认为这是指map / grepList::Utilreduce ?)

I anyone able to help me fill in the blanks here? 我有人能帮我填补这里的空白吗? Which of the above can Perl do easily (and is there an easy example) and are there examples where it falls down? Perl可以轻松完成以上哪些操作(并且有一个简单的例子)并且有哪些例子可以解决它?

Useful things that are relevant: 有用的东西:

Perl monks rant about functional programming Perl僧侣们对功能编程大肆宣扬

Higher Order Perl 高阶Perl

C2.com functional programming definitions C2.com函数式编程定义

First Class functions 头等舱功能

In computer science, a programming language is said to have first-class functions if it treats functions as first-class citizens. 在计算机科学中,如果将编程语言视为一等公民,则称其具有一流的功能。 Specifically, this means the language supports passing functions as arguments to other functions, returning them as the values from other functions, and assigning them to variables or storing them in data structures. 具体来说,这意味着该语言支持将函数作为参数传递给其他函数,将它们作为其他函数的值返回,并将它们分配给变量或将它们存储在数据结构中。

So in Perl: 在Perl中:

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

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

do_something($print_something);

Verdict: Natively supported 判决:本机支持

Higher Order Functions 高阶函数

In mathematics and computer science, a higher-order function (also functional form, functional or functor) is a function that does at least one of the following: 在数学和计算机科学中,高阶函数(也是函数形式,函数或函子)是至少执行以下任一操作的函数:

  • takes one or more functions as an input 将一个或多个函数作为输入

  • outputs a function 输出一个功能

With reference to this post on perlmonks : 关于perlmonks的这篇文章

In Perl terminology, we often refer to them as callbacks, factories, and functions that return code refs (usually closures). 在Perl术语中,我们经常将它们称为回调,工厂和返回代码引用(通常是闭包)的函数。

Verdict: Natively supported 判决:本机支持

Lexical Closures 词汇封闭

Within the perl FAQ we have questions regarding What is a closure? 在perl FAQ中我们有关于What is a closure? :

Closure is a computer science term with a precise but hard-to-explain meaning. 闭包是一个计算机科学术语,具有精确但难以解释的含义。 Usually, closures are implemented in Perl as anonymous subroutines with lasting references to lexical variables outside their own scopes. 通常,闭包在Perl中作为匿名子例程实现,并且在其自己的作用域之外具有对词法变量的持久引用。 These lexicals magically refer to the variables that were around when the subroutine was defined (deep binding). 这些词汇神奇地指的是定义子程序时的变量(深度绑定)。

Closures are most often used in programming languages where you can have the return value of a function be itself a function, as you can in Perl. 闭包最常用于编程语言中,您可以将函数的返回值本身作为函数,就像在Perl中一样。

This is explained perhaps a little more clearly in the article: Achieving Closure 在文章中可能会更清楚地解释这一点: 实现关闭

sub make_hello_printer {
    my $message = "Hello, world!";
    return sub { print $message; }
}

my $print_hello = make_hello_printer();
$print_hello->()

Verdict: Natively supported 判决:本机支持

Pattern Matching 模式匹配

In the context of pure functional languages and of this page, Pattern Matching is a dispatch mechanism: choosing which variant of a function is the correct one to call. 在纯函数语言和此页面的上下文中,模式匹配是一种调度机制:选择函数的哪个变体是正确的调用。 Inspired by standard mathematical notations. 受标准数学符号的启发。

Dispatch tables are the closest approximation - essentially a hash of either anonymous subs or code refs. 调度表是最接近的近似值 - 本质上是匿名子代码或代码引用的散列。

use strict;
use warnings;

sub do_it {
    print join( ":", @_ );
}
my $dispatch = {
    'onething'      => sub { print @_; },
    'another_thing' => \&do_it,
};

$dispatch->{'onething'}->("fish");

Because it's just a hash, you can add code references and anonymous subroutines too. 因为它just一个哈希,所以你也可以添加代码引用和匿名子程序。 (Note - not entirely dissimilar to Object Oriented programming) (注意 - 与面向对象的编程并不完全不同)

Verdict: Workaround 判决:解决方法

Single Assignment 单一作业

Any assignment that changes an existing value (eg x := x + 1) is disallowed in purely functional languages. 在纯函数式语言中不允许任何更改现有值的赋值(例如x:= x + 1)。 4 In functional programming, assignment is discouraged in favor of single assignment, also called initialization. 4在函数式编程中,不鼓励赋值单个赋值,也称为初始化。 Single assignment is an example of name binding and differs from assignment as described in this article in that it can only be done once, usually when the variable is created; 单一赋值是名称绑定的一个示例,与本文所述的赋值不同之处在于它通常只能创建一次,通常是在创建变量时; no subsequent reassignment is allowed. 不允许后续重新分配。

I'm not sure perl really does this. 我不确定perl真的这样做。 The closest approximation might be references/anonymous subs or perhaps constant . 最接近的近似可能是引用/匿名子或可能是constant

Verdict: Not Supported 判决:不支持

Lazy Evaluation 懒惰的评价

Waiting until the last possible moment to evaluate an expression, especially for the purpose of optimizing an algorithm that may not use the value of the expression. 等到最后可能的时刻来评估表达式,特别是为了优化可能不使用表达式值的算法。

Examples of lazy evaluation techniques in Perl 5? Perl 5中的惰性评估技术示例?

And again, coming back to Higher Order Perl (I'm not affiliated with this book, honest - it just seems to be one of the key texts on the subject). 再一次,回到高阶Perl (我不是这本书的附属,诚实 - 它似乎只是关于这个主题的关键文本之一)。

The core concept here seems to be - create a 'linked list' in perl (using object oriented techniques) but embed a code reference at your 'end marker' that evaluates if you ever get that far. 这里的核心概念似乎是 - 在perl中创建一个'链表'(使用面向对象的技术),但在你的'结束标记'中嵌入了一个代码引用,用于评估你是否已经达到目标。

Verdict: Workaround 判决:解决方法

Garbage Collection 垃圾收集

"GarbageCollection (GC), also known as automatic memory management, is the automatic recycling of heap memory." “GarbageCollection(GC),也称为自动内存管理,是堆内存的自动回收。”

Perl does this via reference counting, and releasing things when they are no longer referenced. Perl通过引用计数执行此操作,并在不再引用它们时释放它们。 Note that this can have implications for certain things that you're (probably!) more likely to encounter when functional programming. 请注意,这可能会影响您(可能!)在函数式编程时更有可能遇到的某些事情。

Specifically - circular references which are covered in perldoc perlref 具体而言 - perldoc perlref中涵盖的循环引用

Verdict: Native support 判决:原生支持

Type Inference 类型推断

TypeInference is the analysis of a program to infer the types of some or all expressions, usually at CompileTime TypeInference是一个程序的分析,用于推断一些或所有表达式的类型,通常在CompileTime

Perl does implicitly cast values back and forth as it needs to. Perl会根据需要隐式地来回转换值。 Usually this works well enough that you don't need to mess with it. 通常这很好用,你不需要弄乱它。 Occasionally you need to 'force' the process, by making an explicit numeric or string operation. 有时您需要通过进行显式数字或字符串操作来“强制”该过程。 Canonically, this is either by adding 0, or concatenating an empty string. 通常,这可以通过添加0或连接空字符串来实现。

You can overload a scalar to do different things in by using dualvars 您可以使用dualvars重载标量以执行不同的操作

Verdict: Native support 判决:原生支持

Tail Call Optimization 尾调用优化

Tail-call optimization (or tail-call merging or tail-call elimination) is a generalization of TailRecursion: If the last thing a routine does before it returns is call another routine, rather than doing a jump-and-add-stack-frame immediately followed by a pop-stack-frame-and-return-to-caller, it should be safe to simply jump to the start of the second routine, letting it re-use the first routine's stack frame (environment). 尾调用优化(或尾调用合并或尾调用消除)是TailRecursion的一般化:如果例程在返回之前做的最后一件事是调用另一个例程,而不是做一个跳转和添加堆栈帧紧接着是一个pop-stack-frame-and-return-to-calller,它应该是安全的,只需跳转到第二个例程的开头,让它重新使用第一个例程的堆栈帧(环境)。

Why is Perl so afraid of "deep recursion"? 为什么Perl如此害怕“深度递归”?

It'll work, but it'll warn if your recursion depth is >100. 它会工作,但如果您的递归深度> 100,它会发出警告。 You can disable this by adding: 您可以通过添加:

no warnings 'recursion';

But obviously - you need to be slightly cautious about recursion depth and memory footprint. 但显然 - 你需要对递归深度和内存占用略微谨慎。

As far as I can tell, there isn't any particular optimisation and if you want to do something like this in an efficient fashion, you may need to (effectively) unroll your recursives and iterate instead. 据我所知,没有任何特定的优化 ,如果你想以有效的方式做这样的事情,你可能需要(有效地)展开你的递归并迭代。

Tailcalls are supported by perl. Perl支持Tailcalls。 Either see the goto ⊂ notation, or see the neater syntax for it provided by Sub::Call::Tail 要么看到转到⊂符号,要么看看Sub::Call::Tail提供的neater语法

Verdict: Native 判决:原住民

List Comprehensions 列表理解

List comprehensions are a feature of many modern FunctionalProgrammingLanguages. 列表推导是许多现代FunctionalProgrammingLanguages的一个特征。 Subject to certain rules, they provide a succinct notation for GeneratingElements? 根据某些规则,它们为GeneratingElements提供了简洁的表示法? in a list. 在列表中。 A list comprehension is SyntacticSugar for a combination of applications of the functions concat, map and filter 列表理解是SyntacticSugar,用于函数concat,map和filter的应用程序组合

Perl has map , grep , reduce . Perl有mapgrepreduce

It also copes with expansion of ranges and repetitions: 它还可以应对范围和重复的扩展:

my @letters = ( "a" .. "z" ); 

So you can: 所以你可以:

my %letters = map { $_ => 1 } ( "A" .. "z" ); 

Verdict: Native ( List::Utils is a core module) 判决:Native( List::Utils是核心模块)

Monadic effects 单子效应

... nope, still having trouble with these. ......不,仍然有这些问题。 It's either much simpler or much more complex than I can grok. 它要么比我能理解得简单得多,要么复杂得多。

If anyone's got anything more, please chip in or edit this post or ... something. 如果有人有更多的东西,请填写或编辑这篇文章或......某事。 I'm still a sketchy on some of the concepts involved, so this post is more a starting point. 我对所涉及的一些概念仍然很粗略,所以这篇文章更多的是一个起点。

Really nice topic, I wanted to write an article titled something link "the camel is functional". 非常好的话题,我想写一篇题为“骆驼功能正常”的文章。 Let me contribute with some code. 让我贡献一些代码。

Perl also support this anonymous functions like Perl也支持这种匿名函数

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM