Hoist variables "declared" with do #2552

raganwald opened this Issue Sep 17, 2012 · 5 comments


None yet
4 participants

When I write:

(foo) ->
  do (bar = 5) ->
    foo + bar

Instead of:

(function(foo) {
  return (function(bar) {
    return foo + bar;

I would like the result to be optimized to:

(function(foo) {
  var bar = 5;
  return foo + bar;

In cases where bar is not used elsewhere within foo. This optimization would make many uses of do free at runtime, eliminating an argument about variable scoping and shadowing. The downside is that the code for do would sometimes translate one way and sometimes another, which is certainly a major consideration.

If this gets done, adding a 'let' keyword would be really easy; as let x = 2, y = 3 could easily desugar into do (x = 2, y = 3) ->, which may or may not then cause an extra closure surrounding remainder of the current block.

It's also worth noting that the trigger/context for this bug report is http://news.ycombinator.com/item?id=4534408, in which raganwald recommends the do syntax for situations in which you want to be sure of local scoping.

JavaScript 1.7 introduces the let keyword, so going in the other direction, if this becomes commonplace we could special case the form do (foo = 1, bar = 2) -> to let (foo = 1, bar = 2) { ... }. Hopefully the host JavaScript interpreter would include optimizations of its own.

Although there is an abundance ofexperience hoisting variables out of let expressions in Lisp, we can step back from overengineering by conidering the simplest possible case: Where the sole member of a function is a do epression:

(x) ->
  do (y = z) ->
    # ...


function (x) {
  var y = z;
  // ...

A simple optimization that wouldn't confuse the reader and covers the most common complaint of people who want to "declare" variables local to a specific function.


satyr commented Sep 18, 2012

Where the sole member of a function is a do expression

And the done function doesn't mention the shadowed variable in default values.


  do (x = x + 1) ->
     # ...

can't be:

  `var x`
  x = x + 1
  # ...

jashkenas commented Feb 1, 2013

We're definitely not going to be "optimizing" the do form in order to be used as a variable declaration syntax. If we wanted to provide a good variable declaration syntax, then we should simply do that. do -> is supposed to immediately invoke the function.

@jashkenas jashkenas closed this Feb 1, 2013

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment