Credence.Rule.NoTakeWhileLengthCheck (credence v0.3.1)

Copy Markdown

Detects Enum.take_while/2 piped into length/1 or Enum.count/1, which materializes an intermediate list only to count it.

Why this matters

LLMs generate this pattern when they think procedurally: "keep going while the condition holds, then check how far I got." The idiomatic Elixir approach depends on intent:

# Flagged — materializes a list just to count it
0..(half - 1)
|> Enum.take_while(fn i ->
  Enum.at(graphemes, start + i) == Enum.at(graphemes, start + len - 1 - i)
end)
|> length() == half

# If checking "did all pass?" → use Enum.all?/2
Enum.all?(0..(half - 1), fn i -> ... end)

# If counting consecutive matches → use Enum.reduce_while/3
Enum.reduce_while(range, 0, fn i, count ->
  if condition, do: {:cont, count + 1}, else: {:halt, count}
end)

Enum.take_while |> length always allocates a throwaway list. Enum.all? and Enum.reduce_while do not.

Flagged patterns

  • Enum.take_while(enum, fun) |> length()
  • Enum.take_while(enum, fun) |> Enum.count()
  • length(Enum.take_while(enum, fun))
  • Enum.count(Enum.take_while(enum, fun))
  • enum |> Enum.take_while(fun) |> length()