When are lambdas needed?

I have seen many tutorials on the Internet explaining where lambdas
CAN be used, such as clever multiplication functions, but when are
they actually NEEDED?

Sure, I can take a lambda and "pass it around" so to speak, but I can
call a function from anywhere too, right?

Can somebody give me an extremely useful, NOT complicated, example of
when lambdas are the absolute perfect solution to a problem?

Thanks!

Every time you use a block in ruby you're using a lambda implicitly.

···

On Thu, Apr 17, 2008 at 5:35 PM, Stedwick <philip.brocoum@gmail.com> wrote:

Can somebody give me an extremely useful, NOT complicated, example of
when lambdas are the absolute perfect solution to a problem?

--
Avdi

Home: http://avdi.org
Developer Blog: Avdi Grimm, Code Cleric
Twitter: http://twitter.com/avdi
Journal: http://avdi.livejournal.com

Stedwick wrote:

I have seen many tutorials on the Internet explaining where lambdas
CAN be used, such as clever multiplication functions, but when are
they actually NEEDED?

Sure, I can take a lambda and "pass it around" so to speak, but I can
call a function from anywhere too, right?

Can somebody give me an extremely useful, NOT complicated, example of
when lambdas are the absolute perfect solution to a problem?

Thanks!

lambda is like a function pointer in c/c++.
Let me give you an example.

hello = lambda { "Hello" }
hello.call
=> "Hello"
hello = lambda { "World" }
hello.call
=> "World"

HTH,
Minseok Choi

cache :index, :ttl => 42, :key => lambda{ request['important'] }

this is a class level method which says

"cache the index method, invalidating every 42 seconds, by using the current request's 'important' value from the query"

note that in this cast the lambda will be instance_eval'd - so when we say 'request' here it will ultimately mean the current request

another example:

   def each &block

     @list.each &block

  end

here we need to have captured the calling block's scope in other to relay it along to our internal @list object's each method. it's NOT the case that we want the scope if the function for this lambda, what we want is logic bound to the scope of the caller

lambda are perfect anytime you want a context sensitive result and don't want to code everything in one massive global scope.

a @ http://codeforpeople.com/

···

On Apr 17, 2008, at 3:35 PM, Stedwick wrote:

Can somebody give me an extremely useful, NOT complicated, example of
when lambdas are the absolute perfect solution to a problem?

--
we can deny everything, except that we have the possibility of being better. simply reflect on that.
h.h. the 14th dalai lama

"Stedwick" <philip.brocoum@gmail.com> wrote in message
news:9568e4ae-6c60-4d8f-b460-7d9f414bcee9@l42g2000hsc.googlegroups.com...

I have seen many tutorials on the Internet explaining where lambdas
CAN be used, such as clever multiplication functions, but when are
they actually NEEDED?

Sure, I can take a lambda and "pass it around" so to speak, but I can
call a function from anywhere too, right?

Can somebody give me an extremely useful, NOT complicated, example of
when lambdas are the absolute perfect solution to a problem?

Thanks!

One main use is precisely when you don't need to pass anything around - you
need a one-off function, and probably the function isn't particularly
complicated. Typical examples are when supplying a code block to a sort,
group, map or filter function.

Are they needed? No. But then again, neither are subroutines or modules or
for loops...

AHS

the lambda expression came from the lisp community, it's kind of
abstraction of procedures.
in oo languages it's usually difficult to extend methods than extend
data structures.
ruby or other modern programming languages did a great job to mix them together.
well , back to the topic, imo to fully understand the power of
lambda(or abstraction), one has to look into the lisp/scheme world :slight_smile:

···

On Fri, Apr 18, 2008 at 5:35 AM, Stedwick <philip.brocoum@gmail.com> wrote:

I have seen many tutorials on the Internet explaining where lambdas
CAN be used, such as clever multiplication functions, but when are
they actually NEEDED?

Sure, I can take a lambda and "pass it around" so to speak, but I can
call a function from anywhere too, right?

Can somebody give me an extremely useful, NOT complicated, example of
when lambdas are the absolute perfect solution to a problem?

Thanks!

Stedwick <philip.brocoum@gmail.com> writes:

