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

Under the OP's "proposal", you would still be able to do

$x = 123; { my $x = 456; }

They didn't advocate removing my, only making its use optional.

Replies are listed 'Best First'.
Re^3: A short whishlist of Perl5 improvements leaping to Perl7
by tobyink (Canon) on Nov 27, 2020 at 11:45 UTC
      wouldn't compile, because the second $x is not declared - there was no prior assignment on file-scope - and automine implied strict

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

Re^3: A short whishlist of Perl5 improvements leaping to Perl7
by LanX (Saint) on Nov 27, 2020 at 12:19 UTC
    > Under the OP's "proposal", you would still be able to do

    I can't see that the OP made a proposal just a fuzzy wish and linking to a thread where I coined the term automine and already highlighted the problems.

    >

    $x = 123; { my $x = 456; }

    Your example is redundant, cause the obvious rule is that any assignment in a new scope equals a declaration.

    So what's the proposal now?

    Python has IMHO

    • rather complicated rules, (which changed again in Py2.2 for enclosed )
    • no block-scope, no loop-scope, just (nested) function-scopes ( def )
    • no my to support, but the inverse nonlocal for Py3
    • it's hoisting declarations to scopes start
    These rules only look easy on simple cases, but closures are rather fuzzy. Given that most Pythonistas have a rather simple worldview, they don't miss closures.

    This model is very hard to transfer to Perl.

    Where would we steal? Ruby? Javascript?

    JS is a mess, a var is

    • like our outside a function
    • like my inside a function
    • is hoisting
    JS had to introduce let to have a proper my plus an optional strict

    So again WHAT is the proposal???

    For the records: I'd love to be able to have an automine pragma which makes easy cases easy and complicated cases feasible.

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

      Your example is redundant, cause the obvious rule is that any assignment in a new scope equals a declaration.

      That's ludicrous. It would prevent this common construct:

      my $x; if (f()) { ... $x = ...; } else { ... $x = ...; }

      And this one:

      my $found; for (...) { if (...) { $found = ... } }

      And this one:

      my @a; while (...) ... push @a, ...; }

      I don't think any program I've ever written would work!

        > That's ludicrous.

        That's why I elaborated two models.

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

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


      short version:*

      • basically only file and function scope are automatic.
      • all deeper nested scopes need to be explicit. Implicit effects there - if allowed - belong to the surrounding file/function scope.
      • nested subs are tricky


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

      • file-scope (outside any sub)

        $x = 1 ==> my $x =1

      • function-scope

        sub foo { $x = 1; ... } ==> sub foo { my $x =1; ... }

      • loop-header but NOT body

        for $x (@a) {...} ==> for my $x (@a) {...}

      • some commands like open *

        open $fh, ... ==> open my $fh, ...

      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

      • to restrict the scope of a var you'll still need an explicit my
      • an implicit my (i.e. assignment to a new var) belongs to the outer scope, starting with the block

        { $x=42 }; print $x; => 42

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

      • if they follow rule 1, than we need a declaration alike Py's nonlocal ... maybe its or over to mark vars avoiding implicit my
      • if they are exempt from rule 1 and rather act like 4, we get a break in symmetry
      • another solution would be a new keyword fun to create a sub with auto-mine while keeping sub explicit.
      6. ( ??? ) functional blocks like in map {BLOCK} are technically anonymous subs °
      • see point 5
      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 ...

      • Did I forget a case?
      • Do you need examples?
      • Please inform yourself about closures before judging.

      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

        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

Re^3: A short whishlist of Perl5 improvements leaping to Perl7
by kcott (Archbishop) on Nov 27, 2020 at 02:14 UTC

    OK, that's a fair point; one could differentiate between the two $x variables.

    I still dislike it. Given the OP has indicated "I think my idea isn't good", I don't think further discussion is necessary.

    — Ken

      I wasn't defending it. In fact, I explained why it's not a good idea here.

        "I wasn't defending it."

        That was my understanding. I certainly wasn't suggesting that you were defending it.

        — Ken