What are closures, continuations?

I've seen these mentioned in various places. From what I can tell:

- Ruby has closures -- which seem to be returning procs from functions?
- Continuations may be planned for a future release of Ruby.

If anybody can elaborate/correct, please feel free! Also, how would each
be useful?

Thanks,
Joe

···

--
Posted via http://www.ruby-forum.com/.

Joe Ruby MUDCRAP-CE wrote:

I've seen these mentioned in various places. From what I can tell:

- Ruby has closures -- which seem to be returning procs from functions?
- Continuations may be planned for a future release of Ruby.

If anybody can elaborate/correct, please feel free! Also, how would each be useful?

Thanks,
Joe
  
Closures are tricky, but you can think of them as blocks of code, or a way of making code a first-class object. Or as anonymous functions. Or as lambdas. There is a lot of documentation on them, I'd start with the Pickaxe book if you have it, or the online version if you do not.[1] Then google for "ruby blocks" and read what you can find to clarify. Also search this list for past discussions.

Continuations are currently available in Ruby[2], although, from what I understand, they are not widely used. There was a thread earlier about YARV (the "engine" for the next version of Ruby) not yet supporting continuations. That might be what you are thinking of.

-Justin

[1]Programming Ruby: The Pragmatic Programmer's Guide
[2]class Continuation - RDoc Documentation

Continuations are hard, so I won't touch them. Very good examples here:

<http://www.rubycentral.com/faq/rubyfaq-11.html&gt;

Closures are something I can handle (I discuss them in my AppleScript
book, for example).

* A binding is an association of a name and a value.

* A free variable is a variable defined in a surrounding scope.

* A closure is block of code where free variables are bound in
accordance with the surrounding scope and (this is important) retain
that binding.

So, for example:

var = 7
p = Proc.new {puts var}
def hereGoesNothing
  var = "yoho"
  yield
end
hereGoesNothing &p # => 7
var = 200
hereGoesNothing &p # => 200

The block "{puts var}" is a closure. Its "var" is a free variable and is
therefore bound to the "var" in the surrounding scope, which is the
"var" set to 7 in the first line. So what we see is that the "var"
inside hereGoesNothing makes no difference. As we change the top-level
"var", its new value is used each time we execute the block. It doesn't
matter what we do with p; it will retain its bindings.

Here's another example (more like your procs from functions idea):

def proc_maker
  var = 7
  Proc.new {puts var}
end
p = proc_maker
p.call # => 7

Here, "var" exists only inside the method "proc_maker". When we come to
call p, there is no "var"! But that doesn't matter; the proc "{puts
var}" has retained the binding of "var" with 7 from the place where it
was bound to start with, inside the method.

m.

···

Joe Ruby MUDCRAP-CE <joeat303@yahoo.com> wrote:

- Ruby has closures -- which seem to be returning procs from functions?
- Continuations may be planned for a future release of Ruby.

--
matt neuburg, phd = matt@tidbits.com, Matt Neuburg’s Home Page
Tiger - http://www.takecontrolbooks.com/tiger-customizing.html
AppleScript - http://www.amazon.com/gp/product/0596102119
Read TidBITS! It's free and smart. http://www.tidbits.com

- Continuations may be planned for a future release of Ruby.

If anybody can elaborate/correct, please feel free! Also, how would each
be useful?

Continuations represent "the rest of the computation". Try googling
continuations and continuation passing style. Here's an example of how
closures and continuations are useful, cooperative threading:

# threading.rb:

class Scheduler
  def initialize
    @threads =
  end

  def yield
    callcc do |continuation|
      @threads << continuation
      schedule
    end
  end

  def spawn
    callcc do |continuation|
      @threads << continuation
      yield
      schedule
    end
  end

  def schedule
    return if @threads.empty?
    @threads.shift.call
  end
end

def thread
  yield Scheduler.new
end

if $0 == __FILE__
  puts "Testing spawning and stuff..."

  thread { |scheduler|
    puts "In parent"
    scheduler.spawn {
      puts "In child"
      scheduler.yield
      puts "In child again"
    }
    puts "In parent again"
    scheduler.yield
  }
end

$ ruby threading.rb
Testing spawning and stuff...
In parent
In child
In parent again
In child again

···

On 10/27/06, Joe Ruby MUDCRAP-CE <joeat303@yahoo.com> wrote:

