What Perl compilation features does Perl offer that other languages ​​do not?

advertisements

Is Perl considered a general purpose programming language?

Reading about it on Wikipedia

Perl has a Turing-complete grammar because parsing can be affected by run-time code executed during the compile phase.[41] Therefore, Perl cannot be parsed by a straight Lex/Yacc lexer/parser combination. Instead, the interpreter implements its own lexer, which coordinates with a modified GNU bison parser to resolve ambiguities in the language.

It is often said that "Only perl can parse Perl," meaning that only the Perl interpreter (perl) can parse the Perl language (Perl), but even this is not, in general, true. Because the Perl interpreter can simulate a Turing machine during its compile phase, it would need to decide the Halting Problem in order to complete parsing in every case. It's a long-standing result that the Halting Problem is undecidable, and therefore not even perl can always parse Perl. Perl makes the unusual choice of giving the user access to its full programming power in its own compile phase. The cost in terms of theoretical purity is high, but practical inconvenience seems to be rare.

So, it says that though Perl has the Turing complete badge, it is different from other languages because gives "the user access to its full programming power in its own compile phase". What does that mean? What programming power does Perl provide me at compiling phase that others don't?


There are no features of Perl that do not appear in any other language. Lisp can do anything (Lisp is an example, here.). So perhaps we can narrow the question down to what are the features of Perl that make wide behavior swings an easy thing to do.

  • BEGIN blocks (END blocks, too.) which alter the behavior during compile. So I can write Perl code that changes the location of modules to be loaded.

    Even the following code might have a different meaning.

    use Frobnify;
    Frobnify->new->initialize;
    
    

    Because I could have changed where Frobnify loads from:

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

    So on Tuesdays, I load /var/days/tuesday/perl/lib/Frobnify.pm

  • Source Filters can programmatically edit the code that will perform. (CAVEAT on source filters!) (crudely and roughly equivalent to LISP macros)

  • Somewhat along with BEGIN blocks are @INC hooks. As I can modify @INC at the beginning to see change what gets loaded. I can set a subroutine at the front of the @INC array to load anything I want to load. The hook can receive a request to load Frobnify and respond to it by loading Defrobnify.pm.

  • Somewhat along with this is Symbol Manipuation. After loading Defrobnify.pm, I can do this:

    *Frobnify:: = \*Defrobnify::;
    
    

    Now Frobnify->new creates a Defrobnify object!