develooper Front page | perl.perl5.porters | Postings from July 2021

Re: Review of `defer` (was: FINALLY - ready for comments/review)

Thread Previous | Thread Next
From:
Paul "LeoNerd" Evans
Date:
July 28, 2021 19:13
Subject:
Re: Review of `defer` (was: FINALLY - ready for comments/review)
Message ID:
20210728201303.2eff5f1c@shy.leonerd.org.uk
On Wed, 28 Jul 2021 17:48:47 +0000
Oodler 577 via perl5-porters <perl5-porters@perl.org> wrote:

> This part made me get it more fully:
> 
>    The operation can be considered a little similar to an END block
> 
> Since the topic of Try::Tiny and requiring a "catch" block has come
> up, I feel like it's approproprite to request that there be some
> consistency between a generic "defer" block and the optional
> "finally" block of Try::Tiny.

Yes. `defer` is in many ways a prereq of adding `finally`, because once
OP_PUSHDEFER exists, then try/finally can simply use that in its
implementation.

> Questions:
> 
> a. does "defer" work if at the same "scope" as END? (and it's my
> understanding that END is executed regardless of the predestined exit
> code (e.g., 0, 255 (die), or something else).
> 
>   #foo.pl
>   my $foo = q{bar};
>   defer { print qq{hi!\n} };
>   sub END {
>     print qq{bye!\n};
>   }

I'm not sure I follow the question here. But here's the behaviour:

$ ./perl -Ilib -I. -E 'use feature "defer";
  defer { say "Hi!" }
  END { say "Bye!" }
  '
defer is experimental at -e line 2.
Hi!
Bye!

> b. are there any effective differences between "defer" and
> Try::Tiny's "finally"?

defer happens at the exit of its own containing block.
finally of try/finally acts as if there was a containing block around
the try/finally statement.

  {
    defer { say "Later"; }
    say "First";
  }

equiv to

  try { say "First"; }
  finally { say "Later"; }

> c. if "b" is, "not fundamentally", would it behoove us to make
> "defer" and "finally" consistent to the point that "defer" becomes
> "finally" and can be defined either inside the block to which it
> apples or can be added to the end of the block as "finally" appears
> to be in Try::Tiny ( I understand 'catch' and 'finally' are actually
> taken to be parameters of 'try', and prototype coersion is utilize
> for the desired effect)?
> 
> Ultimately, this boils down to this - it seems "defer" and "finally"
> are similar enough in nature (at least from the effective view of the
> developer), that it would be highly beneficial to make them
> consistently applied from the developer perspective. If we do not
> deeply consider this, then I am afraid we will be introducing yet
> another inconsistency.

Yes; they'll be implemented by the same underlying mechanism. See above.

> I'd like to point on that Qore has "on_exit" for subroutines, which
> seems like what "defer" would emulate if defined inside of a sub
> block.
> 
>    https://docs.qore.org/qore-1.0.2/lang/html/statements.html#on_exit
> 
> I thought D lang had the same sort of thing, but I can't seem to find
> it at this moment.

Go's `defer` operates at the function level too. It's not a great fit
for Perl's very lexical nature.

-- 
Paul "LeoNerd" Evans

leonerd@leonerd.org.uk      |  https://metacpan.org/author/PEVANS
http://www.leonerd.org.uk/  |  https://www.tindie.com/stores/leonerd/

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About