# Whitespace (newline) following return statement

**URL:** <https://es.discourse.group/t/whitespace-newline-following-return-statement/1818>\
**Category:** 💡 Ideas\
**Created:** [October 9, 2023, 4:40am UTC](https://es.discourse.group/t/whitespace-newline-following-return-statement/1818 "2023-10-09T04:40:36Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![zambetti](https://avatars.discourse-cdn.com/v4/letter/z/eb9ed0/32.png) [@zambetti](https://es.discourse.group/u/zambetti)\
**Post date:** [October 9, 2023, 4:40am UTC](https://es.discourse.group/t/whitespace-newline-following-return-statement/1818/1 "2023-10-09T04:40:36Z")

</div>

When returning an anonymous object from a function, a parse error results if the opening brace is not on the same line as the return statement; this is sensitivity to whitespace unecmascriptlike.

In the two functions below functionA() is fine, but functionB() results in "Uncaught SyntaxError: Unexpected token ':'"

It is [written in the specification](https://262.ecma-international.org/#prod-ReturnStatement) that a line terminator is not allowed after a return, but this strangely enforces a particular brace style for return statements that does not match what is allowed elsewhere, for example assignments.

```javascript
// OK
functionA()
{
    return {
        propertyA: true,
        propertyB: true
    };
}

// Not OK
function functionB()
{
    return
    {
        propertyA: true,
        propertyB: true
    };
}

// OK
var myobject =
{
    propertyA: true,
    propertyB: true
};

```

---

<div class="post-metadata">

**Author:** ![ljharb](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/ljharb/32/8_2.png) [@ljharb](https://es.discourse.group/u/ljharb)\
**Post date:** [October 9, 2023, 4:41am UTC](https://es.discourse.group/t/whitespace-newline-following-return-statement/1818/2 "2023-10-09T04:41:20Z")

</div>

It does indeed, which is why One True Brace Style is the preferred brace style in JS.

---

<div class="post-metadata">

**Author:** ![zambetti](https://avatars.discourse-cdn.com/v4/letter/z/eb9ed0/32.png) [@zambetti](https://es.discourse.group/u/zambetti)\
**Post date:** [October 9, 2023, 9:25am UTC](https://es.discourse.group/t/whitespace-newline-following-return-statement/1818/3 "2023-10-09T09:25:23Z")

</div>

Putting brace-style religions aside ... if you look at the examples above, do you agree that it is inconsistent that a line terminator is allowed in the other scenarios, but not when returning an object-literal?

---

<div class="post-metadata">

**Author:** ![ljharb](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/ljharb/32/8_2.png) [@ljharb](https://es.discourse.group/u/ljharb)\
**Post date:** [October 9, 2023, 3:17pm UTC](https://es.discourse.group/t/whitespace-newline-following-return-statement/1818/4 "2023-10-09T15:17:36Z")

</div>

Yes, ASI is very inconsistent in terms of intuition, which is also why the recommended style is to use semicolons (and a linter that checks them for you). However, such things can’t ever be changed or they’d break websites.

(OTBS: [https://en.wikipedia.org/wiki/Indent\_style#Variant:_1TBS_.28OTBS.29](https://en.wikipedia.org/wiki/Indent_style#Variant:_1TBS_.28OTBS.29) )

---

<div class="post-metadata">

**Author:** ![zambetti](https://avatars.discourse-cdn.com/v4/letter/z/eb9ed0/32.png) [@zambetti](https://es.discourse.group/u/zambetti)\
**Post date:** [October 9, 2023, 3:55pm UTC](https://es.discourse.group/t/whitespace-newline-following-return-statement/1818/5 "2023-10-09T15:55:12Z")

</div>

> [@ljharb](#):
>
> the recommended style is to use semicolons

Where in the examples above did I not use semicolons?

> [@ljharb](#):
>
> However, such things can’t ever be changed or they’d break websites.

Can you give a concrete example where allowing a line-terminator between the return keyword and an object literal would not be backwards compatible?

> [@ljharb](#):
>
> OTBS

Yes, I'm aware of OTBS/1TBS, it is just one style of many, hardly the 'one true' one. Regardless, ECMAscript does not require or enforce that one particular style. However, in this scenario, where a line-terminator is not accepted between a return and an opening brace of an object-literal, the language specification is (unusually) opinionated about style.

What I am raising for discussion, is this correctable inconsistency/opinionatedness in the language specification.

I am fairly certain that the grammar/specification could be updated to allow a line-terminator between the return keyword and an object literal while maintaining backwards compatibility with all existing programs. I am raising this question to the forum to understand if this is or is not the case.

---

<div class="post-metadata">

**Author:** ![ljharb](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/ljharb/32/8_2.png) [@ljharb](https://es.discourse.group/u/ljharb)\
**Post date:** [October 9, 2023, 4:11pm UTC](https://es.discourse.group/t/whitespace-newline-following-return-statement/1818/6 "2023-10-09T16:11:06Z")

</div>

No, it wouldn’t be possible to change any aspect of the grammar here; there are programs that depend on it.

---

<div class="post-metadata">

**Author:** ![zambetti](https://avatars.discourse-cdn.com/v4/letter/z/eb9ed0/32.png) [@zambetti](https://es.discourse.group/u/zambetti)\
**Post date:** [October 9, 2023, 4:17pm UTC](https://es.discourse.group/t/whitespace-newline-following-return-statement/1818/7 "2023-10-09T16:17:58Z")

</div>

> [@ljharb](#):
>
> there are programs that depend on it.

There are programs that depend on the absence of a line-terminator between the return keyword and the opening brace of an object-literal?

Can you provide a short code example of such a scenario?

> [@ljharb](#):
>
> No, it wouldn’t be possible to change any aspect of the grammar here

Surely you cannot be suggesting that the specification cannot be changed; the title of the document is ["ECMA-262, 14th edition, June 2023"](https://262.ecma-international.org/)

Or is this not the correct forum to suggest such changes?

---

<div class="post-metadata">

**Author:** ![ljharb](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/ljharb/32/8_2.png) [@ljharb](https://es.discourse.group/u/ljharb)\
**Post date:** [October 9, 2023, 5:51pm UTC](https://es.discourse.group/t/whitespace-newline-following-return-statement/1818/8 "2023-10-09T17:51:00Z")

</div>

All it would take is a program where that pattern _appears_, and code that expects the function to return undefined, and that program depends on that pattern. I expect it wouldn't take too long to find such code on github, let alone on npm, and I doubt browsers would have the risk appetite for such a change anyways.

The language almost never has _breaking_ changes; virtually all changes are additive. Breaking changes are only possible if they're web compatible, and something as fundamental as this is almost certainly not.

---

<div class="post-metadata">

**Author:** ![Josh-Cena](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/josh-cena/32/1408_2.png) [@Josh-Cena](https://es.discourse.group/u/Josh-Cena)\
**Post date:** [October 9, 2023, 8:18pm UTC](https://es.discourse.group/t/whitespace-newline-following-return-statement/1818/9 "2023-10-09T20:18:16Z")

</div>

A not-hard-to-imagine pattern is

```js
function foo() {
  if (condition())
    return
  function condition() {
  }
}

```

Which would now be a reference error.

---

<div class="post-metadata">

**Author:** ![mhofman](https://avatars.discourse-cdn.com/v4/letter/m/f14d63/32.png) [@mhofman](https://es.discourse.group/u/mhofman)\
**Post date:** [October 9, 2023, 8:30pm UTC](https://es.discourse.group/t/whitespace-newline-following-return-statement/1818/10 "2023-10-09T20:30:47Z")

</div>

> [@zambetti](#):
>
> There are programs that depend on the absence of a line-terminator between the return keyword and the opening brace of an object-literal?
> 
> Can you provide a short code example of such a scenario?

Maybe not, but there are possibly programs that have an unreachable empty block after a return statement. While improbably it's valid syntax, and you can't change the meaning of valid syntax.

```js
function functionB()
{
    return
    {
        // unreachable block
    };
}

```

---

<div class="post-metadata">

**Author:** ![senocular](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/senocular/32/642_2.png) [@senocular](https://es.discourse.group/u/senocular)\
**Post date:** [October 9, 2023, 9:04pm UTC](https://es.discourse.group/t/whitespace-newline-following-return-statement/1818/11 "2023-10-09T21:04:45Z")

</div>

> [@mhofman](#):
>
> ```javascript
> function functionB()
> {
> return
> {
> // unreachable block
> };
> }
> 
> ```

I think this example is important too because it explains the SyntaxError in the original code. That error isn't so much about an object literal not being allowed after a return statement. Its that in that context, the brackets are being seen as a code block rather than an object literal. As a code block there's an error given the use of the comma operator between two labeled statements. Removing the comma would make the syntax valid (though the function would still return undefined).

```typescript
// OK
function functionB()
{
    return
    {
        propertyA: true
        propertyB: true
    };
}

```

Out of context there's no distinction between a literal with a single property and a code block with a single labeled statement.

```typescript
// either an object literal or a block with a labeled statement
{
    propertyA: true
}

```

---

<div class="post-metadata">

**Author:** ![theScottyJam](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/thescottyjam/32/616_2.png) [@theScottyJam](https://es.discourse.group/u/theScottyJam)\
**Post date:** [October 10, 2023, 4:05am UTC](https://es.discourse.group/t/whitespace-newline-following-return-statement/1818/12 "2023-10-10T04:05:56Z")

</div>

Future proposals may be adding other hurdles for those who like to put the opening curly bracket on a new line. Pattern matching, for example, wishes to invent a new "match" syntax, but since "match" isn't a reserved keyword, they have to be a bit tricky about it. The current plans are as follows:

```javascript
// Today this would be a syntax error.
// Because of this, they can add meaning to this syntax without
// breaking old code. A.k.a. this is what pattern-matching will likely look like.
match (val) {
  ...
}

// This is valid syntax today (we're calling a "match" function, then we have a block of code).
// Because of this, pattern-matching can't use this syntax space.
// This will always need to mean the same thing.
match (val)
{
   ...
}

```

In other words, as currently planned, for pattern-matching to work you _must_ put the opening curly bracket on the same line as the "match". In general, if they ever want to invent a new control structure-like thing, and want to use a keyword for it that isn't currently reserved, this is how they'd have to do it - either that or do some ugly stuff with the new syntax.

Ideally, it wouldn't be this way and everyone could choose to place the curly brackets wherever they want, but that's just not the reality.

---

<div class="post-metadata">

**Author:** ![zambetti](https://avatars.discourse-cdn.com/v4/letter/z/eb9ed0/32.png) [@zambetti](https://es.discourse.group/u/zambetti)\
**Post date:** [October 10, 2023, 7:59am UTC](https://es.discourse.group/t/whitespace-newline-following-return-statement/1818/13 "2023-10-10T07:59:35Z")

</div>

> [@senocular](#):
>
> Out of context there's no distinction between a literal with a single property and a code block with a single labeled statement.
> 
> ```javascript
> // either an object literal or a block with a labeled statement
> {
> propertyA: true
> }
> 
> ```

Good example. Some of the other mentioned scenarios could be handled by lookahead (eg. the function scenario). This one, however, is ambiguous.

> [@mhofman](#):
>
> there are possibly programs that have an unreachable empty block after a return statement. While improbably it's valid syntax, and you can't change the meaning of valid syntax.
> 
> ```javascript
> function functionB()
> {
> return
> {
> // unreachable block
> };
> }
> 
> ```

This makes good sense. Returning an empty object-literal vs. undefined.

> [@theScottyJam](#):
>
> Future proposals may be adding other hurdles for those who like to put the opening curly bracket on a new line.

I was not aware of this proposal, this is another good point.  
This would add more brace-opinionatedness, in addition to 'return' and 'throw'.

Thank you all for entertaining this idea and providing counter-examples.
