why is this legal

Vincent Zweije zweije@cs.kun.nl
Tue, 5 Feb 2002 11:28:04 +0100


On Sat, Feb 02, 2002 at 10:03:20AM -0500, Antony Courtney wrote:

||    f x = f' 0 x
||        where f' acc [] = acc
||              f acc (x:xs) = f' (x+acc) xs

||  Yes, these are all valid uses, which is why I would favor having the
||  compiler emit a warning in such circumstances.
||
||  Interestingly, this is exactly what gcc does if you shadow a parameter
||  with a local variable in a function in C:
||
||  int f(int y) {
||    int y = 20;
||
||    return y + 10;
||  }

It is not exactly the same.  The C construct makes y completely
unusable.  The Haskell construct leaves f usable from the outer scope.

||  $ gcc -c shadow.c
||  shadow.c: In function `f':
||  shadow.c:4: warning: declaration of `y' shadows a parameter
||  $
||
||  Many in the Haskell community disagree with me, but I find compiler
||  warnings such as the above immensely helpful.  They are a way for the
||  compiler to say to the programmer, "Your program has a reasonable
||  meaning, but you used some dangerous construct so that what you said
||  might not have been what you meant."
||
||  Of course, good compilers/tools will let you turn such warnings on and
||  off selectively, and good programmers write programs that compile
||  without warnings (since warnings usually indicate dubious constructs).
||  While the examples you give are valid, I'm not convinced they are common
||  enough that a warning would become a nuisance.

How about (having an option for) emitting a warning only when the types
of the shadowing variable and the shadowed variable are unifyable?
That would be a nice approximation of when the shadowing might be an
actual programming error.