Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

lambda's method? Mats' example code confuse me .

def memoize
  cache = {}
  lambda { |*args| 
    unless cache.has_key?(args)
      cache[args] = self[*args]
    end
    cache [args]
  }
end

factorial =  lambda {|x| return 1 if x== 0; x*factorial[x-1];}.memoize

puts factorial.call 10

The code is from book "The ruby programming language ". But it confuse me : how can the method(memoize) apply to a lambda as its method? Can lambda followed by other lambda with dot(.) as its own method?

lambda {|x| return 1 if x== 0; x*factorial[x-1];}.memoize

BTW: The above code works in irb, but ruby interpreter encounter error as following:

memoize.rb:11: private method `memoize' called for #<Proc:[email protected]:11> (NoMethodError)

Why?

like image 375
lbaby Avatar asked Aug 13 '12 08:08

lbaby


People also ask

Can you give an example of lambda expression?

println( 2 *x); // This calls above lambda expression and prints 10. Multiple parameters : (p1, p2) -> System.

How do you calculate lambda example?

The formula for calculating lambda is: Lambda = (E1 – E2) / E1. Lambda may range in value from 0.0 to 1.0. Zero indicates that there is nothing to be gained by using the independent variable to predict the dependent variable. In other words, the independent variable does not, in any way, predict the dependent variable.

What is λ in math?

In mathematics and computer programming, the Lambda symbol is used to introduce "anonymous functions." Lambda notation distinguishes between variables used as mathematical arguments and variables that stand for predefined values.


1 Answers

Where you're saying this:

def memoize
  #...
end

I think you mean to say this:

class Proc
  def memoize
    #...
  end
end

That would add a public memoize method to Procs and lambda { ... } (or -> { ... } in newer Rubies) gives you a Proc instance.

Now on to memoize itself. Methods return the value of their last expression and for memoize, that last expression is this:

lambda { |*args| 
  unless cache.has_key?(args)
    cache[args] = self[*args]
  end
  cache [args]
}

So memoize returns a wrapper for the Proc (self) that is a closure over cache and all this wrapper does is:

  1. Check to see if cache has an entry for the argument list in question (the Array args) .
  2. If we don't have a cached value then compute the original Proc's value (self[*args]) and store it in the cache.
  3. Return the cached value.

You can use the [] method to execute a Proc so proc.call(a, b) is the same as proc[a, b].

like image 110
mu is too short Avatar answered Sep 20 '22 20:09

mu is too short