Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw
 
PerlMonks  

Re: why does Perl eval have a strange terminator?

by ikegami (Patriarch)
on Jun 14, 2022 at 16:32 UTC ( [id://11144732]=note: print w/replies, xml ) Need Help??


in reply to why does Perl eval have a strange terminator?

«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.

Replies are listed 'Best First'.
Re^2: why does Perl eval have a strange terminator?
by misterperl (Pilgrim) on Jun 14, 2022 at 20:04 UTC
    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
        Try::Tiny requires a ;, and if you investigate why it is because it is implemented using prototypes.
        sub try (&;@) { ... sub catch (&;@) { ... sub finally (&;@) { ...
        I am not suggesting "eval BLOCK" is implemented using prototypes, but one could implement their own that would literally become a drop-in replacement (since the ; is likey already there. FWIW, (&;@) means the BLOCK param is coerced into a coderef, then optionally (after that ;), which allows something like the:
        try { } catch { } finally { };
        So now the POD seems to make a little more sense.
      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

        I think that's at least partly due to sharing its name with eval "string";

        It's due to it returning a value. That makes it an expression.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://11144732]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others admiring the Monastery: (2)
As of 2024-04-26 01:17 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found