Credence.Pattern.NoSortThenAt
(credence v0.7.0)
Copy Markdown
Performance rule (fixable): Detects Enum.sort |> Enum.at(index) where the
index is a literal 0 or -1 and the sort direction can be statically
determined. These are replaced with Enum.min/Enum.max, avoiding the
O(n log n) sort entirely.
The fix uses the empty_fallback form Enum.min(c, fn -> nil end) rather than
bare Enum.min(c): Enum.at(sorted, 0 | -1) returns nil on an empty
collection, while bare Enum.min/1 raises Enum.EmptyError. The fallback
preserves the original nil-on-empty behaviour for every input (incl. [],
%{}, empty ranges/MapSets), so the rewrite needs no assumption.
Recognised direction forms
Enum.sort(nums) # default :asc
Enum.sort(nums, :asc) # explicit atom
Enum.sort(nums, :desc) # explicit atom
Enum.sort(nums, &>=/2) # capture → :desc
Enum.sort(nums, &<=/2) # capture → :asc
Enum.sort(nums, fn a, b -> a > b end) # anonymous comparator → :desc
Enum.sort(nums, fn a, b -> b > a end) # flipped comparator → :ascNot flagged
Other literal indices like Enum.sort(nums) |> Enum.at(3) are not flagged
because there is no standard-library O(n) replacement for kth-element access.
Variable indices such as Enum.sort(nums) |> Enum.at(k - 1) are not flagged
because they represent valid kth-element access that genuinely needs a sort.
Unresolvable directions such as Enum.sort(nums, dir) |> Enum.at(0) or
opaque comparators like Enum.sort(nums, &MyModule.compare/2) |> Enum.at(0)
are not flagged because we cannot determine whether the result is min or max.