On Wed, Aug 02, 2006 at 08:30:10AM +0900, Just Another Victim of the
Ambient M. wrote:
The current definition on Wikipedia is scattered, vague, and without
salient points on this matter. I’ve read through the thing from end to
end, and the article spends an awful lot of time failing to concretely
define a closure.
On that, we can agree. 
If you two agree then... why don't you improve it? It's a wiki, after
all…
I probably will. Doing so during this discussion would have come off as
trying to “cheat”, though.
Hi –
On Wed, 2 Aug 2006, Chad P. wrote:
Actually, if you go back and read David’s post [ruby-talk:205331],
which is the first reference to hair splitting in this thread, you’ll
see that he clearly believes both of the first two examples to be
closures. When he mentions hair splitting, it’s directly in relation
to the third form – an unconverted (yielded to) block.
You were right, up to the point where you said “When he mentions hair
splitting”. The problem at that point that prompted him to mention hair
splitting was the fact that I was balking at defining that second
example as a “closure”.
No, I meant that my comments about whether blocks were closures was
hair-splitting. (Maybe the fact that I introduced the comments that
way looked like I was actually summing up what came before, but the
hair-splitting pronouncement ended with a colon 
David
Hi –
On Wed, 2 Aug 2006, [email protected] wrote:
I would say: control passes to the block. The block itself is not
represented by an object (which I think is the only quasi-objective
[ha ha] definition of “sent”) in any scope other than the one in which
it was created.
(Nor, I should add, in the one in which it was created.)
David
Hi –
On Wed, 2 Aug 2006, Just Another Victim of the Ambient M. wrote:
this is the sample code you provided…
a = 10
the block is defined here but “sent” to the “each” method…
[1, 2, 3].each {|x| puts x * a }
I would say: control passes to the block. The block itself is not
represented by an object (which I think is the only quasi-objective
[ha ha] definition of “sent”) in any scope other than the one in which
it was created.
David
On Wed, Aug 02, 2006 at 10:01:11AM +0900, [email protected] wrote:
No, I meant that my comments about whether blocks were closures was
hair-splitting. (Maybe the fact that I introduced the comments that
way looked like I was actually summing up what came before, but the
hair-splitting pronouncement ended with a colon 
. . . so it was a complete non-sequitur? Mea culpa. I assumed that
comment had something to do with your response to me. In fact, the
impression I got was that you were talking about the hair-splitting that
occurs in the differentiation between “gets something from this scope”
and “could get something from this scope”, but then decided to introduce
more hair-splitting about something related – but not strictly.
. . . which makes me wonder what you were actually saying about my
points, now.
Hi –
On Wed, 2 Aug 2006, Chad P. wrote:
occurs in the differentiation between “gets something from this scope”
and “could get something from this scope”, but then decided to introduce
more hair-splitting about something related – but not strictly.
Sorry – at this point my head is spinning. I really can’t untangle
the thread itself any further.
. . . which makes me wonder what you were actually saying about my
points, now.
My main point was that you can see a closure in action in a negative
sense, in a case where there are no local variables, by doing this:
def x
lambda { puts n }
end
n = 1
x.call # undefined local variable or method `n'
You get an error because the “puts n” is being executed in the context
in which the lambda was created. If it were being executed in the
calling context, it would print 1.
If you rule out calling the lambda a closure, then you have to explain
this suspiciously closure-like behavior 
Closures, one might say, close things out, as well as closing them in.
David
On Wed, Aug 02, 2006 at 11:36:56AM +0900, [email protected] wrote:
Sorry – at this point my head is spinning. I really can’t untangle
the thread itself any further.
No problem. I’ve had to specifically choose to abandon some of the less
promising subthreads to keep my own head from spinning like a top.
n = 1
x.call # undefined local variable or method `n’
You get an error because the “puts n” is being executed in the context
in which the lambda was created. If it were being executed in the
calling context, it would print 1.
If you rule out calling the lambda a closure, then you have to explain
this suspiciously closure-like behavior 
This is where I thought you were saying that my statements might be
considered splitting hairs – in differentiating between a closure with
a closure variable and a (non?)closure with a closing lexical scope that
may or may not have a closure variable.
Closures, one might say, close things out, as well as closing them in.
I certainly agree with that – though at least one person seemed to
disagree with me on that statement. At this point, I have no
recollection of who it was or exactly what was said, though.
On Wed, Aug 02, 2006 at 11:40:05AM +0900, Just Another Victim of the
Ambient M. wrote:
(Nor, I should add, in the one in which it was created.)
...but does the definition of a closure require that the closure be an
object? No, a closure is a block of code that executes outside of it’s
defining scope but still has access to said scope.
Someone correct me if I’m wrong, but . . . I got the impression that the
point being made didn’t really have anything to do with objects, per se.
The use of the word “object” might have been ill-advised in terms of
keeping the conversation on-track. The impression I got from that is
that the intent was to say “the block itself is not represented,
present, whatever in any scope other than the one in which it was
created.” The use of the term “object” probably arose only because
we’re discussing closures within the context of Ruby.
I think.
On the other hand, I think “a block of code that executes outside of its
defining scope but still has access to said scope” works as about a
90%-complete definition of closures. All that’s really missing is
something that seems to be necessarily implied by that sentence: that
the scope in question is “closed”.
[email protected] wrote in message
news:[email protected]…
a = 10
the block is defined here but “sent” to the “each” method…
[1, 2, 3].each {|x| puts x * a }
I would say: control passes to the block. The block itself is not
represented by an object (which I think is the only quasi-objective
[ha ha] definition of “sent”) in any scope other than the one in which
it was created.
(Nor, I should add, in the one in which it was created.)
...but does the definition of a closure require that the closure be
an
object? No, a closure is a block of code that executes outside of
it’s
defining scope but still has access to said scope.
Of course the control is passed to the block. How else can the
block
execute? Control is passed to the block even if it were a Proc object
so
this is not even a distinction, much less a meaningful one…
Chad P. wrote:
On Wed, Aug 02, 2006 at 08:40:14AM +0900, Hal F. wrote:
I think “lexically” might be the key word there. Isn’t it true
that Perl has only lexical closures, not “real” closures?
Lexical closures are “real” closures. The term “closure” as it is
being bandied about is an abbreviation for “lexical closure”.
I can’t disagree with you. I have a friend, a very knowledgeable
person, who made a distinction there. Besides being a little
smarter than I am, he is a Perl programmer, which I am not.
I’ll ask him about it sometime.
Hal
“Chad P.” [email protected] wrote in message
news:[email protected]…
[ha ha] definition of “sent”) in any scope other than the one in which
point being made didn’t really have anything to do with objects, per se.
The use of the word “object” might have been ill-advised in terms of
keeping the conversation on-track. The impression I got from that is
that the intent was to say “the block itself is not represented,
present, whatever in any scope other than the one in which it was
created.” The use of the term “object” probably arose only because
we’re discussing closures within the context of Ruby.
I know what you mean. I was afraid that he meant "object" in the
colloquial sense, rather than the programmatic sense, except that he
says
“the block itself is not represented by an object,” which is false if we
interpret “object” in the general sense of the word. The keyword
“yield”
represents our ability to execute the block and we may even pass the
block
parameters with it. Therefore, I interpreted the use of the word
“object”
in the programmatic sense, since it is true that a method is not given a
block as an object unless you explicitly convert it to one…
I think.
I try to, as well, but it's hard sometimes...
Chad P. schrieb:
bar.call
Chad, I didn’t carefully read all of this long thread because I’ve been
offline for a couple of days. You don’t have to answer to this mail, if
it isn’t relevant to you.
I had the impression that you think a block can’t be called a closure if
it doesn’t reference any free variables from its context, just as the
block in the example above. If I understand you correctly, then the
following two blocks should be exactly the same, shouldn’t they?
blk1 = Foo.new.bar
blk2 = Foo.new.bar
But they aren’t the same, as can be seen from the following code:
eval “self”, blk1 # => #Foo:0x2b851e0
eval “self”, blk2 # => #Foo:0x2b85138
As you can see, each block remembers at least the value of “self”, when
it was created. You can get at this value even if the “self” object goes
out of scope, as you can see from my code above. There’s no explicit
reference to the two instances of Foo. From this it follows (at least
for me), that each block in Ruby is a closure.
Regards,
Pit
On 8/1/06, Just Another Victim of the Ambient M.
[email protected] wrote:
never really leaves the context in which it is created, because of the
that without that reference?
The way I imagine it (I haven’t looked at the C, so I could be – and
probably am – way off, but this is how I might make a first stab at
implementing it) is that when a method is called with a non-converted
block, that block never leaves its creation point. It is not wrapped
up in any representation, except maybe a few variables within (not
referring to) the calling context. When yield is encountered in the
method body, execution is bumped back up into the calling context
where the block is executed, then when the block returns we pop back
into the current context of the method. So when the block is executed,
it has access to the context where it was created because it’s being
executed in the context where it was created.
This is obviously not what is really happening, since – for instance
– variables first assigned to within the block do not persist within
that blocks creating context after the block terminates. It should be
close enough, though, to show how the block can access its creating
context without needing a reference to it.
But semantically, whether a block is converted to a proc or just
yielded to, the behavior regarding variable scope is identical; so if
one is a closure, it’s useful to refer to the other as a closure as
well, even if it’s not implemented as a true closure. In this sense,
all blocks are closures.
I believe that, when describing a programming language and its features,
the behaviour of the language is more important than its implementation. I
mean, the language is defined by its specification rather than some
implementation, right?
Agreed. You’ll find me in the camp that claims all blocks are closure
for all practical purposes. Mostly, I was just trying to figure out
myself what David might have been referring to in his hair-splitting
comments, since I respect him a great deal and expect him to know much
more about Ruby internals than I do. 
Jacob F.
On 8/1/06, Just Another Victim of the Ambient M.
[email protected] wrote:
The current definition on Wikipedia is scattered, vague, and without
salient points on this matter. I’ve read through the thing from end to
end, and the article spends an awful lot of time failing to concretely
define a closure.
On that, we can agree. 
If you two agree then... why don't you improve it? It's a wiki, after
all…
The truth? Because I’d already spent to much energy and time in this
thread, I didn’t have any left to spend on the wikipedia entry.
Especially since before trying to make any sort of edit based on a
belief that my understanding was more correct I’d want to do a lot
more research in authoritative sources to back up my claims.
I hope that I can find the impetus and time to do it in the near
future, however.
Jacob F.
On Wed, Aug 02, 2006 at 10:59:15PM +0900, Pit C. wrote:
bar = foo.bar
following two blocks should be exactly the same, shouldn’t they?
it was created. You can get at this value even if the “self” object goes
out of scope, as you can see from my code above. There’s no explicit
reference to the two instances of Foo. From this it follows (at least
for me), that each block in Ruby is a closure.
While I’ve reached a point where I think I agree that all blocks can be
called closures according to a particular valid (liberal) definition of
“closure”, I don’t think your explanation holds water as it stands. The
problem is that maintaining state is not the only requirement for a
closure. In fact, according to the interpretation of a closure’s
definition that allows all blocks in Ruby to be closures, a closure need
not maintain (meaningful) state at all. Besides, I think you’re
pointing out memory addresses for those objects, not something internal
to them. Please correct me if I’m wrong.
On 8/2/06, Chad P. [email protected] wrote:
eval “self”, blk2 # => #Foo:0x2b85138
As you can see, each block remembers at least the value of “self”, when
it was created. You can get at this value even if the “self” object goes
out of scope, as you can see from my code above. There’s no explicit
reference to the two instances of Foo. From this it follows (at least
for me), that each block in Ruby is a closure.
[snip]
I think you’re
pointing out memory addresses for those objects, not something internal
to them. Please correct me if I’m wrong.
self is not just a memory address (well, not any more than any other
object reference). You’re seeing the memory address because that’s the
default #inspect output for an object, but it’s not really relevant
here. self is an object reference just like any other variable would
be. Let’s replace the contents of the evals with a method call
instead:
using the same definition of Foo as referenced earlier
foo1, foo2 = Foo.new, Foo.new
foo1.object_id # => 1742734
foo2.object_id # => 1742684
blk1, blk2 = foo1.bar, foo2.bar
eval “object_id”, blk1 # => 1742734
eval “object_id”, blk2 # => 1742684
I also captured the Foo objects themselves so we can see that the
object_id method call is being sent to the foo object rather than the
block itself.
Jacob F.
On Thu, Aug 03, 2006 at 01:11:35AM +0900, Jacob F. wrote:
foo1.object_id # => 1742734
foo2.object_id # => 1742684
blk1, blk2 = foo1.bar, foo2.bar
eval “object_id”, blk1 # => 1742734
eval “object_id”, blk2 # => 1742684
I also captured the Foo objects themselves so we can see that the
object_id method call is being sent to the foo object rather than the
block itself.
Are we sure, though, that we’re not just looking at a number (associated
with that instance) that’s stored in a hash table external to the
object?
On 8/2/06, Chad P. [email protected] wrote:
foo1, foo2 = Foo.new, Foo.new
Are we sure, though, that we’re not just looking at a number (associated
with that instance) that’s stored in a hash table external to the
object?
Actually, object_id is calculated from the reference itself.
Simplified, it’s pretty similar to the memory reference itself. But
the point is, while the memory reference may be the source of the
value, we’re retrieving it through a method call. The fact that I’m
making a method call implies that we have a reference to an object
call that method against. The choice of object_id as that method is
just convenience to show that the objects referred to are at once
unique from each other, and identical to the source objects.
Jacob F.
On Thu, Aug 03, 2006 at 02:23:36AM +0900, Jacob F. wrote:
making a method call implies that we have a reference to an object
call that method against. The choice of object_id as that method is
just convenience to show that the objects referred to are at once
unique from each other, and identical to the source objects.
That sounds plausible. Okay, I believe you. Heh.
Thanks for the effort in explaining it.