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 let
, 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 = x
by a regular occurs check.