Re: RFC 12 (v2) variable usage warnings

2000-09-21 Thread Bart Lateur

On Wed, 20 Sep 2000 12:30:26 -0600, Tom Christiansen wrote:

$a = undef;

You have initialized it to undef.

Solution:

Remove all references from the language to defined and undef.

Quite the reverse.

Simply assume that uninitialized variables in Perl simply don't exist,
that all variables (values) are ininitalized, but some of them to undef.
Therefore the word "initialized", when talking about Perl, is
meaningless.

Replace all occurences of the (sub)word "initialized" with "defined", in
all of the documentation and in all error messages, in particular in
"Use of uninitialized value%s".

Look at what perldiag says about it:

   Use of uninitialized value%s
 (W uninitialized) An undefined value was used as if it were already
 defined. It was interpreted as a "" or a 0, but maybe it was a
 mistake. To suppress this warning assign a defined value to your
 variables.

Look ma. The message talks about "uninitialized". The explanation only
talks about "defined"/"undefined". The message should match the
description.

-- 
Bart.



Re: RFC 12 (v2) variable usage warnings

2000-09-21 Thread Dave Storrs



On Wed, 20 Sep 2000, Steve Fink wrote:

 1 my ($x, $y, $z);
 2 $z = 1;
 3 my $logfile = "/tmp/log";
 4 $x = 1 if cond();
 5 print $x+$y;
 6 undef $z;
 7 print $z;
 
 -- use of uninitialized variable $y in line 5 (compile time)
 -- possible use of uninitialized variable $x in line 5 (compile time)
 -- variable $logfile defined in line 3 but never used (compile time)
 -- use of undefined value in line 7 (run time)


Couldn't the error on line 7 be detected at compile time as well?
After all, there is no execution path which will result in $z having a
defined value.

Dave




Re: RFC 12 (v2) variable usage warnings

2000-09-21 Thread Dave Storrs



On Wed, 20 Sep 2000, Eric Roode wrote:

 foo();
 print $x;
 
 Generate a warning, or not?  Which one? Remember, foo() may initialize $x.


My suggest (FWIW) would be that, if there is no execution path
which leads to $x being defined in the second line, then a "Use of
uninit'd variable $x" warning should be thrown at compile time.  If there
is at least one path that will result in $x being defined AND at least one
path that will result in it being undefined, the compile-time warning
could be something like "Possible use of undefined variable $x" or "Not
all execution paths leave $x defined".

Dave




Re: RFC 12 (v2) variable usage warnings

2000-09-21 Thread Steve Fink

Dave Storrs wrote:
 
 On Wed, 20 Sep 2000, Eric Roode wrote:
 
  foo();
  print $x;
 
  Generate a warning, or not?  Which one? Remember, foo() may initialize $x.
 
 My suggest (FWIW) would be that, if there is no execution path
 which leads to $x being defined in the second line, then a "Use of
 uninit'd variable $x" warning should be thrown at compile time.  If there
 is at least one path that will result in $x being defined AND at least one
 path that will result in it being undefined, the compile-time warning
 could be something like "Possible use of undefined variable $x" or "Not
 all execution paths leave $x defined".

Makes sense. Just have to be careful to describe all this stuff without
mixing together initialization vs definedness, globals vs lexicals, flow
control analysis vs counting occurrences, compile time vs run time, and
definite problems vs possible problems. Makes my head hurt.



Re: RFC 12 (v2) variable usage warnings

2000-09-21 Thread Eric Roode

Allow me to throw another log on the fire:

my $x;
if (something)
{
$x = 1;
}
my $y = $x;

This would give a compile-time warning under your RFC, warning the
user of a possibly uninitialized $x. Okay. Next:

my $x;
if (something)
{
$x = 1;
}
else
{
$x = 2;
}
my $y = $x;

Would this give the same warning? Would it notice that $x is set
in both branches of the condition?
Worse:

my $x;
if (something)
{
$x = 1;
}
if (!something)
{
$x = 2;
}
my $y = $x;

I presume this would generate a warning under your RFC, right?
Since I would guess the compiler shouldn't be required to notice
that one condition is the inverse of the other?
I'm not sure I like the above construct not behaving identically
to the second case (if...else...) above...

Moving on:

