Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical
 
PerlMonks  

why does Perl eval have a strange terminator?

by misterperl (Pilgrim)
on Jun 14, 2022 at 14:33 UTC ( [id://11144728]=perlquestion: print w/replies, xml ) Need Help??

misterperl has asked for the wisdom of the Perl Monks concerning the following question:

Blessed Monks:

Maybe I'm missing something but why does

eval { lines ending in ; }; ^ | require that?
Everywhere else in Perl like map, if, else, while, given, etc etc, I guess either the last ; is implied (as it is on the last line BEFORE the "}" , or maybe something is different about eval? I use it so infrequently, I inadvertently forget it..

TY , Blessed Be!

Replies are listed 'Best First'.
Re: why does Perl eval have a strange terminator?
by LanX (Saint) on Jun 14, 2022 at 15:30 UTC
    That's how the parser is organized.

    you must distinguish between

    (Contrived) Examples:

    map and eval fall into the function category.

    • @x = map { $_ ** 2  } @y ;

      you can see multiple nested terms and functions in the statement

    • for ( eval{ some_func() } ) { print }

      for (EXPR) {BLOCK} is a compound statement and eval is single EXPR without(!) semicolon

    NB: If you wanted to use a compound statement inside an expression, you would need to put it inside do {BLOCK}

    HTH! :)

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    Wikisyntax for the Monastery

    updates

  • added links to simple-statements, terms and expressions
  • PS: It's a bit confusing that Larry's definition of "Term" (leaf of the syntax-tree) is different to the one in mathematics.
Re: why does Perl eval have a strange terminator?
by stevieb (Canon) on Jun 14, 2022 at 15:30 UTC

    From perlsyn:

    Simple Statements The only kind of simple statement is an expression evaluated for its s +ide-effects. Every simple statement must be terminated with a semicol +on, unless it is the final statement in a block, in which case the se +micolon is optional. But put the semicolon in anyway if the block tak +es up more than one line, because you may eventually add another line +. Note that there are operators like eval {}, sub {}, and do {} that +look like compound statements, but aren't--they're just TERMs in an e +xpression--and thus need an explicit termination when used as the las +t item in a statement.

    So, eval requires the terminating semicolon because it's a simple statement. You're using it for its side effects.

    sub, when used in an expression, requires the semicolon as well (eg. my $coderef = sub {...};).

Re: why does Perl eval have a strange terminator?
by ikegami (Patriarch) on Jun 14, 2022 at 16:32 UTC

    «if», «else» and «while» are keywords part of "if" statements and "while" statements. Flow control statements don't take semicolons.

    while ( COND ) BLOCK if ( COND ) BLOCK

    The «if» and «while» keywords are also found in statement modifiers. Statements with statement modifiers do take a semicolon.[1]

    EXPR while COND; EXPR if COND;

    eval and map are "functions" (named operators). Function calls do no take semicolons.

    if ( !eval { f() } ) { ... }
    But they may be found in statements which do use a semicolon.
    my $x = eval { f() } or ...;

    This includes simple statements.[1] These are statements that consist of nothing but an expression.

    EXPR;

    The statement you gave is an example of a simple statement, and so is the «or»-using statement above.

    C, C++, C#, JavaScript and Java all work this way.


    1. The semicolon can be omitted if it terminates the last statement of a block or file.

    Updated to elaborate.

      TY Monks, this helps and I understand the difference between compound/simple expessions, but I suppose I didn't understand that a simple statement can be, the same time BE a compound statement. But I suppose this is specific to eval perhaps?

      Although I do understand that, it might have seemed more consistent to also make eval { } compound?

      Brite Blessings to all!

        Although I do understand that, it might have seemed more consistent to also make eval { } compound?

        eval EXPR is often used more like a function ($sum = eval("3+4");), and the return value of eval BLOCK is important too (e.g. Bug in eval in pre-5.14). Thus it is consistent with e.g. do BLOCK, map BLOCK, grep BLOCK, and less with if, which though it has a "return value", I've very rarely seen it used, and e.g. the return value of for should explicitly not be relied upon (I can't find the reference for the latter right now but that's the gist of it). Think of eval like a function with a special syntax for its argument and it makes sense.

        I suppose I didn't understand that a simple statement can be, the same time BE a compound statement

        Something is either a simple statement or a compound statement, not both.

        But one can include the other.

        • eval { for (1..2) { f(); } }; is a simple statement.
        • for (1..2) { f(); } is a compound statement.
        • f(); is a simple statement.

        And eval is neither a simple nor a compound statement. As I've already said, eval is an operator (like +, and and time), not a type of statement.

        Operators can include blocks and thus statements:

        • do
        • eval
        • map
        • grep
        • sort
        • print (e.g. print { ; $fh } $_)
        • say
        • Subs calls to subs with the & prototype
        • Indirect method call (e.g. new { ; "Class" })
        • Replacement "expression" of s///e
        • Circumfix derefs (e.g. ${ ; \$_ })
        • (?{ }) in regex patterns
        • (??{ }) in regex patterns
        I think I'm beginning to understand where you're coming from.

        Try/Catch in other languages is a compound statement, and the new Perl feature is also implemented as such.

        But

        • eval {BLOCK};

        isn't, it's function like.

        I think that's at least partly due to sharing its name with

        • eval "string";

        in Perl.

        Actually it's quite surprising for many coming from other languages, that we call it "eval".

        Larry often loved to "recycle" concepts.

        Cheers Rolf
        (addicted to the Perl Programming Language :)
        Wikisyntax for the Monastery

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://11144728]
Approved by marto
Front-paged by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (3)
As of 2024-04-19 02:23 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found