DEV Community

Cover image for Code Smell 297 - Syntactic Noise
Maxi Contieri
Maxi Contieri

Posted on • Edited on

2 1 1 1 1

Code Smell 297 - Syntactic Noise

Your code shouldn't look like alien hieroglyphics

TL;DR: Too many cryptic symbols make your code hard to understand and maintain.

Problems 😔

Solutions 😃

  1. Avoid language clever hacks
  2. Prefer meaningful variable names
  3. Extract complex expressions
  4. Use language features wisely
  5. Limit expression complexity

Refactorings ⚙️

Context 💬

Syntactic noise refers to code constructs that don't directly map to real-world concepts.

While symbols like '{}' are valid syntax in many programming languages, excessive use creates code that looks like abstract art rather than a solution to a problem.

When you pack too many operators, brackets, and special characters into a single expression, you force readers to mentally parse complex syntax before understanding what the code does.

This disconnect between symbols and real-world meaning makes your code harder to understand, debug, and maintain.

Think of your code as a form of communication with other developers (and your future self).

Just as excessive punctuation!!! makes text!!?!? hard to read!!!

Excessive syntactic noise creates similar barriers in code.

Sample Code 📖

Wrong ❌

[](){}

/* This valid lambda function:

Captures no variables.
Takes no arguments.
Performs no actions.

[]: This is the capture clause. 
It specifies which variables from the surrounding scope
are accessible inside the lambda function. 
An empty capture clause [] means the lambda
*does not capture* any variables from the surrounding scope.

(): This is the parameter list. 
It defines the arguments the lambda function accepts. 
An empty () means the lambda takes *no parameters*.

{}: This is the function body. 
It contains the code that the lambda executes when called. 
An empty {} means the lambda has no operations 
to perform—it does nothing.

*/
Enter fullscreen mode Exit fullscreen mode
const result = arr.filter(x => x !== null && x !== undefined)
  .map((y) => ({ val: y.value, meta: 
    y.meta ? y.meta : {default: true}}))
  .reduce((acc, {val, meta}) => 
    meta.default ? acc : [...acc, 
      {processed: val * 2, origin: meta}], [])
  .some(({processed}) => processed > 10 && processed < 50);
Enter fullscreen mode Exit fullscreen mode

Right 👉

function isNotNull(x) {
  return x !== null && x !== undefined
  // Another code smell here
}

function mapToValueAndMeta(y) {
  const meta = y.meta ? y.meta : { default: true }
  return { val: y.value, meta }
}

function reduceToProcessedList(acc, { val, meta }) {
  if (meta.default) {
    return acc
  }
  return [...acc, { processed: val * 2, origin: meta }]
}

function isProcessedInRange({ processed }) {
  return processed > 10 && processed < 50
}

// This is more declarative but far from 
// Domian business and too generic
const filtered = arr.filter(isNotNull)
const mapped = filtered.map(mapToValueAndMeta)
const processedList = mapped.reduce(reduceToProcessedList, [])
const result = processedList.some(isProcessedInRange)
Enter fullscreen mode Exit fullscreen mode

Detection 🔍

[X] Semi-Automatic

You can detect syntactic noise by looking for lines with multiple nesting levels of brackets, parentheses, or braces, chained operations that stretch across numerous lines, and expressions that make you pause to count opening and closing symbols.

Code that requires horizontal scrolling due to symbol density is another red flag, multiple ternary operators in a single expression, and nested arrow functions with implicit returns.

Modern IDEs and linters can help identify overly complex expressions.

ESLint rules like complexity and max-depth flag code with too many nested constructs.

The "cognitive complexity" metric in SonarQube also helps identify hard-to-understand code.

Exceptions 🛑

  • Code Optimized by Machines

Tags 🏷️

  • Complexity

Level 🔋

[x] Intermediate

Why the Bijection Is Important 🗺️

Code should map one-to-one with the real-world concepts it represents.

Each variable, function, and expression should correspond to something tangible in your problem domain.

When you clutter code with excessive syntax that doesn't represent real-world entities, you create a disconnect between the problem and solution.

Remember that code is written once but read many times.

By maintaining a clear bijection between code constructs and real-world concepts, you create software that stays maintainable throughout its lifecycle.

AI Generation 🤖

AI code generators sometimes create syntactic noise.

When you ask for code with minimal prompt guidance, AI tools frequently optimize for brevity over readability, packing multiple operations into dense one-liners.

This approach produces "clever" but hard-to-maintain code with chained methods, nested ternaries, and complex expressions.

Modern AI generators like GPT models can also create exceptionally dense code when asked to solve problems in minimal lines, inadvertently producing syntactically noisy solutions.

They may not recognize when code crosses the readability threshold without specific instructions to prioritize clarity over conciseness.

Please don't prompt this.

AI Detection 🥃

AI tools can help detect and fix syntactic noise with appropriate prompting.

If you use instructions like "refactor for readability" or "simplify this expression," you will get cleaner code.

Try Them! 🛠

Remember: AI Assistants make lots of mistakes

Suggested Prompt: Remove the syntactic noise and make it more declarative

Conclusion 🏁

Syntactic noise is like static interference in communication—technically valid, but gets in the way of understanding.

When you prioritize clear code over clever one-liners, you create software that's easier to understand, debug, and maintain.

Next time you're tempted to pack multiple operations into a dense expression, remember that you're not just writing for the computer—you're writing for people.

Break complex operations into named steps that reflect real-world concepts, and your code will tell a story that everyone can follow.

Relations 👩‍❤️‍💋‍👨

More Information 📕

Martin Fowler's blog

Wikipedia

Disclaimer 📘

Code Smells are my opinion.

Credits 🙏

Photo by Elyas Pasban on Unsplash


The function of good software is to make the complex appear simple

Graciano Cruz


This article is part of the CodeSmell Series.

Sentry image

Make it make sense

Only get the information you need to fix your code that’s broken with Sentry.

Start debugging →

Top comments (0)

Scale globally with MongoDB Atlas. Try free.

Scale globally with MongoDB Atlas. Try free.

MongoDB Atlas is the global, multi-cloud database for modern apps trusted by developers and enterprises to build, scale, and run cutting-edge applications, with automated scaling, built-in security, and 125+ cloud regions.

Learn More

👋 Kindness is contagious

Dive into this thoughtful piece, beloved in the supportive DEV Community. Coders of every background are invited to share and elevate our collective know-how.

A sincere "thank you" can brighten someone's day—leave your appreciation below!

On DEV, sharing knowledge smooths our journey and tightens our community bonds. Enjoyed this? A quick thank you to the author is hugely appreciated.

Okay