Skip to content

Enhancement: Output let and const for variable declarations, without breaking changes #5377

Open
@GeoffreyBooth

Description

@GeoffreyBooth

Migrating this from #5344 (comment):

Now that CoffeeScript 2 outputs modern ES6+ syntax, we can use let and const in our output. Leaving aside the question of supporting block-scoped variables in the CoffeeScript input, (see #4985) there’s no reason that our generated output needs to use var when it could use let or const instead. We could therefore make two improvements in output code readability:

  1. Whenever possible, variable declarations should be placed at the block scope (via let) rather than always at the top of the function scope (the current behavior with var).

  2. Whenever possible, variable declarations should use const. This would be whenever a variable is never reassigned.

The key here is to not cause any breaking changes. So when in doubt, we would keep the current “define at the top of the function scope” behavior. A declaration/first assignment within a loop is a example of such a case. A let x within a loop means that x is declared multiple times (once for each iteration of the loop) which might be a breaking change for existing code.

If you look at this example:

if new Date().getHours() < 9
  breakfast = if new Date().getDay() is 6 then 'donuts' else 'coffee'
  alert "Time to make the #{breakfast}!"
else
  alert 'Time to get some work done.'

breakfast is only used within that if block, but it’s currently getting a var breakfast; line at the top of the output. The output instead could be this:

if (new Date().getHours() < 9) {
  let breakfast;

  breakfast = new Date().getDay() === 6 ? 'donuts' : 'coffee';
  alert(`Time to make the ${breakfast}!`);
} else {
  alert('Time to get some work done.');
}

And then phase 2 would see that breakfast is never reassigned and never referenced before its assignment (read about the let/const “temporal dead zone”) and use const instead:

if (new Date().getHours() < 9) {
  const breakfast = new Date().getDay() === 6 ? 'donuts' : 'coffee';
  alert(`Time to make the ${breakfast}!`);
} else {
  alert('Time to get some work done.');
}

I would try to achieve the two enhancements as separate PRs, probably with the block-scoping first.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions