Skip to main content
Scala, with its blend of object-oriented and functional programming, has several common anti-patterns that can lead to performance issues, code maintainability problems, and bugs. Here are the most important anti-patterns to avoid when writing Scala code.
Never call .get on an Option without first checking if it contains a value, as it will throw a NoSuchElementException if the option is None.
Avoid using null in Scala. Instead, use Option[T] to represent the presence or absence of a value.
Don’t ignore return values, especially from pure functions. Either use them or explicitly discard them with val _ = ....
Minimize the use of var in favor of val and functional transformations to make code more predictable and easier to reason about.
Avoid returning Any as it bypasses the type system. Use algebraic data types (ADTs) or sealed traits instead.
Don’t use exceptions for expected failure cases. Use Option, Either, or Try to represent operations that might fail.
Use case classes for data objects to automatically get useful methods like equals, hashCode, toString, and copy.
Use pattern matching instead of type checks and casts for more expressive and safer code.
Use implicits judiciously. They can make code harder to understand and debug when overused.
Avoid excessive nesting. Use flatMap/map chains or for-comprehensions for more readable code.
Always properly close resources using try-finally blocks or utilities like Using (Scala 2.13+).
Favor composition over inheritance and consider functional programming approaches like type classes.
Prefer immutable collections and transformations over mutable state.
Use Either, Option, or Try for error handling instead of throwing exceptions.
Use lazy val for expensive computations that might not be needed, and consider using streams or views for lazy collection processing.
Avoid blocking on futures. Compose them using map, flatMap, or for-comprehensions.
Use consistent functional error handling with Try, Either, or Option.
Use proper type parameters instead of Any to leverage the type system.
Use the rich collection API instead of reinventing common operations.
Use string interpolation (s"", f"", raw"") instead of concatenation for better readability.
Keep case classes immutable and use copy for creating modified instances.