Credence.Pattern.NoEnumAtNegativeIndex
(credence v0.4.1)
Copy Markdown
Detects Enum.at/2 called with a negative integer literal index.
Elixir lists are singly-linked, so Enum.at(list, -1) traverses the
entire list to reach the last element. Calling Enum.at(list, -2) does
the same to reach the second-to-last, and so on — each call pays O(n).
When multiple negative-index accesses target the same list, the cost multiplies unnecessarily.
Bad
last = Enum.at(sorted_list, -1)
one_before_last = Enum.at(sorted_list, -2)
value = sorted |> Enum.at(-1)Good
# For multiple tail elements, reverse once and pattern-match
sorted_list_reversed = Enum.reverse(sorted_list)
[last, one_before_last | _] = sorted_list_reversed
# For a single last element, use List.last/1
value = List.last(sorted)Auto-fix
When multiple assignments access the same list variable with negative
indices within the same function, the fixer groups them into a single
Enum.reverse/1 call and a pattern match (up to depth 5).
A lone Enum.at(x, -1) is rewritten to List.last(x).
A lone Enum.at(x, -N) where N > 1 is rewritten to a reverse +
pattern match on a single variable.