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

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!

  • Comment on Re^2: why does Perl eval have a strange terminator?

Replies are listed 'Best First'.
Re^3: why does Perl eval have a strange terminator?
by haukex (Archbishop) on Jun 14, 2022 at 20:26 UTC
    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.

Re^3: why does Perl eval have a strange terminator?
by ikegami (Patriarch) on Jun 14, 2022 at 20:55 UTC

    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.
Re^3: why does Perl eval have a strange terminator?
by LanX (Saint) on Jun 14, 2022 at 21:56 UTC
    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.