[{"name":"CognitiveComplexity","comment":"\n\n@docs rule\n\n","unions":[],"aliases":[],"values":[{"name":"rule","comment":" Reports functions that have a too high cognitive complexity.\n\nYou can configure the threshold above which a function will be reported (`15` in the example configuration below).\n\n    config =\n        [ CognitiveComplexity.rule 15\n        ]\n\n\n## What is cognitive complexity?\n\nCognitive complexity is **not to be confused with \"Cyclomatic Complexity\"**, which has a different way of measuring the\ncomplexity.\n\nHere's an explanation extracted from [free white paper](https://www.sonarsource.com/resources/white-papers/cognitive-complexity/)\nprovided by SonarSource, the creators of the concept.\n\n> Cognitive complexity tries to measure how hard it is to understand a function, primarily focusing on the control structures\n> that hinder the understanding of a function by reading it from top to bottom in one go, like you would for a novel.\n\n> A Cognitive Complexity score is assessed according to three basic rules:\n\n> 1.  Ignore structures that allow multiple statements to be readably shorthanded into one\n> 2.  Increment (add one) for each break in the linear flow of the code\n> 3.  Increment when flow-breaking structures are nested\n\nSome small differences may be found between the implementation detailed in the paper and this rule, as the idea was\nformulated more on imperative programming languages, and may not be applicable to a pure functional language like Elm.\n\nYou can read about how is works in the [complexity breakdown section](#complexity-breakdown) below.\n\n\n## When (not) to enable this rule\n\nThis rule is an experiment. I don't know if this will be more useful or detrimental, and I haven't yet figured out what\nthe ideal complexity threshold for Elm projects is.\n\nI would for now recommend to use it with a very high threshold to find places in your codebase that need refactoring,\nand eventually to enable it in your configuration to make sure no new extremely complex functions appear. As you refactor more\nand more of your codebase, you can gradually lower the threshold until you reach a level that you feel happy with.\n\nPlease let me know how enabling this rule works out for you!\n\n\n## Complexity breakdown\n\nFollowing is a breakdown of how the complexity of a function is computed:\n\n  - If expression: Increases complexity by 1 + nesting, and increases nesting.\n    `else if` also increases complexity by 1 + nesting, but doesn't further increase the nesting.\n    `else` doesn't increase the complexity.\n\n```js\n-- Total: 4\na =\n  if b then           -- +1\n    if c then         -- +2, including 1 for nesting\n      1\n    else\n      2\n  else if d then      -- +1\n      3\n  else                -- +0\n      4\n```\n\n  - Case expression: Increases complexity by 1 + nesting, regardless of how many cases are handled, and increases nesting.\n\n```js\n-- Total: 3\na =\n  case b of -- +1\n    A -> 1\n    B -> 2\n    C ->\n      case c of -- +2, including 1 for nesting\n        _ -> 3\n    D -> 4\n```\n\n  - Let functions: Increases nesting.\n\n```js\n-- Total: 2\na =\n  let\n    fn b =   -- increases nesting\n      if b then    -- +2, including 1 for nesting\n        1\n      else\n        2\n\n    constant = -- Not a function, no increase\n      True\n  in\n  fn constant\n```\n\n  - Anonymous functions: Increases nesting.\n\n```js\n-- Total: 2\na things =\n  List.map\n    (\\thing ->        -- increases nesting\n      case thing of   -- +2, including 1 for nesting\n        Just _ -> 1\n        Nothing -> 2\n    )\n    things\n```\n\n  - Logical operator suites: Increase complexity by 1 for every discontinuation of the suite\n\n```elm\na && b -- +1\n\n-- This is still the same logical construction as\n-- above, and therefore about as hard to understand\na && b && c && d && e -- +1\n\n-- Total: 3\na && b && c -- +1\n  || d -- +1 for breaking the chain of && with a ||\n  || not (e || f) -- +1 for breaking the chain\n                  -- with a `not` of a binary operation\n```\n\n  - Recursive function calls (direct or indirect): Increase complexity by 1 for each different call\n\n```js\n-- Total: 2\nfun1 n =\n  fun2 n    -- +1\n  + fun2 n  -- +0, already counted\n  + fun1 n  -- +1\n\n-- Total: 1\nfun2 n =\n  fun1 n    -- +1\n```\n\n[The original metric](https://www.sonarsource.com/docs/CognitiveComplexity.pdf) increases the complexity for other\nstructures that the Elm language doesn't have.\n\n\n## Try it out\n\nYou can try this rule out by running the following command:\n\n```bash\nelm-review --template jfmengels/elm-review-cognitive-complexity/example --rules CognitiveComplexity\n```\n\nThe cognitive complexity is set to 15 in the configuration used by the example.\n\n\n## Thanks\n\nThanks to the team at SonarSource for designing the metric and for not restricting its use.\nThanks to G. Ann Campbell for the different talks she made on the subject.\n\n","type":"Basics.Int -> Review.Rule.Rule"}],"binops":[]}]