A linguistic antipattern is a place in the code where the naming implies that it does one thing and in fact, it does something different. For example, the method void isEmpty() suggests that it will return a boolean reflecting whether or not the object is empty, yet the method does not return anything.

“Whereas ‘design’ antipatterns represent recurring, poor design choices, linguistic antipatterns represent recurring, poor naming and commenting choices.”1

Studies have shown2 that the presence of linguistic antipatterns results in higher cognitive load for anyone attempting to read the code. They also show that we are more likely to “chunk” the information incorrectly2, making it simultaneously more difficult to understand and more likely to make a mistake.

These are worth identifying and fixing in your codebase.

A 2013 paper1 listed 17 different kinds of linguistic antipatterns, across these 6 groupings.

  1. Does more than it says
  2. Says more than it does
  3. Does the opposite
  4. Contains more than it says
  5. Says more than it contains
  6. Contains the opposite

See also: https://www.linguistic-antipatterns.com/, which groups the same items in a different way.

1. Does more than it says

“Get” - more than an accessor
A getter that has side effects
“Is” returns more than a Boolean
Example: Customer isAvailable() which implies that it will only return true or false and then returns a Customer object.
“Set” method returns
Example: Customer setName(String name) which is unexpectedly returning a value.
Expecting but not getting a single instance
Example: List<Customer> getCustomer() which implies that it’s returning a single customer and then returns a list of them.

2. Says more than it does

Not implemented condition
Name implies that there is conditional logic while no conditions are checked. Example: A method refreshIfStale() that always refreshes, whether or not the data is stale.
Validation method does not confirm
Name implies that something will happen in certain situations. Example: A comment like “This will return an empty list if no elements found” when it doesn’t actually check for an empty list.
“Get” method does not return
Example: void getName() implies that it will return a name but it returns nothing.
Not answered question
Example: void isEmpty() implies that it will return a boolean but it returns nothing.
Transform method does not return
Name implies that some form of transformation will happen and yet nothing is returned. Example: void convertToRoman(int number) which implies that it will return a roman version of the number.
Expecting but not getting a collection
Name implies that a collection will be returned, while sometimes it returns nothing or perhaps a single value.

3. Does the opposite

Method name and return type are opposite
Example: int getCustomer() which implies that you’ll get a Customer object but it returns an int.
Method signature and comment are opposite
The code and comment are out of sync

4. Contains more than it says

Says one but contains many
Example: List<Customer> getCustomer()
Name suggests Boolean but type does not
Example: int[] isReached

5. Says more than it contains

Says many but contains one
Example: boolean stats = true

6. Contains the opposite

Contains the opposite
Example: MAssociationEnd start = null ; where the type implies it’s an end but the variable name implies it’s a start.
Attribute signature and comment are opposite
Example: The comment suggests we need to pass in an id, whereas the code wants us to pass in a Customer object.
  1. Arnaoudova, Venera & Di Penta, Massimiliano & Antoniol, Giuliano & Guéhéneuc, Yann-Gaël. (2013). A New Family of Software Anti-Patterns: Linguistic Anti-Patterns. Proceedings of the European Conference on Software Maintenance and Reengineering, CSMR. 10.1109/CSMR.2013.28.  2

  2. The Programmer’s Brain: What every programmer needs to know about cognition by Felienne Hermans  2