D is a general-purpose programming language with static typing, systems-level access, and C-like syntax. It combines the performance and safety of compiled languages with the expressive power and convenience of modern languages.
D Anti-Patterns Overview
Excessive Use of Runtime Type Information (RTTI)
cast
operations. This approach is slow, error-prone, and leads to brittle code. Instead, use polymorphism, interfaces, or templates to handle different types in a more type-safe and efficient manner.Not Using @safe, @trusted, and @system Properly
@safe
, @trusted
, and @system
) to clearly indicate the safety level of your code. Mark unsafe code as @system
, wrap it with carefully reviewed @trusted
functions, and aim to make most of your codebase @safe
. This helps prevent memory safety issues and makes your code more robust.Excessive Use of Shared Mutable State
Not Using UFCS (Uniform Function Call Syntax)
Not Using Range-Based Algorithms
std.algorithm
and related modules instead of manual iteration and transformation. Range-based algorithms are more expressive, less error-prone, and often more efficient than manual loops.Excessive Use of Dynamic Arrays
std.experimental.allocator
to have more control over memory management.Not Using Contract Programming
in
and out
blocks) to specify preconditions and postconditions for functions. Contracts make your code more robust by clearly documenting and enforcing expectations about inputs and outputs.Not Using Proper Error Handling
std.typecons
types like Nullable
or Tuple
to represent success/failure states when appropriate, especially for operations that might reasonably fail.Not Using Templates Effectively
Not Using Proper Memory Management
scope
statement, or RAII (Resource Acquisition Is Initialization) patterns to ensure resources are properly cleaned up.Not Using Immutability
const
, immutable
) to make your code more robust and easier to reason about. Mark function parameters as const
when they shouldn’t be modified, and use immutable
for data that should never change.Not Using Proper Modules
Not Using Proper Documentation
Not Using Unit Tests
unittest
blocks. Unit tests help ensure your code works correctly and continues to work as you make changes. They also serve as executable documentation showing how your code is intended to be used.Not Using Properties
Not Using Proper Concurrency Patterns
std.concurrency
over shared mutable state. When shared state is necessary, use proper synchronization mechanisms like atomic operations, mutexes, or reader-writer locks.