I have seen many tutorials on the Internet explaining where lambdas
CAN be used, such as clever multiplication functions, but when are
they actually NEEDED?

Sure, I can take a lambda and "pass it around" so to speak, but I can
call a function from anywhere too, right?

Can somebody give me an extremely useful, NOT complicated, example of
when lambdas are the absolute perfect solution to a problem?

Lambdas are anonymous function.

As long as you can give a name to all the functions, they're not
needed, you can just define (ie. name) a function, and give that
function by name instead of using lambda.

But that's the very point! One gets fed up in having to come with
names for ALL the little functions we can encounter in a program.

Like if you went on a road, and gave a name to all the little peebles
you encounter, keeping with you a picture of each peeble with the
associated (unique!) name in your notebook. What a big useless
notebook!

Also, lambdas (closures actually) are equivalent to classes (objects).
So, as long as you can write a class (give it a name!), and
instanciate an object, everywhere you would use lambdas, they're not
needed. But what a burden!

Compare:

···

------------------------------------------------------------------------
def example
  array=[1,2,3,4]
  array.each{|i| print i," -> ",i+i,"\n" }
  array.each{|i| print i," -> ",i*i,"\n" }
  ...
  :done
end
------------------------------------------------------------------------

vs.

------------------------------------------------------------------------
def printDouble(i)
  print i," -> ",i+i,"\n"
end
def printSquare(i)
  print i," -> ",i*i,"\n"
end
...
class Array
  def callForEach(f)
     for i in 0..self.size()-1 do
        f.call(self[i])
     end
  end
end
def example
  array=[1,2,3,4]
  array.callForEach(method(:printDouble))
  array.callForEach(method(:printSquare))
  :done
end
------------------------------------------------------------------------

and compare:

------------------------------------------------------------------------
def example
  k=42
  array=[1,2,3,4]
  array.each{|i| print i," -> ",i+k,"\n" }
  array.each{|i| print i," -> ",i*k,"\n" }
  :done
end
------------------------------------------------------------------------

vs.

------------------------------------------------------------------------
class Adder
   def initialize(k)
      @k=k
   end
   def run(i)
      print i," -> ",i+@k,"\n"
   end
end

class Multiplier
   def initialize(k)
      @k=k
   end
   def run(i)
      print i," -> ",i*@k,"\n"
   end
end

class Array
  def sendRunWithEach(o)
     for i in 0..self.size()-1 do
        o.run(self[i])
     end
  end
end

def example
  k=42
  array=[1,2,3,4]
  array.sendRunWithEach(Adder.new(k))
  array.sendRunWithEach(Multiplier.new(k))
  :done
end
------------------------------------------------------------------------

So if you have a lot of time, a lot of memory, and a lot of fingers,
perhaps you can do without lambda, but us poor mortals just need it.

--
__Pascal Bourguignon__

How about using lambda as representing recursive type and
implemeting lazy evaluation in easygoing way.

class Natural
def initialize
   @succ = lambda {Natural.new}
end

def take(maximum)
   [1] + if maximum == 1
           
         else
           @succ.call.take(maximum - 1)
         end
end

def accumulate(num, result = 0)
   if num == 0
      result
   else
      accumulate(num - 1, result + 1)
   end
end

def summate(maximum)
   if maximum == 1
     1
   else
     accumulate(maximum) + summate(maximum - 1)
   end
end

def filter(index = 1,result = , &block)
   num = accumulate(index)
   if yield(num) == true
     result << num
     filter(index + 1,result, &block)
   else
     result
   end
end
end

irb(main):040:0> n = Natural.new
#<Natural:0xb7a970ec @succ=#<Proc:0xb7a9c2a4@(irb):3>>

irb(main):041:0> n.take(100)
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]

irb(main):042:0> n.accumulate(100)
100

irb(main):043:0> n.filter {|i| i < 10}
[1, 2, 3, 4, 5, 6, 7, 8, 9]

irb(main):045:0> n.summate(100)
5050

···

On Fri, 18 Apr 2008 06:35:08 +0900 Stedwick <philip.brocoum@gmail.com> wrote:

I have seen many tutorials on the Internet explaining where lambdas
CAN be used, such as clever multiplication functions, but when are
they actually NEEDED?

