None
instead of Some(null)
SC-A1002It is more idiomatic in scala to use Option
, i.e. Some
and None
instead of null
. Using Some(null)
instead of None
defeats the entire purpose of Option
. However, there might be certain scenarios where this is a legitimate approach, such as when dealing with Java-based libraries, to improve compatibility.
Carefully consider whether using Option
with null
is necessary before doing so.
It is suggested that you do not use wildcards in the import statements. This defeats the entire purpose of properly packing the code into different classes and packages. Rather, import only what you need.
Scala allows you to import entities from same package in separate statements. However, it is generally recommended that you group such imports together. Doing so makes the code more readable and easier to navigate.
Enum values are always accessed using the enum's name. Therefore, it does not make any sense to prefix the enum's values with the enum's name. Doing so is repetitive and adds noise to the code.
infix
modifier is redundant for symbol-like methods SC-R1089infix
modifier is a new modifier introduced in Scala 3 that can be applied to methods.
This allows you to use the method as an infix operation. However, symbol-like methods are by default allowed in infix operations and do not require this modifier.
Since this makes the modifier redundant, it is recommended that you drop the said modifier for such methods.
catch
clause SC-W1089Cases within the catch
clause potentially allow you to recover from an error within your application.
Because you have Error
-s apart from Exception
-s under Throwable
-s, you may end up trying to recover from a point of no return such as
running under extremely low memory limits. Therefore, it is always a good practice to specify types.
length
-like property is compared against values which always evaluate to the same result SC-W1091length
-like properties are usually used to "count" the number of elements.
For example, in the context of an array, length
tells us the number of elements in the array.
Comparing this property against 0
using the <
or >=
operators is meaningless and will always evaluate to false
and true
respectively.
This comparison is likely a mistake and should be rewritten meaningfully.
final
modifier is redundant for object
SC-R1053A class cannot extend an object thereby making the final
modifier redundant. It is therefore recommended that you drop the said modifier.
Option
should only return Some
or None
SC-T1005Methods with return type Option
should either return Some
if a suitable value exists or None
if not. Returning null
from such methods can have unintended side effects.
Default values are values that are used in case the user does not explicitly supply a value. It is always recommended that you place these default values at last. Placing them at the beginning or in the middle makes it difficult to skip them when invoking the method.
An enum
holds different members that map to different values. In most languages, it is usually expected that these members map to unique values. However, in this case, one or more members map to a value that was already associated with a different member. This could likely be a mistake and greatly affect your program's logic and behaviour. It is recommended that you review all the values associated with this enum's members.
inline
and tailrec
annotations results in a compile-time error in future Scala versions SC-W1088Any method that is annotated with both inline
and tailrec
annotations throw a compile time error in Scala 3 despite compiling and running fine in Scala 2. In case you wish to upgrade to Scala 3 in near future, it is recommended that you take another look at this method and either rewrite it appropriately or drop one of the two said annotations.
Scala allows you to inherit from scala.App
(which uses DelayedInit
) to set up a simple and small Main
program. However, since DelayedInit
is now deprecated, it is recommended that you define a suitable entry point of your own.
Unary methods in Scala are special methods that are used to define unary operators on types. Because unary operators do not take in any arguments and operate on a single entity, declarations of such operators should not define parameters, or have parentheses either.
Scala 2 used the syntax entity_:*
to define vararg splices. However, Scala 3 has changed this syntax to entity*
. While both kinds of syntax are valid in
Scala 3 for now, this behavior is likely to change in the near future. Consider migrating to the newer syntax as soon as possible.
as
keyword for import aliases SC-R1081Scala 2 used the =>
token in import aliases. However, Scala 3 has changed this syntax and now recommends that you use the as
keyword instead.
While both the syntaxes are valid in the present Scala 3 versions for now, it is likely going to change in the near future.
Consider migrating to the newer syntax as soon as possible.
if
statement where possible SC-R1082Instead of assigning values in the then and else clauses of an if
statement, consider using the if
statement itself as an expression.
This allows you to directly assign the returned value to a val
. This syntax is clear and simpler.
Exceptions usually follow the AbcDefException nomenclature. Some examples are - NullPointerException, RuntimeException, etc. This allows the person reading/viewing the code understand that the entity being dealt with is an Exception rather than having to rely on the context.
Classes that are either case
or that implement the unapply()
method allow you to utilize pattern matching. However, in this case, all the patterns specified in the pattern matching are wildcard patterns. Either this is a mistake or you meant to simply match a specific type. In the latter's case, consider using the syntax v: Tpe
.
Lambda expressions are anonymous functions that are not bound to any particular identifier and are extensively used in the standard and 3rd party libraries for operations such as filter
, map
, count
, etc. These expressions may take in one or more parameters just like normal methods. However, in this case, one of the parameters that the lambda depends on is unused. Either you meant to consume the said parameter or that the parameter is simply not required by design and can be omitted.