Perl提供的编译时功能是什么,其他语言没有?

Laz*_*zer 4 scripting perl programming-languages

Perl被认为是通用编程语言吗?

维基百科上阅读它

Perl有一个图灵完备语法,因为解析可能会受到编译阶段执行的运行时代码的影响.[41] 因此,Perl无法通过直接的Lex/Yacc词法分析器/解析器组合进行解析.相反,解释器实现了自己的词法分析器,它与修改后的GNU bison解析器协调以解决语言中的歧义.

人们常说"只有perl可以解析Perl",这意味着只有Perl解释器(perl)才能解析Perl语言(Perl),但即便如此,这一点也不正确.因为Perl解释器可以在编译阶段模拟图灵机,所以需要决定停止问题以便在每种情况下完成解析.这是一个长期存在的结果,Halting问题是不可判定的,因此即使perl也不能总是解析Perl.Perl做出了不寻常的选择,让用户可以在自己的编译阶段获得完整的编程能力.理论纯度方面的成本很高,但实际上的不便似乎很少见.

因此,它说尽管Perl拥有Turing完整徽章,但它与其他语言不同,因为"让用户可以在自己的编译阶段访问其完整的编程功能".那是什么意思?Perl在编译阶段为我提供了哪些编程能力而其他人没有?

Axe*_*man 6

没有任何其他语言的Perl功能.Lisp可以做任何事情(Lisp就是一个例子,这里.).因此,也许我们可以将问题缩小到Perl的特性,这使得广泛的行为变得容易.

  • BEGIN块(END块也是.),它们编译期间改变了行为.所以我可以编写Perl代码来改变要加载的模块的位置.

    即使以下代码可能具有不同的含义.

    use Frobnify;
    Frobnify->new->initialize;
    
    Run Code Online (Sandbox Code Playgroud)

    因为我可以更改Frobnify加载的位置:

    BEGIN { 
        if ( [ localtime ]->[6] == 2 ) { 
            s|^/var|/var/days/tuesday| foreach @INC;
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)

    所以在周二,我加载 /var/days/tuesday/perl/lib/Frobnify.pm

  • 源过滤器可以以编程方式编辑将执行的代码.(源过滤器上的CAVEAT!)(粗略地和大致相当于LISP宏)

  • BEGIN块相关的是@INC钩子.因为我可以@INC在开始时修改以查看更改加载的内容.我可以在@INC数组的前面设置一个子程序来加载我想要加载的任何东西.钩子可以Frobnify通过加载接收加载和响应它的请求Defrobnify.pm.

  • 与此相关的是Symbol Manipuation.加载后Defrobnify.pm,我可以这样做:

    *Frobnify:: = \*Defrobnify::;
    
    Run Code Online (Sandbox Code Playgroud)

    现在Frobnify->new创建一个Defrobnify对象!

  • @delnan它取决于你所说的"编译".Perl被编译为字节码.@Axeman:"LISP可以做任何事情":你这是什么意思?任何图灵完备语言都可以在可计算性方面做任何事情,但我还没有看到一种语言,它不缺少我喜欢的其他语言的功能. (4认同)
  • @Philip Potter,Common LISP有CLOS可以做OO,Mixins和面向方面的编程.如果LISP的主要特征之一是它可以以一种使扩展看起来与内置构造没有区别的方式进行扩展.在C或Perl代码中是一个非结构化的字符串,程序必须手动解析才能进行操作.这通常容易出错.另一方面,LISP将所有代码视为一个数据结构,它将执行或将其传递给可在执行前改变结构的特殊函数. (2认同)