Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Scope for self-referencing functions #1188

Closed
TrevorBurnham opened this issue Mar 8, 2011 · 5 comments
Closed

Scope for self-referencing functions #1188

TrevorBurnham opened this issue Mar 8, 2011 · 5 comments

Comments

@TrevorBurnham
Copy link
Collaborator

Someone posted a StackOverflow question this morning that pointed out that

init = ->
  ...
  init = -> doSomethingElse()

compiles to

var init;
init = function() {
  var init;
  ...
  return init = function() {
    doSomethingElse();
  };
};

That inner var init; declaration surprised him, and it surprises me as well. It's a weird exception to normal scoping rules, isn't it? And as a practical matter, enabling functions to overwrite themselves is quite useful.

The workaround is simple, of course: Just add init = null before the code.

@michaelficarra
Copy link
Collaborator

Yep, that's how our scoping works. We don't pay attention to variable declaration hoisting rules. Since init had not yet been defined at that point, it enters the scope inside the function as well. This is no different than your issue #1121. It's a little weird coming from an experienced JS programmer's background, but after talking with jashkenas about it when #1121 was open, I feel that it's right.

@TrevorBurnham
Copy link
Collaborator Author

I mean, it isn't really the same as #1121 (though "fixing" that issue would also fix this one). As you say, it's the way JavaScript works:

init = function() {
  // "init" lets this function reference itself
}

But more importantly, it feels antithetical to CoffeeScript's ethos to allow people to use the same name to refer to two different variables even on the same line:

func = -> func = (-> 'this is weird')

I don't see any problem with making a special case for assignments made on the same line as a function definition to be processed for scoping purposes before the inside of the function is. Is there something I'm overlooking?

@michaelficarra
Copy link
Collaborator

I think that suggestion would be even more confusing. At least with the way it is right now, it is very consistent. And how does this differ from #1121? You were asking for variable declaration hoisting. Now you're asking for hoisting only when declaring with an assignment to a function.

Remember,

var init = function(){ return init; }

is interpreted in JS as

var init;
init = function(){ return init; }

and you would like CoffeeScript to behave the same way (except only in some certain situations, apparently). That's hoisting.

@satyr
Copy link
Collaborator

satyr commented Mar 9, 2011

Declaring the variable before compiling RHS would fix it, which is reasonable considering = evaluates the LHS first:

$ coffee -e '[][console.log 1] = console.log 2'
1
2

@ghost ghost assigned jashkenas Apr 21, 2011
@jashkenas
Copy link
Owner

@satyr and @TrevorBurnham are right -- this is a bug. I've fixed it in the previous commit by reordering the variable declaration and RHS compilation.

satyr added a commit to satyr/coco that referenced this issue Oct 11, 2012
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants