- The paper introduces a systematic grey literature review to uncover both traditional and unique Elixir code smells by analyzing 17 relevant documents.
- It highlights that while classic smells like duplicated code and long functions are discussed, Elixir-specific issues such as complex multi-clause functions remain under-detected.
- The study reveals that Credo detects only a subset of these smells, indicating a need for enhanced static analysis tools in Elixir projects.
This paper explores the concept of code smells within the context of the Elixir programming language (2203.08877). Recognizing Elixir's growing popularity and the lack of research on its internal code quality, the authors conducted a grey literature review (analyzing blogs, forums, etc.) to identify code structures considered problematic by the Elixir developer community.
Methodology
The paper aimed to answer three research questions:
- Do Elixir developers discuss traditional code smells (as defined by Fowler and Beck)?
- Do Elixir developers discuss other, potentially Elixir-specific, smells?
- Does Credo, a popular Elixir static analysis tool, detect these smells?
A systematic process was followed:
- Search Query: A Google search query was crafted using "Elixir" combined with various terms for code smells ("code smell", "bad practice", "anti-pattern", etc.).
- Document Selection: The top 60 search results were initially considered, and after manual filtering by the authors for relevance, 17 documents were selected for in-depth analysis.
- Data Extraction: Sentences discussing code smells were extracted and validated by both authors.
Key Findings
Traditional Code Smells in Elixir (RQ1):
The review found discussions related to 11 of the 22 classic code smells identified by Fowler and Beck. The smells discussed, in order of frequency found in the documents, were:
- Comments
- Long Parameter List
- Feature Envy
- Shotgun Surgery
- Duplicated Code
- Long Function
- Large Class (likely referring to Large Module in Elixir context)
- Inappropriate Intimacy
- Divergent Change
- Speculative Generalization
- Primitive Obsession
Example: The "Comments" smell was the most frequently discussed. The argument presented in the reviewed literature is that extensive comments explaining what code does are often unnecessary in Elixir. Instead, developers should leverage doctest
for documentation, which provides usage examples that can also be run as tests and accessed via the IEx shell.
Elixir-Specific Code Smells (RQ2):
The authors identified 18 novel code smells specific to Elixir's features and paradigms. These were categorized into:
- Design-related smells (10): More complex issues affecting broader design aspects.
- Example: Complex multi-clause function: Abusing Elixir's multi-clause function heads with excessive pattern matching and guard clauses, making the function hard to understand and reason about.
- Other examples: GenServer Envy, Agent Obsession, Unsupervised process, Large messages between processes, Complex API error handling, Exceptions for control-flow, Untested polymorphic behavior, Code organization by process, Data manipulation by migration.
- Low-level concerns smells (8): Simpler issues affecting smaller code segments.
- Example: Working with invalid data: Functions not validating input parameters close to the source (e.g., user input), leading to potential errors deep within the application logic, making debugging difficult.
- Other examples: Map/struct dynamic access, Unplanned value extraction, Modules with identical names, Unnecessary macro, App configuration for code libs, Compile-time app configuration, Dependency with "use" when an "import" is enough.
A full list and descriptions are available in the paper's Table II and the associated GitHub repository mentioned.
Tool Detection (RQ3):
The authors investigated Credo (v1.6.2), a widely used static analysis tool for Elixir, to see if it detects the identified smells.
- Finding: Credo offers limited coverage for the smells found in the grey literature.
- Detected Traditional Smells: Duplicated Code, Long Parameter List.
- Detected Elixir-Specific Smells: Compile-time app configuration.
- Implication: There is a significant opportunity to enhance Credo or develop new tools to automatically detect these identified smells in Elixir projects.
Practical Implications for Developers
- Awareness: The lists of traditional and Elixir-specific smells provide developers with a vocabulary and checklist to identify potential quality issues in their Elixir codebases.
- Refactoring Guidance: Understanding these smells can guide refactoring efforts to improve maintainability, readability, and robustness. For instance, recognizing a "Complex multi-clause function" might prompt breaking it down into smaller, more focused functions. Identifying "Working with invalid data" suggests adding input validation closer to the system's boundaries.
- Tooling Gap: Developers should be aware that current static analysis tools like Credo might not catch many of these potential issues, requiring more manual code reviews and vigilance.
doctest
Usage: The discussion around the "Comments" smell emphasizes the idiomatic Elixir practice of using doctest
for function documentation and examples over traditional code comments explaining implementation details.
- Process Management: Smells like "GenServer Envy," "Agent Obsession," and "Unsupervised process" highlight the need for careful design when working with Elixir's concurrency primitives (Processes, Tasks, Agents, GenServers) and supervision trees.
The paper concludes by stating these are early results and plans future work, including mining open-source projects and surveying developers to further validate and expand the smell catalog, and potentially developing detection tools.