# NoRecursion plugin A GHC plugin to remove support for recursion General recursion can be the cause of a lot of problems. This removes recursion from GHC, allowing you to guarantee you’re using other mechanisms, like recursion schemes. ## usage Add `no-recursion` to your build dependencies. Add `-fplugin NoRecursion` to your GHC options. This can be done per-module with ```haskell {-# OPTIONS_GHC -fplugin NoRecursion #-} ``` Now, any recursion in that module will result in a compilation failure. **NB**: This won’t prevent you from using recursive functions imported from other modules, but inlined definitions from other modules _will_ be checked. ### allowing some recursion NoRecursion supports two source annotations: `"Recursion"` and `"NoRecursion"`. You can re-enable recursion for individual top-level names like ```haskell recDef :: a -> b recDef = myRecDef {-# ANN recDef "Recursion" #-} ``` Or you can re-enable recursion for an entire module with ```haskell {-# ANN module "Recursion" #-} ``` And then you can re-disable recursion for individual names with ```haskell nonRecDef :: a -> a nonRecDef = id {-# ANN nonRecDef "NoRecursion" #-} ``` If both '"Recursion"' and `"NoRecursion"` annotations exist on the same name (or module), it’s treated as `NoRecursion`. **NB**: If multiple names are mutually recursive, then they must all have recursion enabled to avoid being flagged by the plugin. `ANN` has some caveats: - `ANN` isn’t allowed by [Safe Haskell](https://downloads.haskell.org/ghc/latest/docs/users_guide/exts/safe_haskell.html), so any module that uses it will be inferred as `Unsafe`. - If you enable [the `OverloadedStrings` language extension](https://downloads.haskell.org/ghc/latest/docs/users_guide/exts/overloaded_strings.html), you will have to specify the type in the annotation, like ```haskell {-# ANN module "Recursion" :: String #-} ``` For more about how to use annotations, see [the GHC User’s Guide](https://downloads.haskell.org/ghc/latest/docs/users_guide/extending_ghc.html#source-annotations). ## comparisons Other projects similar to this one, and how they differ. ### [WartRemover](https://www.wartremover.org/) WartRemover is a Scala linting tool. [A `Recursion` wart](https://www.wartremover.org/doc/warts.html#recursion) was added in 2017, and I’ve been meaning to write this plugin ever since. It only took seven years to find a few hours to make it happen …