Thanks,
Joe

--
Posted via http://www.ruby-forum.com/\.

--
- Simen

http://onestepback.org/articles/invitationtoruby/reason4.html

Prasaad

···

On 10/28/06, Joe Ruby MUDCRAP-CE <joeat303@yahoo.com> wrote:

I've seen these mentioned in various places. From what I can tell:

- Ruby has closures -- which seem to be returning procs from functions?
- Continuations may be planned for a future release of Ruby.

If anybody can elaborate/correct, please feel free! Also, how would each
be useful?

Thanks,
Joe

--
Posted via http://www.ruby-forum.com/\.

One more question -- what are lambdas? :wink:

Joe

···

--
Posted via http://www.ruby-forum.com/.

could we say they work as anonymous class in java ???

···

Justin Collins <collinsj@seattleu.edu> wrote:

Closures are tricky, but you can think of them as blocks of code, or a
way of making code a first-class object. Or as anonymous functions.

This example reminded me of Modula-2's coroutines. Are these
concepts related somehow?

···

On 10/28/06, Simen Edvardsen <toalett@gmail.com> wrote:

Continuations represent "the rest of the computation". Try googling
continuations and continuation passing style. Here's an example of how
closures and continuations are useful, cooperative threading:

--
----------------------------------------------------
http://sobrerailes.com

This is a term from LISP. It basically just means a function that you
can define and then pass around and call. In my previous example (about
closures), the thing in curly braces, "{puts var}", was effectively a
lambda.

var = 7
p = Proc.new {puts var}
def hereGoesNothing
  var = "yoho"
  yield
end
hereGoesNothing &p # => 7
var = 200
hereGoesNothing &p # => 200

···

Joe Ruby MUDCRAP-CE <joeat303@yahoo.com> wrote:

One more question -- what are lambdas?

###

def proc_maker
  var = 7
  Proc.new {puts var}
end
p = proc_maker
p.call # => 7

In the first example, I form the function, I assign it to a variable,
and hand it (twice) to a method (hereGoesNothing) which calls it
(yield). In the second example, I form the function and hand it out as
the result of a method (proc_maker), assign it to a variable, and call
it (call).

LISPers like to celebrate this ability (among others) to treat a
function just like any other Thing, passing it around and so forth, by
chanting a poem (with apologies to JRR Tolkien) whose last three lines
are:

  One Thing to name them all, One Thing to define them,
  One Thing to place them in environments and bind them,
In the Lambda Order they are all first-class.

m.

--
matt neuburg, phd = matt@tidbits.com, Matt Neuburg’s Home Page
Tiger - http://www.takecontrolbooks.com/tiger-customizing.html
AppleScript - http://www.amazon.com/gp/product/0596102119
Read TidBITS! It's free and smart. http://www.tidbits.com

There are some similarities but also restrictions. For example you can only reference final variables from the current environment which means you cannot change them. That in turn is typically possible with closures:

irb(main):001:0> def counter(init=0) lambda {|*x| init += x[0]||1} end
=> nil
irb(main):002:0> c = counter
=> #<Proc:0x003a6254@(irb):1>
irb(main):003:0> c
=> 1
irb(main):004:0> c
=> 2
irb(main):005:0> c
=> 3
irb(main):006:0> c
=> 4
irb(main):007:0> c[10]
=> 14

In a way every class is a closure as its instances carry around some state they can always access. But the term "closure" is generally /not/ used for this - this is called "encapsulation".

Kind regards

    robert

···

"Une Bévue" <pere.noel@laponie.com.invalid> wrote:

Justin Collins <collinsj@seattleu.edu> wrote:

Closures are tricky, but you can think of them as blocks of code, or
a way of making code a first-class object. Or as anonymous functions.

could we say they work as anonymous class in java ???

Since continuations represent the state of the computation including the call stack, they can be used to implement coroutines. Methods can suspend computation and pass control around to other methods; when the continuation is called, computation will resume at the same point.

···

On Oct 28, 2006, at 10:22 AM, Juan Lupión wrote:

On 10/28/06, Simen Edvardsen <toalett@gmail.com> wrote:

Continuations represent "the rest of the computation". Try googling
continuations and continuation passing style. Here's an example of how
closures and continuations are useful, cooperative threading:

