Credence.Rule.NoLengthInGuard
(credence v0.3.2)
Copy Markdown
Performance rule: Detects the use of length/1 inside guard clauses (when)
in cases that cannot be automatically rewritten as pattern matches.
length/1 traverses the entire list to compute its size, making it O(n).
When placed in a guard, this cost is paid on every function call attempt,
and the list is almost always traversed again inside the function body.
Note: simple non-empty checks (length(list) > 0) and exact-size checks
(length(list) == N for N in 1..5) are handled by the LengthGuardToPattern
rule, which can auto-fix them into pattern matches.
Bad
def kth_largest(nums, k) when k <= length(nums) do
Enum.sort(nums, :desc) |> Enum.at(k - 1)
endGood
def kth_largest(nums, k) do
if k > length(nums), do: raise(ArgumentError, "k out of bounds")
Enum.sort(nums, :desc) |> Enum.at(k - 1)
endFor bounds checks, moving the validation into the function body avoids redundant traversals when the guard fails and another clause is tried.