Warn on recursive bindings
When you accidentally write something like
let x = .. x ... it can take hours to realize where you made your mistake. This hits me once in a while, and my colleagues often.
I'd propose e.g.
-Wrecursive-bindings that says:
warning: [-Wrecursive-bindings] Recursive binding for `x` in let x = length x
This applies to
where and top-level pattern bindings.
I believe that in practice, I only actually use real recursive bindings once in a while. So I might be bold enough to encourage enabling it in
-Wall for a future major GHC release.
With the compromise that if you have the warning enabled but in one specific place, you want a recursive binding, you can use the
~ tilde to say "I really mean it", e.g.
let ~ones = 1 : ones
That seems like a nice balance to say "I know what I'm doing in this case". So the warning could be more helpful, like:
warning: [-Wrecursive-bindings] Recursive binding for `ones` in let ones = length ones If intentional, use the tilde marker on the name like this: let ~ones = length ones
In Intero if I were to implement a prototype of this check, I'd probably do this, after renaming:
- Use SYB to collect all variable bindings from the pattern.
- Use SYB to listify all mentions of any of these variables in the RHS and any guards or where clauses.
If the list is non-empty, then trigger the error. A transformation function
[Name] -> Pat -> Pat would provide the AST with the offending name(s) tilded as
~x for use in the error message.
If there's general agreement, I could implement this change.
- *EDIT**: mutually recursive bindings apply here too. So
let x = y; y = xby a regular occurs check.