This example reminded me of Modula-2's coroutines. Are these
concepts related somehow?

matt neuburg wrote:

···

Joe Ruby MUDCRAP-CE <joeat303@yahoo.com> wrote:

One more question -- what are lambdas?

This is a term from LISP.

Actually, it is a term from Lambda Calculus, which existed long before
LISP or even computers.

jwm

is that "lambda" name derived from lambda calculus in modern logic, or
is it the reverse, lambda calculus deriving from lisp work ???

(i would think so because lambda calculus is aimed toward automatic
comilation from function down to machine language)

···

matt neuburg <matt@tidbits.com> wrote:

This is a term from LISP. It basically just means a function that you
can define and then pass around and call.

u're right !

···

Robert Klemme <shortcutter@googlemail.com> wrote:

In a way every class is a closure as its instances carry around some state
they can always access. But the term "closure" is generally /not/ used for
this - this is called "encapsulation".

matt neuburg wrote:
>> One more question -- what are lambdas?
> This is a term from LISP.

Actually, it is a term from Lambda Calculus, which existed long before
LISP or even computers.

The lambda calculus took it from the Greek Alphabet, who adapted it
from the Phoenecian Alphabet, and so on (you could keep going
forever). Actually closures are never called "lambdas", at least not
in any writing I've read on Lisp, it's just a symbol used to denote a
closure.

···

On 10/28/06, Jörg W Mittag <Joerg.Mittag@web.de> wrote:

> Joe Ruby MUDCRAP-CE <joeat303@yahoo.com> wrote:

jwm

--
- Simen

> This is a term from LISP. It basically just means a function that you
> can define and then pass around and call.

is that "lambda" name derived from lambda calculus in modern logic, or
is it the reverse, lambda calculus deriving from lisp work ???

The former. The lambda calculus was on the scene long before Lisp was a
twinkle in McCarthy's eye.

(i would think so because lambda calculus is aimed toward automatic
comilation from function down to machine language)

No it's not. It was a mathematical formalism for computation. Whatever gave
you that idea?

Here's the Wikipedia article: Lambda calculus - Wikipedia

K.

···

On Sat, Oct 28, 2006 at 10:05:18PM +0900, Une Bévue wrote:

matt neuburg <matt@tidbits.com> wrote:

--
Keith Gaughan -- kmgaughan@eircom.net -- http://talideon.com/
Peace means something different from "not fighting"... Peace is an active
and complex thing and sometimes fighting is part of what it takes to get it.
    -- Jo Walton

The lambda calculus took it from the Greek Alphabet, who adapted it
from the Phoenecian Alphabet, and so on (you could keep going
forever). Actually closures are never called "lambdas", at least not
in any writing I've read on Lisp, it's just a symbol used to denote a
closure.

A lambda is not necessary a closure. A lambda is an anonymous function (and
as you will see later, this is *not* a block or a Proc.new { ... })

The meaning of the lambda operator in languages like Ruby is "build an
anonymous function", and it does come from lambda calculus. Lambda (in
Ruby) is building a function (actually, a Proc) from a block.
The "closure" part comes from the fact that blocks are closures. If blocks
weren't closures, lambdas would not be either.

Calling 'return' in Proc.new { return }.call fails with LocalJumpError
while it works in lambda { return }.call . Kernel#lambda really changed
the block into a function.

My 2 cents

···

--
Sylvain Joyeux

Right. It's best just to think of lambda as a way to get anonymous
functions. It's more or less like Proc.new (close enough).

Closures are a property of functions, but they have much more to do
with lexical scoping. In fact, older lisps didn't have lexical
closures because because they were dynamically scoped. Also, there is
a mathematical property called closure that is referred to in lisp
texts which has nothing to do with lexical closures.

    x = 1
    (1..5).each {|i| i + x}

You can use the x variable because the block is a closure. Really,
you don't think about it too much, as it just does what you would
expect.

Unless you were expecting the wrong thing =)

···

On 10/28/06, Simen Edvardsen <toalett@gmail.com> wrote:

The lambda calculus took it from the Greek Alphabet, who adapted it
from the Phoenecian Alphabet, and so on (you could keep going
forever). Actually closures are never called "lambdas", at least not
in any writing I've read on Lisp, it's just a symbol used to denote a
closure.

--
Lou.