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

using for..of with do, doesn't behave as expected (newbie disclaimer) #4118

Closed
shanemikel opened this issue Oct 2, 2015 · 6 comments
Closed

Comments

@shanemikel
Copy link

I'm new to using coffeescript, so thanks for this first of all. It's got it's nuances, but overall a beautiful language.

I would like to point out I've had some troubling experience with the way the do operator works
consider:

for own key, symbol of LEVELS
    do (key, val) -> makeGetter key, get: -> return val

That compiles to:

fn1 = function(key, val) {
  return makeGetter(key, {
    get: function() {
      return val;
    }
  });
};
for (key in LEVELS) {
  if (!hasProp.call(LEVELS, key)) continue;
  symbol = LEVELS[key];
  fn1(key, val);
}

(Which wouldn't work in this case)

where I would actually expect the parameters named after the do operator, to only be relevant to the names they're given in the function definition.

The actual behavior would be more clear if the names weren't required to look like a function parameter definition, but could be passed without parens as if they were arguments to the do op.

@vendethiel
Copy link
Collaborator

I'm not sure what you mean. The fact that key and symbol exist in the outer scope is the thing that bugs you?

@shanemikel
Copy link
Author

what I'm saying, is I would expect the original coffee code to compile to this:

fn1 = function(key, val) {
  return makeGetter(key, {
    get: function() {
      return val;
    }
  });
};
for (key in LEVELS) {
  if (!hasProp.call(LEVELS, key)) continue;
  symbol = LEVELS[key];
  fn1(key, symbol);
}

@vendethiel
Copy link
Collaborator

Those are global variables. They shouldn't be. What's the issue?

@connec
Copy link
Collaborator

connec commented Oct 12, 2015

There is no relationship between the for variables and the do arguments. If you look at the compilation of your do by itself:

// do (key, val) -> makeGetter key, get: -> return val
(function(key, val) {
  return makeGetter(key, {
    get: function() {
      return val;
    }
  });
})(key, val);

Notice that (key, val) val are the argument names. This doesn't change when you use do in a loop.

You can rewrite your code to:

for own key, symbol of LEVELS
    do (key, symbol) -> makeGetter key, get: -> return symbol

# OR, more clearly?

for own key, symbol of LEVELS then do (key, symbol) ->
  makeGetter key, get: -> symbol

@shanemikel
Copy link
Author

Okay, well I figured it out, and there's no need to dwell on the issue. Perhaps it's more productive to figure out if this is clearly described in the language guide? But I guess it's just as easy to look at the generated code.

@connec
Copy link
Collaborator

connec commented Oct 16, 2015

See #2518 for some discussion about for and do.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants