16 comments

[ 4.3 ms ] story [ 51.0 ms ] thread
You get the exact same name-resolution funniness in other languages, too. Like python, for example:

  >>> message = "Hello"
  >>> def f(): print message
  ... 
  >>> message = "World"
  >>> def g(): print message
  ... 
  >>> f()
  World
  >>> g()
  World
This post is a nice example of misunderstanding scoping and/or closures (but probably both).
Agreed. True for Ruby too. Its important to remember how closures work, and what variables in the environment are being "closed" over.

> message = 'test'

> a = lambda { puts message }

> message = 'test1'

> b = lambda { puts message }

> a.call

test1

> b.call

test1

(comment deleted)
It would actually creep me out to get any other result.

For his desired outcome on the ES4 command line:

  var message = "Hello";
  var blah0 = function () {
                  var x = message;
                  return function () {
                      print(x);
                  }
              }();
  message = "World!";
  var blah1 = function () {
                  var x = message;
                  return function () {
                      print(x);
                  }
              }();
  blah0();
  >> Hello
  blah1();
  >> World!

  var message = "Hello";
  var blah0 = function (x) {
                  return function () {
                      print(x);
                  }
              }(message);
  message = "World!";
  var blah1 = function (x) {
                  return function () {
                      print(x);
                  }
              }(message);
  blah0();
  >> Hello
  blah1();
  >> World!
Two lines shorter! Ha! (I know, I know, line count isn't everything, yours better explains scoping, etc :-P)
This is just dumb. Who upvoted this story?

Javascript's lexical scoping and closure behavior are 100% conventional, there are no surprises here. There is only one message variable and it is referenced in both functions. Apparently the author wants the "message" assignment to work like a C macro and be evaluated at bind time, but I'm not aware of any language that has that behavior.

Yes.

I have to admit that this behavior confused me too when I was first learning Javascript. My only previous experience with lexical scope was in Common Lisp, which of course works the same way -- but the issue doesn't seem to come up as much there, perhaps because straight reassignment within the same lexical scope (of non-special variables) isn't something you do too often; perhaps because you can establish a new lexical scope and simultaneously rebind with LET within the normal control flow without defining and then calling a function, or perhaps simply for stylistic reasons). So I'd never really noticed it in Lisp. But once I realized what was going on it was clearly perfectly sensible. It's hardly "creepy," and it's certainly easy enough to establish new scope when you need to.

And for crying out loud, it's not got anything at all to do with asynchronicity.

The #1 guy on the leaderboard submitted this? Makes me think he's using a submit-bot.
I thought it was interesting for the comments/discussion triggered by the blogger's error. Maybe that's why he posted it?
Please someone down vote this topic for me, as I don't have that ability yet. He's posting someone's post on something that they think is weird just because they don't understand the language..
I've never downvoted a story before but this one deserved it; but now I can no longer downvote! I am sad.
There is no such thing as downvoting stories. Welcome to Hacker News.
really? I thought I just haven't got enough karma to do so..
Maybe ComputerGuru just doesn't have enough karma to know about it ;)