Semicolon Rules in JavaScript are weird...
Tags: javascript
Published: 2018-09-17 18:22:34

---
title: Semicolon Rules in JavaScript are weird...
published: true
description: Usually the quirks in JavaScript are edge cases, but this is a pretty common case where I don't know what's happening.
tags: javascript
---

I'd like to preface this with that I really do like JavaScript. It has quirks, although _most_ of them are edge cases that you won't encounter. But I just found one that I'm still confused, and I'd rather not look up the JavaScript spec just to figure this out...

My original function:
```js
function cubicBezier(x, u0, u1, u2, u3) {
    return
        u0 * (1 - x) * (1 - x) * (1 - x) +
        u1 * (1 - x) * (1 - x) * x +
        u2 * (1 - x) * x * x +
        u3 * x * x * x;
}
```

Some of you seasoned JavaScript experts might see this and go "it will always return undefined", because the `return` is interpreted as `return;` since nothing else follows. This got me wondering about semicolon rules in JavaScript.

My favorite programming language is Go, which also has optional semicolons. The semicolon rules are extremely simple in Go:

> When the input is broken into tokens, a semicolon is automatically inserted into the token stream immediately after a line's final token if that token is
> * an identifier
> * an integer, floating-point, imaginary, rune, or string literal
> * one of the keywords break, continue, fallthrough, or return
> * one of the operators and punctuation ++, --, ), ], or }

By the way, Go's rules can be interpreted a lot easier like this:

> A semicolon is placed if the line ends with:
> * a letter or number
> * a closing punctuation mark (aka `]`, `)`, `}`, and closing `"`/`'`)
> * `++` or `--`

I thought that JavaScript Semicolon rules were just as simple as Go's when I saw the function return undefined. After all, nothing appears after the `return`, so a semicolon was placed afterward. It is that simple right?

## Well, I looked into it further.

So I made a few functions for adding 1 to an integer to see what JavaScript did.

```js
function addOneNormal(x) {
    return x + 1
}

function addOneWeird(x) {
    return x
        +1
}

function addOneUndefined(x) {
    return
        x + 1
}
```

We know what `addOneNormal` and `addOneUndefined` end up being. `addOneNormal` adds one to `x`, and `addOneUndefined` hits the `return` and returns undefined. So what does `addOneWeird` do?

_(sidenote: in Go, this is very simple, as `return x` ends with a letter, so a semicolon is placed. The next line, `+1`, results in a compile error as `+1` is not being assigned to anything)_

Well, some people would expect it to be the same as `return x + 1;`, although some people (like me) see it as `return x; +1;`, where the `+1` is a `1` with a unary plus operator before it.

## The result

So what was the result? `addOneWeird(5) => 6`. It added 1 successfully. That's weird... isn't it? That statement looked at the next line, even though a bare `return` didn't.

Unfortunately these rules cannot be made more consistent, as backward-compatibility is a requirement in JavaScript.

Anyway, could someone explain why the `+` operator ended up being interpreted as a binary plus rather than a unary plus in this case? If the `addOneUndefined` function resulted in `undefined`, It seems more logical for`addOneWeird` to be interpreted as `return x; +1;`.