in reply to Re^3: A short whishlist of Perl5 improvements leaping to Perl7
in thread A short whishlist of Perl5 improvements leaping to Perl7

let's try a proposal as thought experiment and discuss it


short version:*


1. Any assignment to an undeclared new variable implies a "implicit" my when in

2. explicit my are still optionally allowed, our and state keep their semantics

3. No hoisting, a variable accessed before an implicit my still belongs to the upper scope and needs to be declared there

4. loop-bodies and naked blocks (technically the same) follow the old rules

5. ( ??? ) nested/anonymous subs are tricky, when it comes to closed over vars

6. ( ??? ) functional blocks like in map {BLOCK} are technically anonymous subs ° 7. ( ??? ) class-variables are a current issue in proposed new OOP models.

8. special global vars are exempt from implicit my.

9. Last but not least automine activates strict

So ...

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

°) actually not in the case of map and grep but for all of List::Util , try return to see the difference

*) updated

  • Comment on Re^4: A short whishlist of Perl5 improvements leaping to Perl7 (Thought Experiment No.1)
  • Select or Download Code

Replies are listed 'Best First'.
Re^5: A short whishlist of Perl5 improvements leaping to Perl7 (Thought Experiment No.2)
by LanX (Saint) on Nov 28, 2020 at 12:48 UTC
    While the former thought experiment was closer to Python's behavior - all vars belong (mostly) to function scope - there is another possible approach.

    1. any assignment to a new variable leads to an implicit my but only if their was no previous explicit declaration in a surrounding scope. This will replace former rules 1,4 and 5 all others still apply

    Hence we get the following 4 cases for explicit declarations with my or our

    automine effect comment
    { $x = 1; { $x = 2; } }
    { my $x = 1; { my $x = 2; } }
    not strict w/o automine
    { $x = 1; { my $x = 2; } }
    { my $x = 1; { my $x = 2; } }
    not strict w/o automine
    { my $x = 1; { $x = 2; } }
    { my $x = 1; { $x = 2; } }
    backwards compatible
    { my $x = 1; { my $x = 2; } }
    { my $x = 1; { my $x = 2; } }
    backwards compatible

    Surprises and pitfalls:

    automine effect comment
    sub foo { if (1) { $x = 2; } print $x; }
    sub foo { if (1) { my $x = 2; } print $x; # undeclared }
    Doesn't compile

    Surprising for Pythonistas

    sub add { $x = 0; for (1..9) { $x = $x + $_; } print $x; }
    sub add { my $x = 0; for (1..9) { my $x = $x + $_; } print $x; # prints 0 }
    Unexpected result!

    Needs an explicit my $x = 0 at init to avoid implicit my

    This is a very Perlish approach and avoids many edge cases.

    Of course this laziness comes with a price, introducing a new explicit declaration on file scope has an effect at the distance and could silently break subroutines

    use automine # our $var; ... sub foo { $var = shift; # not 'my $var' if explicit 'our $var' exists ... }

    That's why this theoretical pragma must be optional. (Of course scoping the our inside a tight block would also prevent this.)

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