my $x;
if (thing1)
{
$x = 1;
}
elsif (thing2)
{
$x = 2;
}
elsif (thing3)
{
$x = 3;
}
else
{
$x = 4;
}
my $y = $x;

Warnings, or no?

How about:

my ($x, $i);
for ($i=0; $i10; $i++)
{
$x .= $i;
}
my $y = $x;

Now, I can look at that and see that $x will be '0123456789', but
the compiler can't be expected (imho) to know whether the loop
condition will ever execute, so under your RFC it will generate a
"possibly uninitialized" warning, right?

 --
 Eric J. Roode,  [EMAIL PROTECTED]   print  scalar  reverse  sort
 Senior Software Engineer'tona ', 'reh', 'ekca', 'lre',
 Myxa Corporation'.r', 'h ', 'uj', 'p ', 'ts';




Re: RFC 12 (v2) variable usage warnings

2000-09-21 Thread Steve Fink

Eric Roode wrote:
 
 Allow me to throw another log on the fire:
 
 my $x;
 if (something)
 {
 $x = 1;
 }
 my $y = $x;
 
 This would give a compile-time warning under your RFC, warning the
 user of a possibly uninitialized $x. Okay. Next:

Yes.

 my $x;
 if (something)
 {
 $x = 1;
 }
 else
 {
 $x = 2;
 }
 my $y = $x;
 
 Would this give the same warning? Would it notice that $x is set
 in both branches of the condition?

Yes, it would notice this and not warn. All paths of flow control
leading to the final statement contain an initialization.

 Worse:
 
 my $x;
 if (something)
 {
 $x = 1;
 }
 if (!something)
 {
 $x = 2;
 }
 my $y = $x;
 
 I presume this would generate a warning under your RFC, right?

Yes. And not necessarily a spurious one: consider using $dsoifjd++ for
'something'.

 Since I would guess the compiler shouldn't be required to notice
 that one condition is the inverse of the other?

It would also have to prove that the value of 'something' does not
change from one call to the next.

 I'm not sure I like the above construct not behaving identically
 to the second case (if...else...) above...

The "possibly" version would need to be optional (or more optional) than
the others. As soon as it gave me even one spurious warning, I would
immediately turn it off except to periodically turn on all warnings full
blast to get a "lint"-like effect.

 Moving on:
 
 my $x;
 if (thing1)
 {
 $x = 1;
 }
 elsif (thing2)
 {
 $x = 2;
 }
 elsif (thing3)
 {
 $x = 3;
 }
 else
 {
 $x = 4;
 }
 my $y = $x;
 
 Warnings, or no?

No warnings.

 How about:
 
 my ($x, $i);
 for ($i=0; $i10; $i++)
 {
 $x .= $i;
 }
 my $y = $x;
 
 Now, I can look at that and see that $x will be '0123456789', but
 the compiler can't be expected (imho) to know whether the loop
 condition will ever execute, so under your RFC it will generate a
 "possibly uninitialized" warning, right?

Right. We could stray from correctness here and assume any for loop is
executed at least once, but I'd rather not -- this is the code pattern
where it is most useful (because often the programmer doesn't notice
that, in fact, that for or while loop might not execute, in some weird
case.)

In this particular case, it might not be unreasonably difficult to ask
the question of "is COND true immediately after INIT in for(INIT; COND;
INCR)?" But the compiler certainly won't be that smart in version 1.



Re: RFC 12 (v2) variable usage warnings

2000-09-20 Thread Steve Fink

Tom Christiansen wrote:
 
 The warning for the use of an unassigned variable should be "use of
 uninitialized variable C$x".
 
 The problem with that idea, now as before, is that this check happens
 where Perl is looking at a value, not a variable.  Even were it possible
 to arduously modify Perl to handle explicitly named simple variables,
 there's much more to consider.
 
 if ( fx() == fy() ) { }
 
 For one.
 
 --tom

Yes, we've been through this before. :-) And now, as before, that's not
what the RFC is saying. Your fx() example would produce the warning "use
of undefined value". No variable name. Same for the code Cmy @x =
(1,2,3); print $x[32]. I am not changing the existing warning at all,
just rewording it from "uninitialized" to "undefined", because that's
what it is. 'Initialized' means you've assigned something to it at least
once; undefined means defined() returns false.

