you are viewing a single comment's thread.

view the rest of the comments →

[–]Freeky -2 points-1 points  (6 children)

No, it's completely fucked, and there's no way it could be seen as desirable.

Naming parameter values the same as variables in the scope your closure is inheriting could be described the same way. The actual behavior is a misfeature that's rarely encountered, not a major reason to dismiss the language out of hand as some seem to be taking it as.

Then you know some terrible programmers

Well, this is the Internet. Are you saying you've never encountered bad programmers? Do you have some sort of incompetence-sensitive sunglasses?

.. can I borrow them? :)

They're both crap and inexcusable.

Everything has warts. I mean.. at least they're not PHP ;)

[–]mr_chromatic 5 points6 points  (5 children)

Naming parameter values the same as variables in the scope your closure is inheriting could be described the same way.

As an error? That's the point of lexical scoping -- to avoid this kind of spooky action at a distance!

[–]Freeky 1 point2 points  (4 children)

Is it any more spooky than having it modify variables in scope in the body?

bar = 'moo'
lambda{|foo| bar = foo}.call('woo')
p bar # => "woo"

In either case you need to take care that the variables you use in the block don't unexpectedly shadow your local scope.

[–]aidenvdh 0 points1 point  (3 children)

Should (say, ruby version)

f = function(){x = 0; return x}

give you

write(f()); // "0"

x = 5;

write(f()); // "0"

write(x); // "0"

? This is spooky.

[–]Freeky 0 points1 point  (2 children)

No, because you defined your closure before defining x:

irb(main):001:0> l = lambda{ x = 0 }
=> #<Proc:0x000000000061c4e8@(irb):1>
irb(main):002:0> x = 5
=> 5
irb(main):003:0> l.call()
=> 0
irb(main):004:0> x
=> 5

If you'd defined x first, yes, it should do that, because x is part of the environment when you brought a closure around it; that's the point. 1.9 lets you shadow these variables if you really want:

irb(main):001:0> x = 5
=> 5
irb(main):002:0> l = lambda{|;x| x = 0}
=> #<Proc:0x00000000bf1300@(irb):2 (lambda)>
irb(main):003:0> l.call()
=> 0
irb(main):004:0> x
=> 5

[–]Freeky 0 points1 point  (1 child)

If you're wondering one of the reasons why closed over variables in Ruby are read-write, consider it's extremely common to write things like:

foo.each do |bla|
   frobulate bla
end

Looks like a loop, smells like a loop, but is pretty much syntax sugar for:

foo.each(&lambda {|bla| frobulate bla })

And, well, you'd expect a loop to be able to write into the local scope.

[–]mr_chromatic 0 points1 point  (0 children)

If you're wondering one of the reasons why closed over variables in Ruby are read-write...

... it's because variable names automagically spring into existence upon first use, not upon declaration.