Sure, I can take a lambda and "pass it around" so to speak, but I can
call a function from anywhere too, right?

Can somebody give me an extremely useful, NOT complicated, example of
when lambdas are the absolute perfect solution to a problem?

Thanks!

--
Akimichi Tatsukawa

I have seen many tutorials on the Internet explaining where lambdas
CAN be used, such as clever multiplication functions, but when are
they actually NEEDED?

Well, there is always a workaround, so no language feature is actually "needed" in the strict sense of the word.

Sure, I can take a lambda and "pass it around" so to speak, but I can
call a function from anywhere too, right?

Yes, but a lambda is an object which makes certain things very nice.

Can somebody give me an extremely useful, NOT complicated, example of
when lambdas are the absolute perfect solution to a problem?

I like to use them when I have to efficiently choose an algorithm based on some value:

algos = {
   "print" => lambda {|x| puts x},
   "ignore" => lambda {|x| },
   "log" => lambda {|x| File.open("log","w") {|io| io.puts x}},
}

Now you can efficiently call a function based on some input

...each do |x,y|
   algos[y]
end

Yes, I know the example is artificial and yes, you can do it with an object and #send as well. But if keys are not Strings or have different types then this approach is simpler.

Kind regards

  robert

···

On 17.04.2008 23:33, Stedwick wrote:

I have seen many tutorials on the Internet explaining where lambdas
CAN be used, such as clever multiplication functions, but when are
they actually NEEDED?

Sure, I can take a lambda and "pass it around" so to speak, but I can
call a function from anywhere too, right?

Sure, you can call methods from almost anywhere. But you can't pass them
around (unless you turn them into proc objects, in which case you are back to
using lambdas.) And passing them around is necessary if you didn't write (and
don't want to have to monkeypatch) all the library, etc., code from which you
may want to perform a particular task. If those libraries are written to let you
pass in proc objects, you are in good shape.

Can somebody give me an extremely useful, NOT complicated, example of
when lambdas are the absolute perfect solution to a problem?

Callbacks.

···

On Thu, Apr 17, 2008 at 2:35 PM, Stedwick <philip.brocoum@gmail.com> wrote:

Avdi Grimm wrote:

Can somebody give me an extremely useful, NOT complicated, example of
when lambdas are the absolute perfect solution to a problem?

Every time you use a block in ruby you're using a lambda implicitly.

Implicitly, but not really. I wonder, was the original question more like "what are blocks for?" or "yes, I know what blocks are for, but why are there also these Proc objects, which are instantiated with the lambda construct?"

If the latter, then one answer is: when you need the program state that is encapsulated in a block to persist outside of the method in which it is used. For example, this happens in event-based frameworks: a setup method in a client class registers lambdas as event handlers; the framework doesn't need to know the classes or methods of the client class, hence loose coupling. As a bonus, these handlers can refer to shared program state (local variables) in the setup method.

···

On Thu, Apr 17, 2008 at 5:35 PM, Stedwick <philip.brocoum@gmail.com> wrote:

--
       vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407

lambda are perfect anytime you want a context sensitive result and
don't want to code everything in one massive global scope.

My problem with lambda's is that I have a hard time to find a
real use case for them. I am not sure of some use case with
lambda {} that brings a definite advantage over i.e. just
using some special object or simple method.

···

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

Lambda comes from lambda calculus. The fact that LISP uses them is just a
happy coincidence.

But let's compare LISP and Ruby for a moment.

