jfmengels / elm-review-unused

Provides elm-review rules to detect unused elements in your Elm project
https://package.elm-lang.org/packages/jfmengels/elm-review-unused/latest/
BSD 3-Clause "New" or "Revised" License
23 stars 12 forks source link

Detect unused recursive parameters #19

Open jfmengels opened 3 years ago

jfmengels commented 3 years ago

What the rule should do:

Detect parameters of recursive function that are only used for passing it to the function again.

What problems does it solve:

This would help remove the argument and simplify both the recursive function and its call sites.

Example of things the rule would report:

recursive unusedValue list =
  case list of
    [] -> 1
    x :: xs -> x + recursive unusedValue xs

In the case above, unusedValue is marked as used by NoUnused.Variables because it is used as an argument of recursive. But we never use the value anywhere else, meaning it serves no purpose.

We can report the same thing even if different values are passed in some cases.

recursive unusedValue list =
  case list of
    [] -> 1
    x1 :: x2 :: xs -> x1 + recursive x2 xs
    x :: xs -> x + recursive unusedValue xs

In the example above, the value of unusedValue may change, but we never use it anywhere.

Slightly more advanced:

recursive unusedValue list =
  case list of
    [] -> 1
    x :: xs -> x + recursive (unusedValue - 1) xs

For this one, it is used in an expression, but that expression ultimately ends up only being used as the same argument for recursive, meaning whatever the value may turn out to be, it will not serve any purpose.

To go one step further, we could detect let declarations

recursive unusedValue list =
  case list of
    [] -> 1
    x :: xs ->
      let value = unusedValue - 1
      in x + recursive value xs

And also pipeline usage (note that I've reversed arguments)

recursive list unusedValue =
  case list of
    [] -> 1
    x :: xs -> unusedValue |> recursive xs

Example of things the rule would not report:

recursive accumulator list =
  case list of
    [] -> accumulator
    x :: xs -> recursive (accumulator + x) xs

When (not) to enable this rule:

:man_shrugging:

I am looking for:

miniBill commented 3 years ago

Something something mark arguments has having an impact on flow something something fixpoint?

jfmengels commented 2 months ago

Most of these have been implemented a while ago. Only the let declaration case hasn't:

recursive unusedValue list =
  case list of
    [] -> 1
    x :: xs ->
      let value = unusedValue - 1
      in x + recursive value xs

This one would be the most complex because as @miniBill mentioned, this will likely need a bit more flow-like analysis.