I thought this was the one that worked?

On 8/1/06, Chad P. [email protected] wrote:

and this is a closure:

def foo
lambda { puts “Hellow world!” }
end

bar = foo

Yes, this is exactly the point we’ve been trying to get across. Both
of these are closures.

but this is not a closure:

foo = 0

foo.each do
puts bar += 1
end

This is where we get into what David Black described as hair
splitting. Lets move away from each, and to a set of more general
methods:

greeting = “Hello”

1) explicit proc

def foo(callback)
callback.call(“world”)
end

callback = lambda{ |arg| puts “#{greeting}, #{arg}!” }
foo(callback)

prints “Hello, world!”

2) block converted to proc

def bar(&callback)
callback.call(“world”)
end

bar{ |arg| puts “#{greeting}, #{arg}!” }

prints “Hello, world!”

3) block yielded to

def baz
yield “world”
end

baz{ |arg| puts “#{greeting}, #{arg}!” }

prints “Hello, world!”

The first example obviously uses a closure. While true that the
environment where “greeting” is defined never goes out of scope, it is
not visible within the context where callback is actually executed.

The second example performs the exact same operation as the first, the
only difference is the syntax and when the chunk of code becomes a
proc.

The third example simply removes the explicit conversion from a block
to a proc, using yield instead. As such, the semantics between all
three are similar and example three can be arguably said to use a
closure as well. This is the stance Gennady and “the Victim” are
taking.

David’s point, however, is that in the third example, when yield is
used instead of converting it to a block, the code inside the block
never really leaves the context in which it is created, because of the
way non-converted blocks are implemented. More specifically, that
implementation doesn’t need to store that environment. This is a
probable reason for the speed difference between converted blocks
(first class procs) and unconverted blocks (yield). Since the
environment is never stored, it’s not really a closure in the
implementation
. This is the hair that David was splitting.

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.

Jacob F.

On Wed, 2 Aug 2006, Chad P. wrote:

That still doesn’t make all blocks closures, though.

really?

harp:~ > cat a.rb
class Object
def closure(&block) block end
end

p(eval(‘self’, closure))

class C
p(eval(‘self’, closure))
end

harp:~ > ruby a.rb
main
C

any block encloses, at minimum, ‘self’. therefore all blocks are
closures.

-a

On Aug 1, 2006, at 3:56 PM, Chad P. wrote:

end

Then x _will_ be a closure but, then again, we already knew  

this…

If that’s the case, then everything else is a closure too, because
everything else has access to a – at least where lexical or global
scope exists.

Actually no one has access to a because it is a local variable.

Look all blocks close over at least self. If a block contains a
call to any receiverless method it is a closure even by your rigid
definition.

On Wed, Aug 02, 2006 at 04:56:53AM +0900, Jacob F. wrote:

methods:
Let’s not. Hair splitting actually came up in reference to the
distinction between the first two examples, and not in reference to the
third. If you’re calling the distinction for the third example “hair
splitting”, I’m just going to have to call you flat-out “wrong”, unless
this is a case of “the Ruby community uses a definition of ‘closure’
that is in direct contradiction of other definitions of ‘closure’”,
which seems really odd to me since Ruby most definitely is capable of
proper closures as defined elsewhere.

On Wed, 2 Aug 2006, Chad P. wrote:

We’re back to the absurdly broad here:

If any “thing” that has access to another scope is a closure, that makes
every nested “thing” in a language with global and/or lexical scope a
“closure”. That’s a little like defining a “human” as “has four limbs”.

closures in ruby have neither global nor lexical scope though:

harp:~ > cat a.rb
class Object
def closure(&b) b end
end

c = closure

def a() p 42 end
eval ‘a’, c

def a() p ‘forty-two’ end
eval ‘a’, c

harp:~ > ruby a.rb
42
“forty-two”

the scoping is dynamic. in otherwords we can add things to the enclosed
state
later - it’s not frozen at the time the closure is created.

that can refine the def a bit.

regards.

-a

On 8/1/06, Chad P. [email protected] wrote:

define a closure.
On that, we can agree. :slight_smile:

either, because the explanations of closures I’ve seen can potentially
be interpreted in that manner. Even so, I’d say that to fit a strict
definition of a closure, the chunk of code in question needs to exit its
enclosing scope before it’s a closure – else it’s not “closed”.

I don’t necessarily agree with that, but it’s incidental to my point,
so I won’t argue it.

Even then, an empty environment can’t exist in Ruby. There’s always at
least one “variable” in the environment that will be accessible in the
closure: self. Take the following example:
[snip example]

Now you’re arguing that there does, indeed, have to be a variable.
What?

No, I’m not saying there has to be a variable for it to be a
closure. I’m simply demonstrating that in Ruby there always will be
a variable: self.

bar.call

. . . so I don’t see your point. Cut out the middleman, and it still
works.

Ah, but you’re still using self in that example. Who is the receiver
of the call to puts inside the block? It’s self.

There is no such thing as a “function” in ruby; they are all methods.
When you make a method call without an explicit receiver, that method
is called with a receiver of self. Even puts; the Kernel module
defines a puts method, which is mixed into the Object class, so all
objects have access to that puts method. That’s what some other
posters were demonstrating when they used all that trickery redefining
puts for the object’s singleton. You’re still using self. I was just
trying to make that dependence on self more explicit by using a
non-standard method like baz.

Jacob F.

On Wed, Aug 02, 2006 at 12:45:46AM +0900, Marshall T. Vandegrift wrote:

I’m joining the party late, but try this example:

Why? Why should we keep trying unnecessarily complex examples that
introduce a bunch of variables (in the statistical study sense of the
term) that are not strictly relevant to the point under consideration?
I’m frankly getting a little tired of having someone new enter the
conversation every few hours and say “Let’s try this discussion,” after
which I have to expend energy on several emails back and forth to get
the broad, complex example offered narrowed down to the salient points,
over and over again – especially since the salient points are the same
in each case. One step forward, three steps back.

From the Wikipedia definition:

[A] closure is a function that refers to free variables in its
lexical context.

Also from the Wikipedia definition:

[A] closure is a function

That’s not very useful. The Wikipedia “description” (it’s not a
dictionary, and as such doesn’t strictly speaking aim to “define” the
terms contained within it) is, for purposes of this discussion,
nigh-uselessly broad and lacking in coherent detail.

variables, but the ruby implementation has no way of knowing that.
Thus, every block carries around a lexical context which references
all free variables in that context. Thus, every block is a closure.

Only if you accept a description of a closure as a definition. As I
implied elsewhere, however, “has four limbs” may be an accurate
description of a human, but the fact “dog” fits that description doesn’t
make it a human.

On Wed, 2 Aug 2006, Chad P. wrote:

end

Then x will be a closure but, then again, we already knew this…

But the a inside x and the a outside x are unrelated. Method
definition blocks (with def) aren’t closures.

Wait . . . are you serious? Ruby is using dynamic scope here? Ugh.

no.

def x
puts a
end

is lexical scoping. not dynamic.

-a

On Wed, Aug 02, 2006 at 05:07:26AM +0900, Logan C. wrote:

scope exists.

Actually no one has access to a because it is a local variable.

Look all blocks close over at least self. If a block contains a
call to any receiverless method it is a closure even by your rigid
definition.

The “a” to which I referred was the “a” that existed at “a = 1”.

On Wed, Aug 02, 2006 at 05:07:41AM +0900, [email protected] wrote:

harp:~ > cat a.rb
eval ‘a’, c
that can refine the def a bit.
That’s not much of a closure, then.

On Wed, Aug 02, 2006 at 05:07:33AM +0900, Jacob F. wrote:

end, and the article spends an awful lot of time failing to concretely
define a closure.

On that, we can agree. :slight_smile:

Good.

call “wrong”, even if it doesn’t strike me as particularly “right”
either, because the explanations of closures I’ve seen can potentially
be interpreted in that manner. Even so, I’d say that to fit a strict
definition of a closure, the chunk of code in question needs to exit its
enclosing scope before it’s a closure – else it’s not “closed”.

I don’t necessarily agree with that, but it’s incidental to my point,
so I won’t argue it.

I was overhasty in the way I phrased that, I think. I suppose the chunk
of code doesn’t need to exit its enclosing scope so much as the
reference to the closure scope has to exit that scope irrevocably.

bar = foo.bar

bar.call

. . . so I don’t see your point. Cut out the middleman, and it still
works.

Ah, but you’re still using self in that example. Who is the receiver
of the call to puts inside the block? It’s self.

That’s an impressive bit of gymnastics. I don’t buy it as satisfying
the requirements of a closure, though, at this point. Self is just
something within the current scope, and we’re back to an absurdly broad
redefinition of “closure”.

There is no such thing as a “function” in ruby; they are all methods.

Methods are “functions” in the technical, broadly interpreted computer
science definition of the term. They’re just a special case of
“function” that requires more specific conditions to qualify as
“methods”. A method is a function: a function is not necessarily a
method.

On Wed, 2 Aug 2006, Chad P. wrote:

If that’s the case, then everything else is a closure too, because
everything else has access to a – at least where lexical or global scope
exists.

‘has access to’ and ‘keeps a pointer to’ are to totally separate things
and
is, i believe, the crucial difference between what constitues a concrete
closure. for instance

this_is_a_closure = lambda{}

why? read the c code and see that the object indeed contains a pointer
to
‘this’ context that can be referred to in a dynamic (looking up anything
that’s been added) way.

now, this is not a closure because no object exists, specially not
the
object ‘b’, which remembers or stores a pointer to the enclosing
environment
that contains a. the context was not stored and is lost

a = 42

b = a + 42

the key thing to remember is that, indeed, any ruby statement has to
potential
to become an ‘enclosing’ object since the environment can always be
stored
with a simple

@b = binding

nevertheless, not all statements are closures because not all of them
choose
to remember this environment.

blocks however, due to the magic ruby does under the hood and the fact
that
they must remain valid arguments to

eval some_code, a_binding_or_proc

do maintain a pointer to the enclosing environment which contains at
minimum
‘self’.

regards.

-a

On Wed, Aug 02, 2006 at 05:12:02AM +0900, [email protected] wrote:

is lexical scoping. not dynamic.
It’s not lexical scoping if that “a” variable is separate from the “a”
variable in the enclosing scope.

On Wed, 2 Aug 2006, Chad P. wrote:

eval ‘a’, c
state
later - it’s not frozen at the time the closure is created.

that can refine the def a bit.

That’s not much of a closure, then.

that’s an absurd thing to say don’t you think? it’s not bad or good -
it is
what it is. it is in fact a very pure closure which perfectly captures
the
state in which it was defined in. note that i said it captures the
‘state’
and not the ‘state of the state’ - in otherwords it has a pointer to the
state
and not a copy of the state. that way it even has access to newly added
information as my example shows. this is amazingly powerful even if it
doesn’t fit your idea of what a closure may or may not be.

i might add that perl has exactly this kind of enclosing semantics and
is
considered to have ‘true’ closures.

-a

On Aug 1, 2006, at 4:12 PM, Chad P. wrote:

The “a” to which I referred was the “a” that existed at “a = 1”.

I know. It’s still a local variable.

On 8/1/06, Chad P. [email protected] wrote:

baz = foo
of these are closures.
splitting. Lets move away from each, and to a set of more general
methods:

Let’s not. Hair splitting actually came up in reference to the
distinction between the first two examples, and not in reference to the
third.

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.

If you’re calling the distinction for the third example “hair
splitting”, I’m just going to have to call you flat-out “wrong”

Did you read my explanation? I called it hair-splitting for the same
reason David did – because it can be argued both ways. I gave both
reasons. If you want to debate that point, please reply with more
specifics.

unless this is a case of “the Ruby community uses a definition of ‘closure’
that is in direct contradiction of other definitions of ‘closure’”

I’ll repeat myself: "Since the environment is never stored, it’s not
really a closure in the implementation. This is the hair that David
was splitting.

“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.”

As you can see, I’ve admitted that in the one case of a
non-converted block it is not a true closure. But I believe semantic
terms can be more useful than rigid and narrowly defined formal
theoretical definitions. Like duck typing – as long as it quacks just
like a real closure, it’s close enough for me.

Jacob F.

[ruby-talk:205331]
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/205331

On Wed, Aug 02, 2006 at 05:22:05AM +0900, [email protected] wrote:

information as my example shows. this is amazingly powerful even if it
doesn’t fit your idea of what a closure may or may not be.

No, I don’t think it’s “an absurd thing to say” – it just doesn’t have
much depth. The depth is this:

If it doesn’t provide what OOPish programmers would call “protection”,
it’s not a closure. How can it be a closure if it’s not closed?

i might add that perl has exactly this kind of enclosing semantics and is
considered to have ‘true’ closures.

True – but that doesn’t mean that “this kind of enclosing semantics” is
the closure itself. See above, re: closing something to create a
closure.

On Aug 1, 2006, at 4:20 PM, Chad P. wrote:

is lexical scoping. not dynamic.

It’s not lexical scoping if that “a” variable is separate from the “a”
variable in the enclosing scope.

Ah this is where you misunderstand. def does not close over a. defs
introduce a new “toplevel” scope.

On Wed, 2 Aug 2006, Chad P. wrote:

is lexical scoping. not dynamic.

It’s not lexical scoping if that “a” variable is separate from the “a”
variable in the enclosing scope.

yes. it is, because there is no ‘a’ in the enclosing dynamic scope:

 harp:~ > cat a.rb
 a = 42

 def m() p a end

 m

 harp:~ > ruby a.rb
 a.rb:4:in `m': undefined local variable or method `a' for 

main:Object (NameError)
from a.rb:6

you have to understand that ruby doesn’t always use one method of
scoping -
sometimes it’s dynamic and sometimes it’s lexical.

-a

On 8/1/06, Chad P. [email protected] wrote:

foo = Foo.new
That’s an impressive bit of gymnastics.
Gymnastics? What exactly did I twist?

I don’t buy it as satisfying
the requirements of a closure, though, at this point. Self is just
something within the current scope, and we’re back to an absurdly broad
redefinition of “closure”.

What current scope are you referring to here? If you mean the scope
that was current when the block was created, then why does that not
make it a closure? Why is self different than some other variable
named b? If you don’t mean the scope that was current when the block
was created, then you’re mistaken, because it is the self that was
current when the block was created that is used. This is what others
were trying to demonstrate in the examples you dismissed as having
irrelevant variables.

There is no such thing as a “function” in ruby; they are all methods.

Methods are “functions” in the technical, broadly interpreted computer
science definition of the term. They’re just a special case of
“function” that requires more specific conditions to qualify as
“methods”. A method is a function: a function is not necessarily a
method.

Ok, we’re using different definitions of function. That’s why I put
function in quotes when I said it, but I can see you want to be
pedantic. By your definition, a method is indeed a function.

But I counter your last statement: in Ruby, all functions are
necessarily methods, because you can’t call a method/function without
a receiver. You can write it syntactically without a receiver, but in
that case a receiver of self is still implicit. In this sense, Ruby
has no “functions”, only methods.

Jacob F.