In my last post, I made this assumption:
The closure’s only supposed to capture the environment at the time it was created. Defining x later shouldn’t let fx access that new variable.
It ends up that I’m probably wrong about that, at least according to MzScheme:
cnixon:~$ mzscheme
Welcome to MzScheme v372 [3m], Copyright (c) 2004-2007 PLT Scheme Inc.
> (define fx (lambda () x))
> (fx)
reference to undefined identifier: x
> (define x 1)
> (fx)
1
Chicken Scheme backs me up on this. Ruby, on the other hand, behaves differently:
cnixon:~$ irb
irb(main):001:0> fx = lambda { x }
=> #<Proc:0x010b15d4@(irb):1>
irb(main):002:0> fx
=> #<Proc:0x010b15d4@(irb):1>
irb(main):003:0> fx.call
NameError: undefined local variable or method `x' for main:Object
from (irb):1
from (irb):3:in `call'
from (irb):3
irb(main):004:0> x = 1
=> 1
irb(main):005:0> fx.call
NameError: undefined local variable or method `x' for main:Object
from (irb):1
from (irb):5:in `call'
from (irb):5
Thanks to Dave Cleaver and Topher Cyll for help on figuring this out.