David Feuer wrote:
From: Hal Daume III <hdaume@ISI.EDU>
then, why are we allowed to rebind f in a let clause :)
1. There is no real reason not to allow this,
Hmmm. I thought Hal gave a fairly real reason: f x = f' 0 x where f' acc [] = acc f acc (x:xs) = f' (x+acc) xs This example has a notoriously difficult to spot one character typo that causes the whole program to do something other than what the programmer intended at runtime.
so such a
rule would just limit the flexibility of the language and annoy programmers. It would also make it somewhat harder to write compilers, because they would have to check uselessly for violations of an extra rule.
You know, this is exactly the kind of argument used by a Scheme programmer to tell us why static type systems are bad. :-) I hope you share my (subjective) view that such complaints are bogus if we are talking about static type systems. If so, and if you will forgive a terrible pun, why do you think it's ok for the compiler to catch type errors, but not typing errors? (*GROAN*....couldn't resist, sorry.)
2. It increases the ability to move code around without changing it. For example, suppose you have [...] There is another, possibly more significant reason, however: sometimes it is very nice to be able to "shadow" an external variable
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; } $ 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. -antony -- Antony Courtney Grad. Student, Dept. of Computer Science, Yale University antony@apocalypse.org http://www.apocalypse.org/pub/u/antony
lör 2002-02-02 klockan 16.03 skrev Antony Courtney:
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.
Ghc warns for this if you give the option -fwarn-name-shadowing. However, it's extremely common to write code like this: f expr = case expr of EXPR_NOT expr -> something with expr EXPR_UNARY_MINUS expr -> something with expr not allowing this would make the programmer have to invent new names here. I had to turn off this warning for the project we do at work, because the compiler would emit hundreds of warnings for cases like this. Changing all bound names was not a good option. Regards, Martin
Martin Norbäck wrote: | However, it's extremely common to write code like this: | | f expr = case expr of | EXPR_NOT expr -> something with expr | EXPR_UNARY_MINUS expr -> something with expr | | not allowing this would make the programmer have to invent new names | here. I had to turn off this warning for the project we do at work, | because the compiler would emit hundreds of warnings for cases like | this. Changing all bound names was not a good option. I agree with Antony on that compilers should emit warnings on potentially-dangerous usages. Anyone working on a lint for Haskell? :-) It would be a valuable contribution to our community. On the other hand, I think Martin has a reasonable concern. However, note that in Hal's original example: | f x = f' 0 x | where f' acc [] = acc | f acc (x:xs) = f' (x+acc) xs the inner f is never used. Therefore I believe -fwarn-unused-local-binding (if there is such an option) will detect the bug in Hal's code without flooding stderr in Martin's case. - Zhanyong
I wrote: | Therefore I believe -fwarn-unused-local-binding | (if there is such an option) will detect the bug in Hal's code without | flooding stderr in Martin's case. While it is arguable whether the compiler should warn name shadowing by default, I believe unused local bindings should always be warned since: 1. such are dead code; 2. they almost always indicate a mistake by the programmer; 3. removing them only improves the clarity of the code. - Zhanyong
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.
participants (4)
-
Antony Courtney -
Martin Norbäck -
Vincent Zweije -
Zhanyong Wan