Credence.Pattern.NoListDuplicateJoin
(credence v0.7.1)
Copy Markdown
Detects List.duplicate(string_literal, n) |> Enum.join() (and the nested
Enum.join(List.duplicate(string_literal, n))) and suggests
String.duplicate/2 instead.
When the goal is to repeat a string N times, String.duplicate/2 is the
idiomatic function. LLMs often produce List.duplicate/2 followed by
Enum.join/1 to achieve the same result, which is less readable and
allocates an intermediate list.
Safe core: string-literal first argument only
Enum.join/1 calls to_string/1 on each element, so
Enum.join(List.duplicate(value, n)) works for any value — e.g.
Enum.join(List.duplicate(7, 3)) == "777". String.duplicate/2, by contrast,
requires a binary and raises on anything else (String.duplicate(7, 3)
raises ArgumentError). The two are only guaranteed to agree when the
duplicated value is already a string.
Since a non-literal first argument (a variable, a function call) cannot be
proven to be a binary syntactically, this rule fires only when the
duplicated value is a string literal, where the rewrite is exactly
behaviour-preserving. The n argument may be anything: both List.duplicate/2
and String.duplicate/2 require a non-negative integer and raise identically
otherwise.
Bad
List.duplicate("=", n) |> Enum.join()
Enum.join(List.duplicate("=", n))Good
String.duplicate("=", n)