I am merely suggesting that the compiler detect, when it can, that
you're trying to use the value of a variable without ever having
assigned a value to that variable. And in THAT message, you had better
know the name of the variable, since it's the basis of the analysis. And
yes, it only handles simple named variables.

Example:

1 my ($x, $y, $z);
2 $z = 1;
3 my $logfile = "/tmp/log";
4 $x = 1 if cond();
5 print $x+$y;
6 undef $z;
7 print $z;

-- use of uninitialized variable $y in line 5 (compile time)
-- possible use of uninitialized variable $x in line 5 (compile time)
-- variable $logfile defined in line 3 but never used (compile time)
-- use of undefined value in line 7 (run time)

I'll add this example to the RFC.



Re: RFC 12 (v2) variable usage warnings

2000-09-20 Thread Tom Christiansen

And what about $$x?

Dang, are we back to this incredible confusion about what it is to be
defined in Perl.?

undef $a;

That is now UNINITIALIZED.  So is this:

$a = undef;

You have initialized it to undef.  There is no reasonable difference.

Solution:

Remove all references from the language to defined and undef.
People just aren't smart enough to understand them.  Change
defined() to read has_a_valid_initialized_scalar_value().  Change
undef() to "operator_to_uninitialize_a_variable".  Touch luck
on the chumps who can't type well.  They pay for their brothers'
idiocy.

repeat until blue:

  INITIALIZED ==   DEFINED
UNINITIALIZED == UNDEFINED


--tom



Re: RFC 12 (v2) variable usage warnings

2000-09-20 Thread Eric Roode

Steve Fink wrote:
I am merely suggesting that the compiler detect, when it can, that
you're trying to use the value of a variable without ever having
assigned a value to that variable. And in THAT message, you had better
know the name of the variable, since it's the basis of the analysis. And
yes, it only handles simple named variables.

Um, "when it can"? Isn't this considered a Hard Problem by the 
computer scientists? 


Example:

1 my ($x, $y, $z);
2 $z = 1;
3 my $logfile = "/tmp/log";
4 $x = 1 if cond();
5 print $x+$y;
6 undef $z;
7 print $z;

-- use of uninitialized variable $y in line 5 (compile time)
-- possible use of uninitialized variable $x in line 5 (compile time)
-- variable $logfile defined in line 3 but never used (compile time)
-- use of undefined value in line 7 (run time)

How about:

foo();
$x = 1  unless defined($x);
print $x;

Generate a warning, or not?

Or:
foo();
print $x;

Generate a warning, or not?  Which one? Remember, foo() may initialize $x.

 --
 Eric J. Roode,  [EMAIL PROTECTED]   print  scalar  reverse  sort
 Senior Software Engineer'tona ', 'reh', 'ekca', 'lre',
 Myxa Corporation'.r', 'h ', 'uj', 'p ', 'ts';




Re: RFC 12 (v2) variable usage warnings

2000-09-20 Thread Steve Fink

Eric Roode wrote:
 
 Steve Fink wrote:
 I am merely suggesting that the compiler detect, when it can, that
 you're trying to use the value of a variable without ever having
 assigned a value to that variable. And in THAT message, you had better
 know the name of the variable, since it's the basis of the analysis. And
 yes, it only handles simple named variables.
 
 Um, "when it can"? Isn't this considered a Hard Problem by the
 computer scientists?

The halting problem is unsolvable. That doesn't mean you can't figure
out whether the complete program

$x = 1

halts.

But that doesn't even matter that much here; I'm saying that if the
compiler can definitely determine that you are using an uninitialized
variable, it should warn. If you're using something that appears like it
might be uninitialized, but can't be proven either way without solving
that pesky halting problem, then it (if you ask it) says "you might have
screwed up." 90% of the time, it's right -- if the right set of freak
occurrences happen, you really do use the value of an uninitialized
variable. As an example, this may produce a spurious warning:

$y = 1 if $x;
$y = 2 if ! $x; 