In LISP, any time you want to pass an unnamed ad-hoc function to another
function, you define it like (lambda (var1 var2) (code)), so you wind up
using the lambda macro a lot. You might have
(mapcar #'(lambda (x) (* x x)) '(1 2 3 4))
which returns
(1 4 9 16)

In Ruby, you do this kind of thing a lot too. Only we have syntactic
sugar that makes things a little nicer in many cases. The equivalent code
to the LISP example is
[1 2 3 4].map{|x| x*x}
so you just used a lambda, but didn't have to type the keyword.

There's one thing to know though. Kernel#proc and Kernel#lambda have
slightly different semantics when it comes to the return, next, and break
keywords. Kernel#lambda does things one way, and Kernel#proc or a bare
block do things the other way. So really, Ruby uses lambdas a lot (maybe
even more than LISP) but we just don't use the term very much, mostly
because we've shortened the syntax.

···

On Thu, 17 Apr 2008 20:50:18 -0500, zuo peng wrote:

the lambda expression came from the lisp community, it's kind of
abstraction of procedures.
in oo languages it's usually difficult to extend methods than extend
data structures.
ruby or other modern programming languages did a great job to mix them
together. well , back to the topic, imo to fully understand the power of
lambda(or abstraction), one has to look into the lisp/scheme world :slight_smile:

--
Ken (Chanoch) Bloom. PhD candidate. Linguistic Cognition Laboratory.
Department of Computer Science. Illinois Institute of Technology.
http://www.iit.edu/~kbloom1/

So what is an eminent lisper doing posting on c.l.r - considering a
switch? :slight_smile:

···

On Apr 18, 5:13 am, p...@informatimago.com (Pascal J. Bourguignon) wrote:

Stedwick <philip.broc...@gmail.com> writes:
> I have seen many tutorials on the Internet explaining where lambdas
> CAN be used, such as clever multiplication functions, but when are
> they actually NEEDED?

> Sure, I can take a lambda and "pass it around" so to speak, but I can
> call a function from anywhere too, right?

> Can somebody give me an extremely useful, NOT complicated, example of
> when lambdas are the absolute perfect solution to a problem?

Lambdas are anonymous function.

As long as you can give a name to all the functions, they're not
needed, you can just define (ie. name) a function, and give that
function by name instead of using lambda.

But that's the very point! One gets fed up in having to come with
names for ALL the little functions we can encounter in a program.

Joel VanderWerf wrote:

If the latter, then one answer is: when you need the program state that
is encapsulated in a block to persist outside of the method in which it
is used. For example, this happens in event-based frameworks: a setup
method in a client class registers lambdas as event handlers; the
framework doesn't need to know the classes or methods of the client
class, hence loose coupling. As a bonus, these handlers can refer to
shared program state (local variables) in the setup method.

That's probably the clearest illustration I've ever read of when to use
a block. Thank you.

I hope others chime in, too, as I couldn't imagine programming without
the "implicit usage" of blocks (e.g. each, select, collect, etc.) but
have never used them for the purpose Joel described.

I just got "done" designing a delivery system, and although I'm happy
with it, I wonder if it could be done with blocks. (I re-read that
statement and it sounds stupid: 'done with blocks'. I'll simply trust
you see the absurdity of the statement and understand what I was trying
to say...)

···

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

Technically, you can replace every lambda with
an class and an instance thereof. The difference is that
the lambda is syntactically and semantically more lightweight.

To add another example, Rake tasks store away lambdas.

    my_lib_version = "1.0.2"

    task :tgz do
      sh "tar -czf my_lib-#{my_lib_version}.tgz lib"
    end

Assuming a Ruby-like language without lambdas,
we'd get this "pure OO" Rakefile:

    class TgzTask
      def initialize(version)
        @version = version
      end
      def execute
        sh "tar -czf my_lib-#@version.tgz lib"
      end
    end

    my_lib_version = "1.0.2"

    task :tgz, TgzTask.new(my_lib_version)

All context we need in our method (local variables,
eventually the current "self") has to be explicetely
passed to the constructor, which has to initialize
our object etc. Rake would loose all its appeal.

Stefan

···

2008/4/18, Marc Heiler <shevegen@linuxmail.org>:

> lambda are perfect anytime you want a context sensitive result and
> don't want to code everything in one massive global scope.

My problem with lambda's is that I have a hard time to find a
real use case for them. I am not sure of some use case with
lambda {} that brings a definite advantage over i.e. just
using some special object or simple method.

a lambda is a special object - on that knows about every variable in scope. have fun maintaining code that populates that object by hand :wink:

the entire point of lambdas is that the language already *has* a scope. so, sure, you can cherry pick the required variables and populate an object, but you can also make loops with GOTO - lambda is merely an abstraction.

the 'definite' bit comes in because you don't HAVE to do ANYTHING. you simply write this code

sum = 0

list.each do |i|

   sum += i

end

and you don't have to write anything special, the environment is captured, the code is evaulated in the captured context, but you don't have to build a special summing function that take i and a sum var.

so it 'definitely' is an advantage - that is unless you don't happen to think less code is advantageous over more...

cheers.

a @ http://codeforpeople.com/

···

On Apr 17, 2008, at 6:47 PM, Marc Heiler wrote:

My problem with lambda's is that I have a hard time to find a
real use case for them. I am not sure of some use case with
lambda {} that brings a definite advantage over i.e. just
using some special object or simple method.

--
we can deny everything, except that we have the possibility of being better. simply reflect on that.
h.h. the 14th dalai lama

one more note

if you use

open(path){|fd| p fd.read}

array.each{|i| p i}

or

hash.each{|k,v| p k,v}

you've found a use for them :wink:

a @ http://codeforpeople.com/

···

On Apr 17, 2008, at 6:47 PM, Marc Heiler wrote:

My problem with lambda's is that I have a hard time to find a
real use case for them

--
we can deny everything, except that we have the possibility of being better. simply reflect on that.
h.h. the 14th dalai lama

Short answer: they are more more concise and convenient.

Ever use C++ STL? In this library a "functor" is a very important concept
(for various comparators, visiting objects, etc). You make a functor by
defining a class with a primary method for functor's functionality
("operator()"). It might also have some state (possibly maintained through
other methods) or references to things external to the functor.

In ruby, this type of thing is done with blocks and lambdas. But, it is a
lot more concise and convenient. Because blocks/lambdas have access to
variables in the scope where they are defined (which can also be used to
create state), there shouldn't be a need to create dedicated "functor"
classes.

I code in C++ everyday and miss the not having closures. From what I've
read, C++ will get closures (like ruby has had since day 1) in the next
release (C++0x).

Eric

···

On 4/17/08, Marc Heiler <shevegen@linuxmail.org> wrote:

> lambda are perfect anytime you want a context sensitive result and
> don't want to code everything in one massive global scope.

My problem with lambda's is that I have a hard time to find a
real use case for them. I am not sure of some use case with
lambda {} that brings a definite advantage over i.e. just
using some special object or simple method.

There are about a zillion ways to get and use a Proc object in Ruby

def foo
  yield 1
end

def bar &baz
  #baz is a Proc object, and you can pass
  #that proc object to another method that takes a block
  foo &baz
end

a=lambda{|x| x*x}
#a is a Proc object

b=proc{|x| x*x}
#b is a Proc object

c=Proc.new{|x| x*x}
#c is a Proc object

c.call 2
=>4
#you can also use #call on a Proc object

c[2]
=>4
#or you can "index" it like an Array (which is just a synonym for #call)

The difference between lambda and the other ways of getting a Proc object
is that lambda treats return, next, and break a little bit differently.

In other languages (specifically LISP) use of LAMBDA is the most common
way to create closures. In Ruby, it's one of the rarest.

--Ken

···

On Thu, 17 Apr 2008 16:58:44 -0500, Joel VanderWerf wrote:

Avdi Grimm wrote:

On Thu, Apr 17, 2008 at 5:35 PM, Stedwick <philip.brocoum@gmail.com> >> wrote:

Can somebody give me an extremely useful, NOT complicated, example of
when lambdas are the absolute perfect solution to a problem?

Every time you use a block in ruby you're using a lambda implicitly.

Implicitly, but not really. I wonder, was the original question more
like "what are blocks for?" or "yes, I know what blocks are for, but why
are there also these Proc objects, which are instantiated with the
lambda construct?"

If the latter, then one answer is: when you need the program state that
is encapsulated in a block to persist outside of the method in which it
is used. For example, this happens in event-based frameworks: a setup
method in a client class registers lambdas as event handlers; the
framework doesn't need to know the classes or methods of the client
class, hence loose coupling. As a bonus, these handlers can refer to
shared program state (local variables) in the setup method.

--
Ken (Chanoch) Bloom. PhD candidate. Linguistic Cognition Laboratory.
Department of Computer Science. Illinois Institute of Technology.
http://www.iit.edu/~kbloom1/