Skip to main content

🍬Syntactic sugar, diabetes alert🚨

• 7 min read

Older Article

This article was published 7 years ago. Some information may be outdated or no longer applicable.

Let’s find out how to keep your sugar balanced, shall we?

Syntactic sugar? No, it’s syntactic SUGAR!

Quick definition check:

Syntactic sugar is a syntax aimed to express the same code command in different and mostly better ways, in the same language.

For example:

  • a Array.prototype.filter is an alternative to forEach loop for filtering out an array according to a specific condition, and
  • i++ instead of i = i + 1
  • Or for is an alternative to while for the same purpose.

for loop is just syntactic sugar for while loop So is it JUST syntactic sugar? No. Syntactic sugar is more like *A**lternative**G**ood* syntax that’s meant to empower your code with *S**implicity*, *U**sability,* and make your code more *R**eadable*.

I like to remember it as the SUGAR rule.

Keep the SUGAR on because…

KISS works well with SUGAR

Look at this code:

//Before syntactic sugar
const result = [];

for (let i = 0; i < data.length; i++) {
  const x = data[i];

  if (x % 2 === 0) {
    result.push(x);
  }
}

Swap in the syntactic sugar filter, refactor properly, and you get this:

//After
const isEven = (number) => number % 2 === 0;
const result = data.filter(isEven);

Shorter, more concise and easier to read.

When SUGAR’s in good use, it’s extremely sweet and harmless

If you wield syntactic sugar correctly, you can dodge silly but annoying JavaScript traps. Take the Deadpool BaNaNa trap, caused by typing too many + to compute strings from other strings and variables: Deadpool banana JS trap With the magic of string template:

const banana = `ba${fillme}a`;

Usability at its best.

SUGAR isn’t only about less code, it’s also about efficiency

Think code writing efficiency, and relative performance. We all know [[]](https://medium.com/front-end-weekly/es6-set-vs-array-what-and-when-efc055655e1a) is a better performance choice compared to [new Array()](https://medium.com/front-end-weekly/es6-set-vs-array-what-and-when-efc055655e1a). Similarly with [{}](https://medium.com/front-end-weekly/es6-map-vs-object-what-and-when-b80621932373) instead of [new Object()](https://medium.com/front-end-weekly/es6-map-vs-object-what-and-when-b80621932373) or even [Object.create()](https://medium.com/front-end-weekly/es6-map-vs-object-what-and-when-b80621932373).

But note that performance efficiency *really***differs****per use case**.

And that’s when SUGAR flashes the warning sign.

Beware of JavaScript Diabetes

Everything has a limit before it becomes unbearable. Too much salt costs you your blood pressure. Too much protein causes indigestion. You need them, but in the right amount.

Same goes for syntactic sugar. It’s sweet, easy to reach for, so we developers grab it whenever we can (who wouldn’t love the easy path?). Sometimes without considering the negative effects. Because as long as it fits KISS, it’s good.

Is it? Absolutely not.

Less code !== More readability

Look at this: Only 2 to 3 lines of code. Concise and short.

But can you tell straight away what this block does? If you’re familiar with the problem it’s solving, sure. Not too hard.

(It’s for flattening an array, in case you’re curious.)

But for a first timer, it’s a wall.

Readable? Not really.

... operator is another example. Lovely, but also hard to interpret. The fact that it can be the **spread** operator or the **rest** parameter confuses many developers, especially when both appear in the same context as above.

*Your code needs to be **clear** and direct before everything else, for the sake of the next developer. *Without readability, your beloved syntax is no longer syntactic SUGAR.

Concise code !== Better performance

Less code means a lighter JS file, yes. But it doesn’t necessarily make the performance better: This function, theoretically (without considering the inner loop combinations.map()) takes O(n). Linear time. Should be good, right? But that’s just theory.

Why? Because:

  1. maploops through the original array, *creates***new** array based on it and *returns* the new array. New resource allocated. Same goes for filter, reverse, etc.
  2. reduce also needs to loop through the new array again, and returns a reduced value based on that array with a calculation formula passed.
  3. Each of these calls runs much slower than the original for loop, regardless how optimised the JS profiler is.
  4. JavaScript is single-threaded. While it’s in a loop, the browser technically pauses and *waits for the iteration *to complete before moving on. The bigger the array, the more logic to execute, the longer the wait. Users start seeing the browser “freeze”. Linear time doesn’t really apply here.
  5. Chaining calls like map and reduce makes things worse, not better (the browser **needs** to “freeze” for *map* to complete, then **again** for *reduce*, and so on).
  6. for loops don’t need syntactic sugar that badly. You can rewrite the above code using for and still maintain KISS with efficiency (both in resource allocation and performance).

The syntactic version runs way slower than the classic [for](http://bit.ly/map-reduce-for-benchmark) in a performance test, despite the same time efficiency (O(n²)).

It’s O(n) but NOT always O(n). Be careful. Sometimes the classic for loop wins. Period.

Browser.support(syntactic sugar)?

Not all syntactic sugar is supported in every browser. That’s why we need Babel (for instance) to make it work. Remember our little friend IE (or even Safari 9+?). Some ES6 syntactic sugar like ... and for..of won’t be supported, and suddenly your sweet, clean code which originally looked like this:

const sumUp = (...numbers) => {
  let sum = 0;
  for (const number of numbers) {
    sum += number;
  }
  return sum;
};

After going through Babel’s compiler, becomes (sort of):

var sumUp = function sumUp() {
  for (
    var _len = arguments.length, numbers = Array(_len), _key = 0;
    _key < _len;
    _key++
  ) {
    numbers[_key] = arguments[_key];
  }
  var sum = 0;
  for (
    var _iterator = numbers,
      _isArray = Array.isArray(_iterator),
      _i = 0,
      _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();
    ;

  ) {
    var _ref;
    if (_isArray) {
      if (_i >= _iterator.length) break;
      _ref = _iterator[_i++];
    } else {
      _i = _iterator.next();
      if (_i.done) break;
      _ref = _i.value;
    }
    var number = _ref;
    sum += number;
  }
  return sum;
};

Suddenly not that efficient anymore.

As long as your users still run certain browsers, your code needs to work on them. Before dropping a new syntactic sugar into your code, **read the documentation first**.

Being extra careful with new syntax is always a good habit.

Conclusion

Syntactic SUGAR is good (and totally recommended) to use, as long as it travels with CARE:

  • C stands for Check your use case, the syntax pitfalls, and make sure your new code meshes well with your existing logic.
  • A stands for Ask for review (code review, architecture review, etc). The best person to ask for a code review, to my opinion, is a junior developer or someone new to the team. An expert eye is great, but a junior or new team member brings a fresh look and can tell you straight away whether your code is easy to follow. An extra pair of eyes never hurts.
  • R stands for Read the documentation, read others’ code and remarks. Make your code readable by providing a README file or explanation comments. But only when needed, because…
  • E stands for Explicit. Your code should stand on its own. Split the logic into smaller parts if it helps others understand. Good code means fewer (or no) comments. Why would you need comments if your code is readable and explicit enough?

Code responsibly. Think about efficiency, maintainability, readability for other developers. As long as you know your sugar limit, your syntactic sugar will stay sweet and there won’t be any risk of diabetes.

Disclaimer: This article is based on my talk on the same subject in CityJS Conf 2019 last May. A recorded version is available on Youtube. Enjoy and happy coding everyone!

If you’d like to catch up with me sometimes, follow me on Twitter | Facebook or simply visit my portfolio website.