Is there any way to warn about shadowing a variable in the same scope?


#1

There is so much I like about ReasonML, but one thing that seems very risky to me is the ability to shadow variables in the same scope without any warning, so I am wondering if there is anyway to enable warnings for this.

For instance let’s say I have this piece of code

let specialValue = "someImportantValue";
foo(specialValue); 
...
/* later in the file */
bar(specialValue);

Now sometime in the future, someone adds a feature or fixes a bug, but they didn’t notice that x was already being used.

let specialValue = "someImportantValue";
foo(specialValue); 
...

/* further down in the file, we make this change, totally unrelated change */
let specialValue = "differentValue";  /* this had no relation to the original 
specialValue, we just hadn't realized this name was used */
cat(specialValue); 
...
/* later in the file */
bar(specialValue); /* now this is broken */

By simply introducing a new definition of specialValue for a different feature, I have silently caused a bug.

In most languages, when you would try to do this in the same scope then one will get an error or warning which is great since you might not have noticed that this variable already existed.

I understand that this feature makes it easier to work in the repl, but for other cases it seems like it causes unnecessary risk. I’m perfectly fine with this shadowing occurring inside of nested blocks, I am really just concerned with it happening in the same scope.

So I am hoping that there is a way to enable a warning flag to warn for this situation. I tried enabling all warnings with “+A” but that didn’t seem to give me any notice.

Thanks in advance!

Jeff


#2

That’s an interesting question. There’s no warning for exactly this scenario as far as I know. You could check the OCaml issue tracker to see if this has been requested before and maybe request it if not.

In practice I think the risk is mitigated because we tend to make functions relatively small. Having a function big enough that people can mistakenly shadow let-bindings (because they didn’t see the previous one) is actually an excellent indicator that the function should be broken up.


#3

Yeah, I realize that the risk is lessened in smaller functions, but it is still possible especially if you have lots of similar named variables.


#4

This looks like a discussion that might be related to what I am talking about.

In the comments a user suggested distinguishing between open/import and let shadowing.