> Sorry for all the individual messages here. Let me take a last whack at
> this:
> 
> > Now what if you leave out the declaration?  Then Perl can generate a
> > warning about the $myint in the inner scope shadowing the $myint in
> > the outer scope.  This is what C does.  I think that this has proven
> > to be a successful solution for C.  It might work well for Perl also.
> 
> No, I don't think this is a good idea. I think if someone writes code
> like this:
> 
>    if (condition) {
>       $switch = 1;
>    }
>    # ... 
>    print "$something" if $switch;
> 
> This should do what is intended, without the my()'s. I don't think
> making this harder to do has any benefit.

OK, we seem to have four incompatible proposals here.

1. Declarations should be required on all variables.
   This is also consistent with 'strict vars should be the default'.

   I know Nat has this position, but I think you don't, because that's
   inconsistent with what you say above.

2. Perl should stay the way it is, with variables global by default.

   That's consistent with what you say above, but I'm not sure if it's
   actually your position.

   Note that even if you want Perl to stay the way it is, people
   programming under 'strict vars' by choice will no be able to tell
   the difference between 1 and 2.

3. Variables should be lexical by default:

   a. Perl should be conservative about inference and issue a warning
      when scopes appear to overlap, as in the example above.  In such
      cases a declaration at the outer scope may be required for
      correct behavior.

   b. Perl should be more liberal about inference and should try to do
      the right thing without warnings, as in the example above.

   This is my position (although I haven't committed to 3a or 3b yet
   because the details are not explicit), and it's *also* consistent
   with what you say above, so I'm not sure that you're even
   disagreeing with me. 

You said:

> This should do what is intended, without the my()'s. I don't think
> making this harder to do has any benefit.

Scenario (2) is the current state of affairs: The code 'works' without
change.  I think it may be possible to create 3b so that it also works
without change, so it is not 'harder to do'.

3a is a little harder than (2), because it requires a declaration.
But it is easier than (1), because it requires one declaration instead
of two.

> > You said it would necessarily be strange and obfuscated, and I don't
> > think this situation would be either strange or obfuscated.
> 
> If it's the above example, I think it's both. Definitely. 

3b is identical to (2).  It does the right thing without change.

3a requires a declaration.  The declaration is required in the same
place that it would be required under (1).  For situation (2), people
programming with 'strict vars' would still have to put in a
declaration (the same one) as in (1); this is also the same
declaration that is required in 3a.

EXPLANATION OF 3a:

You seem to be confused, so I'm going to exlpain 3a in more detail.
On the left is the code you actually wrote; on the right is the code
that the compiler pretends that you wrote:

Example 1:

    YOU WRITE:                     PERL INFERS THAT YOU MEANT:

    my $switch;                    my $switch;
    if (condition) {               if (condition) {
       $switch = 1;                  $switch = 1;
    }                              }
    # ...                          # ...
    print "..." if $switch;        print "..." if $switch;

In this case the Perl 5 and Perl 6 behavior are identical.  

Example 2:

    YOU WRITE:                     PERL INFERS THAT YOU MEANT:

    if (condition) {               if (condition) {
       my $switch = 1;                my $switch = 1;
    }                              }
    # ...                          # ...
    print "..." if $switch;        print "..." if $switch;

In this case the Perl 5 and Perl 6 behavior are identical.  The
$switch inside the conditional is different from the one on the print
statement, but that is what you asked for, so it is what you got, just
the same as in Perl 5.


Example 3:

    YOU WRITE:                     PERL INFERS THAT YOU MEANT:

                                   my $switch;
    if (condition) {               if (condition) {
       $switch = 1;                  my $switch = 1;
    }                              }
    # ...                          # ...
    print "..." if $switch;        print "..." if $switch;

                                   WARNING: $switch on line 2 is not
                                            the same as $switch on line 5


Here's the one with the problem.  Perl infers too many declarations
and you don't get what you want.  But you do get a warning.  To fix
it, you add the declaration to make it look like example 1.  This is
not obfuscated or confusing because the resulting code has exactly the
same meaning in Perl 5 and in Perl 6. 

The rule for how Perl infers 'my' is:  Perl infers a 'my' at the
innermost possible scope for every variable that isn't explicitly
declared in some outer scope.

Disadvantages compared to (2), the current state of affairs:  Requires
a declaration.  Advantages compared to (2):  All of the advantages of
the lexical-rich programming style achieved by (1).  This is the big,
big win.  You no longer have to worry that the $x in one part of your
program will collide with an unrelated $x in some other part of the
program.  If you don't think that global variables are a big problem
and need to be avoided whenever possible, you aren't going to like
this proposal, because avoiding global variables is the whole point.

Disadvantages compared to (1), required 'strict':  Nat says it's good
to require that *all* variables be declared, but the purpose of this
proposal is to avoid that.  I disagree, but some people will see it as
a disadvantage.  Advantages compared to (1): Many programs run without
change.  Only a few programs require a few declarations (instead of
*all* programs requiring *many* declarations.)

The warning could be made into a compile-time error if people wanted that.

> If I was any level Perl programmer looking at this, I would be
> incredibly confused at what's going on.

I wish you had been more specific about what was confusing.  Since my
proposal is that the same code have the same behavior, I don't
understand how it could be confusing. 

> Remember, *many* Perl programmers don't know C. I'm a novice C
> programmer at best.

Then forget that I mentioned C; I only brought it up to show that one
of the alternatives (3a) I was proposing had already been tried and
that there were no hidden disasters.  But now I take it back, because
what I'm trying to do is something very different from C, because in C
the declarations are mandatory, and I'm trying to get away implicit
declarations.  

> However, I'm firmly against the other suggestions you have. I think we
> should either keep Perl the way it is, or make it so that the variables
> are *correctly* lexically scoped without the my()'s, but I do *NOT*
> think in any way that default Perl 6 should ever require a my().

Oh well, you won't like this then.

But I think you're being shortsighted.  I am trying to get rid of the
huge problems of default global variables.  To do that, I am making an
exchange: I require a few declarations.  The mandatory strict vars
people are trying to get rid of the same problem, and the cost is to
require declarations *everywhere*.  (Nat also points out that
requiring declarations everywhere buys a bigger benefit: More
declarations means that Perl can catch more errors.  My reply: Those
people should turn on strict vars instead of trying to put it into the
language.)

But if you don't think the thing I am trying to buy is worth buying,
then you certainly won't like my proposal.  If what you really want is
global variables by default, then you should just say so and stop
complaining about obfuscation and how you don't know C and all that
other stuff.



Reply via email to