...because the compiler is unable to be sure that ($x) || (!$x) is
definitely true. (And in fact, it might not be in the presence of tying.
Which is why, when doing this sort of thing, compilers usually
completely ignore the actual conditions being tested, and assume that
they're independent and sometimes true, sometimes false.)

 Example:
 
 1 my ($x, $y, $z);
 2 $z = 1;
 3 my $logfile = "/tmp/log";
 4 $x = 1 if cond();
 5 print $x+$y;
 6 undef $z;
 7 print $z;
 
 -- use of uninitialized variable $y in line 5 (compile time)
 -- possible use of uninitialized variable $x in line 5 (compile time)
 -- variable $logfile defined in line 3 but never used (compile time)
 -- use of undefined value in line 7 (run time)
 
 How about:
 
 foo();
 $x = 1  unless defined($x);
 print $x;
 
 Generate a warning, or not?

$x is a global. The compiler cannot detect all possible assignments to
or accesses of globals, so it never warns about them.

If you inserted my $x at the top of that code, it would most likely
produce the "possible use" warning. Or not; this is a simple enough case
that it might be able to infer the right answer.

I am certainly not saying that the "possible use" warning should be
enabled by default. But please, argue over that one separately from the
others. It's the most likely to annoy.

 Or:
 foo();
 print $x;
 
 Generate a warning, or not?  Which one? Remember, foo() may initialize $x.

Same thing. If $x is lexical, it gives a definite warning. If $x is a
global, it says nothing. You're right; I need to point this out in the
RFC.



Re: RFC 12 (v2) variable usage warnings

2000-09-20 Thread Tom Christiansen

But that doesn't even matter that much here; I'm saying that if the
compiler can definitely determine that you are using an uninitialized
variable, it should warn. 

...

$x is a global. The compiler cannot detect all possible assignments to
or accesses of globals, so it never warns about them.

If you inserted my $x at the top of that code, it would most likely
produce the "possible use" warning. Or not; this is a simple enough case
that it might be able to infer the right answer.

I am certainly not saying that the "possible use" warning should be
enabled by default. But please, argue over that one separately from the
others. It's the most likely to annoy.

 Or:
 foo();
 print $x;
 
 Generate a warning, or not?  Which one? Remember, foo() may initialize $x.

Same thing. If $x is lexical, it gives a definite warning. If $x is a
global, it says nothing. You're right; I need to point this out in the
RFC.

Careful:

sub ouch {
my $x;
my $fn = sub { $x++ };
register($fn);
print $x;
} 

--tom



Re: RFC 12 (v2) variable usage warnings

2000-09-20 Thread Steve Fink

Tom Christiansen wrote:
 
 And what about $$x?
 
 Dang, are we back to this incredible confusion about what it is to be
 defined in Perl.?
 
 undef $a;
 
 That is now UNINITIALIZED.  So is this:
 
 $a = undef;
 
 You have initialized it to undef.  There is no reasonable difference.
 
 Solution:
 
 Remove all references from the language to defined and undef.
 People just aren't smart enough to understand them.  Change
 defined() to read has_a_valid_initialized_scalar_value().  Change
 undef() to "operator_to_uninitialize_a_variable".  Touch luck
 on the chumps who can't type well.  They pay for their brothers'
 idiocy.
 
 repeat until blue:
 
   INITIALIZED ==   DEFINED
 UNINITIALIZED == UNDEFINED

Thank you, that's a better way of describing part of the intent of this
RFC. I want to distinguish between variables that are uninitialized, and
expressions whose values are undefined.

my $x; # $x is uninitialized. Also, the value of $x is undefined.
undef $x; # $x has now been initialized. The value of $x is still
undefined.

This is *not* adding a new sort of value to perl. It is adding a
different state for the compiler to think of a variable as being in.
Initialization of a variable means you've done something that influenced
the value of that variable -- either by setting it, or blowing it away
and making it undefined.

You aren't interpreting the last part of the DESCRIPTION section ("you
need to do my $x= undef") as meaning that

my $x;
and
my $x = undef;

have a runtime difference, are you? I think this is confusing some
people, and I really shouldn't say "you would need to" do anything
different; I meant "you would need to say my $x = undef if you have this
warning turned on and you don't want to see it."



Re: RFC 12 (v2) variable usage warnings

2000-09-20 Thread Tom Christiansen

Anything else? Any opinion on whether eval "" should do what it does
now, and be invisible for the purposes of this analysis; or if it should
be assumed to instead both use and initialize all visible variables? The
former produces more spurious warnings, the latter misses many errors.

You have to assume eval STRING can do anything.

--tom



Re: RFC 12 (v2) variable usage warnings

2000-09-20 Thread Steve Fink

Tom Christiansen wrote:
 
 Anything else? Any opinion on whether eval "" should do what it does
 now, and be invisible for the purposes of this analysis; or if it should
 be assumed to instead both use and initialize all visible variables? The
 former produces more spurious warnings, the latter misses many errors.
 
 You have to assume eval STRING can do anything.
 
 --tom

"have to"? Perl5 doesn't.

% perl -we '$x = 3; $v = "x"; eval "\$$v++"'
Name "main::x" used only once: possible typo at -e line 1.

I'd rather think of it as a cost-benefit tradeoff.



Re: RFC 12 (v2) variable usage warnings

2000-09-20 Thread Tom Christiansen

Tom Christiansen wrote:
 
 Anything else? Any opinion on whether eval "" should do what it does
 now, and be invisible for the purposes of this analysis; or if it should
 be assumed to instead both use and initialize all visible variables? The
 former produces more spurious warnings, the latter misses many errors.
 
 You have to assume eval STRING can do anything.
 
 --tom

"have to"? Perl5 doesn't.

You mean "perl".

% perl -we '$x = 3; $v = "x"; eval "\$$v++"'
Name "main::x" used only once: possible typo at -e line 1.

Non sequitur.  And no, I don't have time.



Re: RFC 12 (v2) variable usage warnings

2000-09-20 Thread Steve Fink

Tom Christiansen wrote:
 
 Tom Christiansen wrote:
 
  Anything else? Any opinion on whether eval "" should do what it does
  now, and be invisible for the purposes of this analysis; or if it should
  be assumed to instead both use and initialize all visible variables? The
  former produces more spurious warnings, the latter misses many errors.
 
  You have to assume eval STRING can do anything.
 
  --tom
 
 "have to"? Perl5 doesn't.
 
 You mean "perl".
 
 % perl -we '$x = 3; $v = "x"; eval "\$$v++"'
 Name "main::x" used only once: possible typo at -e line 1.
 
 Non sequitur.  And no, I don't have time.

It is relevant in that perl's existing behavior has proven to be useful
even though the implementation is not correct. The correct
implementation would not have issued the above warning, because an
eval"" was present in the code. However, the correct implementation
would also fail to warn in many legitimate cases. The current heuristic
seems to strike a pretty good balance:

% perl -le '$x = 3; eval "\$x++"'
(no warning issued)



Re: RFC 12 (v2) variable usage warnings

2000-09-20 Thread Tom Christiansen

Have a nice day.  And thanks for all the fish.



Re: RFC 12 (v2) variable usage warnings

2000-09-20 Thread Daniel Chetlin

On Wed, Sep 20, 2000 at 07:20:44PM -0700, Steve Fink wrote:
 Tom Christiansen wrote:
  Steve Fink wrote:
  % perl -we '$x = 3; $v = "x"; eval "\$$v++"'
  Name "main::x" used only once: possible typo at -e line 1.
 
  Non sequitur. And no, I don't have time.

 It is relevant in that perl's existing behavior has proven to be
 useful even though the implementation is not correct.

I think Tom's point is that the eval has nothing to do with what
you're showing.

  [~] $ perl -we '$x = 3; $v = "x"; eval "\$$v++"'
  Name "main::x" used only once: possible typo at -e line 1.
  [~] $ perl -we '$x = 3; $v = "x"; $$v++'
  Name "main::x" used only once: possible typo at -e line 1.

 The correct implementation would not have issued the above warning,
 because an eval"" was present in the code. However, the correct
 implementation would also fail to warn in many legitimate cases. The
 current heuristic seems to strike a pretty good balance:

 % perl -le '$x = 3; eval "\$x++"'
 (no warning issued)

  [~] $ perl -wle'$x = 3; eval "\$x++"'
  Name "main::x" used only once: possible typo at -e line 1.



Re: RFC 12 (v2) variable usage warnings

2000-09-19 Thread Tom Christiansen

The warning for the use of an unassigned variable should be "use of
uninitialized variable C$x". 

The problem with that idea, now as before, is that this check happens 
where Perl is looking at a value, not a variable.  Even were it possible
to arduously modify Perl to handle explicitly named simple variables,
there's much more to consider.

if ( fx() == fy() ) { }

For one.

--tom