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

Re: Pre-RFC: Phaser Expressions

Thread Previous | Thread Next
From:
Yuki Kimoto
Date:
November 16, 2021 00:56
Subject:
Re: Pre-RFC: Phaser Expressions
Message ID:
CAExogxNFRiSZ2mUHuR5VZPrLNuf2fX1Q0TY+eLDgrfzcxyzWxA@mail.gmail.com
I don't oppose this Pre-RFC.

However I am worried that RFCs will increase before more important things
are completed.

For example, isa, try - catch - finally, match, signatures.


2021年11月15日(月) 20:47 Paul "LeoNerd" Evans <leonerd@leonerd.org.uk>:

> TL;DR: Add `BEGIN expr...` syntax to hoist the evaluation time of an
>   expression into BEGIN time, without creating a new scope.
>
> Regular `my` variable assignment happens at runtime, even though the
> variable itself is visible much earlier. Usually we don't notice this
> problem, but occasionally awkward things happen.
>
> For example, in a unit test or self-contained script file, it's common
> to put little helper classes at the end of the file so they don't
> clutter up the main logic. This means that assignment statements in
> that package happen "too late" for the program to work properly. E.g.
> consider
>
>   #!/usr/bin/perl
>   use v5.36;
>
>   Helper::say_hello;
>
>   package Greeter {
>     my $message = "Hello, world";
>     sub say_hello { say $message }
>   }
>
> Here, while the variable is known to exist and thus the code compiles
> OK, the assignment hasn't actually happened yet and so `undef` is
> printed, with a warning.
>
> The first reaction to this might be to wrap the line in a BEGIN block,
> but then the variable is hidden by the braces of that BEGIN block.
> Often this is solved in practice by splitting the declaration and
> assignment in two:
>
>   package Greeter {
>     my $message; BEGIN { $message = "Hello, world"; }
>     ...
>
> This is a bit messy, and also a DRY failure - we've named the variable
> twice.
>
> It would be great if `BEGIN` (and by extension the admittedly
> less-useful phasers of INIT, CHECK and UNITCHECK) could also be
> prefixes for expressions, allowing one to write:
>
>   package Greeter {
>     BEGIN my $message = "Hello, world";
>     sub say_hello { say $message }
>   }
>
> There are no extra braces here, so the variable isn't hidden by the
> block but is visible to subsequent code. But being prefixed by BEGIN we
> can see it is evaluated at BEGIN time and its side-effects (namely, the
> assignment of a value into the variable) have already happened.
>
>
> Phaser expressions in non-void context would also be evaluated once, at
> the appropriate time, and replaced by a compiletime constant containing
> the result. This might also be handy for many situations where
> currently folks `use constant ...` to get a constant that's only ever
> used once.
>
>   use Digest::MD5 'md5_hex';
>
>   foreach ( 1 .. 100 ) {
>     say "The MD5 hash is ", BEGIN(md5_hex("my content here"));
>   }
>
> This would act like an "anonymous scalar", being roughly equivalent to:
>
>   use Digest::MD5 'md5_hex';
>
>   my $md5; BEGIN { $md5 = md5_hex("my content here"); }
>
>   foreach ( 1 .. 100 ) {
>     say "The MD5 hash is ", $md5;
>   }
>
> except without polluting the lexical namespace with an additional name.
>
>
> Such syntax would also handily solve the problem of `my` being used for
> class data, as discussed by:
>
>   https://github.com/Ovid/Cor/issues/44#issuecomment-968818780
>
> --
> 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