What do you call the -> operator as in the following?
->(...) do
...
end
Aren't the following snippets equivalent?
succ = ->(x) {x + 1}
succ = lambda {|x| x + 1}
In Ruby Programming Language ("Methods, Procs, Lambdas, and Closures"), a lambda defined using -> is called lambda literal.
succ = ->(x){ x+1 }
succ.call(2)
The code is equivalent to the following one.
succ = lambda { |x| x + 1 }
succ.call(2)
Informally, I have heard it being called stabby lambda or stabby literal.
=> == Hash Rocket
Separates keys from values in a hash map literal.
-> == Dash Rocket
Used to define a lambda literal in Ruby 1.9.X (without args) and Ruby 2.X (with args). The examples you give (->(x) { x * 2 } & lambda { |x| x * 2 }) are in fact equivalent.
->(x) { ... } is the same as lambda { |x| ... }. It creates a lambda. See Kernel#lambda A lambda is a type of proc, one that ensures the number of parameters passed to it is correct. See also Proc::new and Kernel#proc.
Related
I am trying to use lambdas as blocks for an array each:
(1..10).each ->(i) {p i}
But I get this error:
ArgumentError: wrong number of arguments (given 1, expected 0)
Why does it happen? The lambda has exactly one argument.
Range#each doesn't take a lambda, it takes a block. The lambda is being passed as an argument, which Range#each is not expecting. Try this instead:
(1..10).each { |i| p i }
You can convert a lambda if you are so inclined:
lam = ->(i) { p i }
(1..10).each(&lam)
In order to understand the functional programming part of ruby I want to write a function that takes 2 functions f(x,y),g(x) as arguments and returns a new function h(x,y)=f(g(x),g(y)).
def foo(x, y)
return x+y
end
def bar(x)
return 2*x
end
def comp(f,g)
end
f=comp(f,g)
f(1,2) #=> 6
I tried things like
def comp(f,g)
mylambda = lambda {|x,y| return f(g(x),g(y))}
return mylambda
end
f=comp(foo, bar)
f.call(1,2)
I thought f would be a Proc now, and I could just call it. But apparently "in `foo': wrong number of arguments (0 for 2) (ArgumentError)"
What syntax would I have to use? And is it possible to return a "real" function instead of a Proc, so that instead of f.call(1,2) I could just writhe f(1,2) like if I had just defined f myself normaly?
This type of functional pattern doesn't work as smoothly as on more functional languages, as javascript or python. Since ruby has optional parentheses, writing foo is the same as calling the foo method without passing any arguments.
To get a reference to a method, you need to use the Object#method method:
def foo(x, y)
x + y
end
def bar(x)
x * 2
end
def comp(f, g)
lambda { |x, y| f.call(g.call(x), g.call(y)) }
end
h = comp(method(:foo), method(:bar))
h.call(1, 2) # => 6
Ruby doesn't have first class functions like Python. Ruby has lambdas, and method objects that can be constructed specially from a method, but methods themselves are not objects. The closest you'll get to this is this:
def foo(x, y)
return x+y
end
def bar(x)
return 2*x
end
def comp(f,g)
return lambda {|x, y| f.call(g.call(x), g.call(y))}
end
f=comp(method(:f),method(:g))
f.call(1,2) #=> 6
Also, for the calling syntax point, you can call a lambda with square brackets, so you could do this:
f[1,2]
What you have there aren't functions, they are methods. Functions (more precisely: procedures) are defined like this:
foo = -> (x, y) { x + y }
bar = -> x { 2 * x }
comp = -> (f, g) { -> (x, y) { f.(g.(x), g.(y)) } }
f = comp.(foo, bar)
f.(1, 2) #=> 6
Try this:
def foo() lambda {|x,y| x+y} end
def bar() lambda {|x| 2*x} end
def comp(f,g) lambda {|x,y| f[g[x], g[y]]} end
h = comp(foo, bar)
h[1,2] # => 6
or any of the following
h.call(1,2) # => 6
h.(1,2) # => 6
h.yield(1,2) # => 6
If you'd prefer,
foo = lambda {|x,y| x+y}
bar = lambda {|x| 2*x}
Before this question I was unaware of the myriad of ways one can now invoke a lambda (or proc). (The rationale for providing Proc#yield escapes me, as it is the same as call and may be confused with the unrelated yield keyword we all know and love.) One could substitute Proc.new or proc for lambda, or create the lambda with the "stabby" syntax -> (e.g., def bar() ->(x) {2*x} end.
f=comp(foo, bar)
This won't work like it would in python. The error message you're getting is wanting to see something like this.
f = comp(foo(1,2), bar(1))
You need to actually make foo and bar lambdas themselves (or methods that return lambdas) if you want to call it like that:
foo = lambda { |x, y| x + y }
bar = lambda { |x| 2 * x }
or
def foo(x, y)
lambda { |x, y| x + y}
end
def bar(x)
lambda { |x| 2 * x }
end
Then you can achieve what you want to do.
I want to create a new lambda taking no arguments from lambda taking one.
Say, I have
irb(main):001:0> f1 = lambda { |p| p }
=> #<Proc:0x00000001045190#(irb):1 (lambda)>
irb(main):002:0> f1.call(2)
=> 2
and now I
irb(main):003:0> f2 = lambda { f1.call(2) }
=> #<Proc:0x00000000f620e8#(irb):3 (lambda)>
irb(main):004:0> f2.call
=> 2
but I do not want to create a lambda around first one but want to "substitute" parameter for it or something.
May be if we have call, there is some magic that do the same thing as call, but returns a lambda except of actually calling the code:
f2 = f1.some_magic(2)
f2.call
=> 2
P.S. Sorry if this question is dumb, this functional stuff is hard to understand to me sometimes.
P.P.S. Found this topic on ruby-forum.com, and it seems I want to do the same things without unnecessary calls overhead.
You could create a function which binds the arguments to a proc. This works with Ruby >= 1.8:
def bind_args(l, *bound_args)
lambda { |*unbound_args|
l[*(bound_args + unbound_args)]
}
end
In use:
f1 = lambda { |p| p }
f2 = bind_args(f1, 2)
p f2.call
# 2
If you want to bind some, but not all arguments, you can do that too:
f1 = lambda { |p, q| [p, q] }
f2 = bind_args(f1, 2)
p f2.call(3)
# [2, 3]
Except that curry makes a call rather than a new lambda if given the full arguments to the lambda being bound, this is pretty much what curry does. I didn't call it curry to avoid confusion with the method of that name that's built into Ruby 1.9.
Are you looking for curry ?:
f1 = lambda { |p| p }
p f1.curry[2] #=> 2
Curry is available in Ruby 1.9
Is there a straightforward way in Ruby to produce a copy of a Proc?
I have a Proc called #foo. I want another method to periodically augment #foo with additional logic. For example:
# create initial Proc
#foo = lambda { |x| x }
# augment with more logic
#foo = lambda { |x| x > 1 ? x*x : #foo[x] }
I don't want the second line that does the augmentation to produce a recursive function. Instead, I want #foo to be bound by value into the lexical scope of the new #foo definition, producing a function that looks more like this:
#foo = lambda { |x| x > 1 ? x*x : lambda{ |x| x }[x] }
I get an infinite recursion and an eventual stack overflow instead, due to the resulting function looking like this:
#foo = lambda { |x| x > 1 ? x*x : lambda { |x| x > 1 ? x*x : { lambda |x| # etc...
I'd like the code to be like this:
# augment with more logic
#foo = lambda { |x| x > 1 ? x*x : (#foo.clone)[x] }
but clone doesn't work on Procs.
Additionally, the standard Ruby deep copy hack, using marshal and unmarshal, doesn't work on Procs either. Is there some way to do this?
Even if clone would work on Procs, it wouldn't help you, because you'd still be calling clone on the new value of #foo, not on the previous one like you want.
What you can do instead is just store the old value of #foo in a local variable that the lambda can close over.
Example:
def augment_foo()
old_foo = #foo
#foo = lambda { |x| x > 1 ? x*x : old_foo[x] }
end
This way old_foo will refer to the value that #foo had when augment_foo was called and everything will work as you want.
I want to be able to write a lambda/Proc in my Ruby code, serialize it so that I can write it to disk, and then execute the lambda later. Sort of like...
x = 40
f = lambda { |y| x + y }
save_for_later(f)
Later, in a separate run of the Ruby interpreter, I want to be able to say...
f = load_from_before
z = f.call(2)
z.should == 42
Marshal.dump does not work for Procs. I know Perl has Data::Dump::Streamer, and in Lisp this is trivial. But is there a way to do it in Ruby? In other words, what would be the implementation of save_for_later?
Edit: My answer below is nice, but it does not close over free variables (like x) and serialize them along with the lambda. So in my example ...
x = 40
s = save_for_later { |y| x + y }
# => "lambda { |y|\n (x + y)\n}"
... the string output does not include a definition for x. Is there a solution that takes this into account, perhaps by serializing the symbol table? Can you access that in Ruby?
Edit 2: I updated my answer to incorporate serializing local variables. This seems acceptable.
Use Ruby2Ruby
def save_for_later(&block)
return nil unless block_given?
c = Class.new
c.class_eval do
define_method :serializable, &block
end
s = Ruby2Ruby.translate(c, :serializable)
s.sub(/^def \S+\(([^\)]*)\)/, 'lambda { |\1|').sub(/end$/, '}')
end
x = 40
s = save_for_later { |y| x + y }
# => "lambda { |y|\n (x + y)\n}"
g = eval(s)
# => #<Proc:0x4037bb2c#(eval):1>
g.call(2)
# => 42
This is great, but it does not close over free variables (like x) and serialize them along with the lambda.
To serialize variables also, you can iterate over local_variables and serialize them as well. The problem, though, is that local_variables from within save_for_later accesses only c and s in the code above -- i.e. variables local to the serialization code, not the caller. So unfortunately, we must push the grabbing of local variables and their values to the caller.
Maybe this is a good thing, though, because in general, finding all free variables in a piece of Ruby code is undecidable. Plus, ideally we would also save global_variables and any loaded classes and their overridden methods. This seems impractical.
Using this simple approach, you get the following:
def save_for_later(local_vars, &block)
return nil unless block_given?
c = Class.new
c.class_eval do
define_method :serializable, &block
end
s = Ruby2Ruby.translate(c, :serializable)
locals = local_vars.map { |var,val| "#{var} = #{val.inspect}; " }.join
s.sub(/^def \S+\(([^\)]*)\)/, 'lambda { |\1| ' + locals).sub(/end$/, '}')
end
x = 40
s = save_for_later(local_variables.map{ |v| [v,eval(v)] }) { |y| x + y }
# => "lambda { |y| _ = 40; x = 40;\n (x + y)\n}"
# In a separate run of Ruby, where x is not defined...
g = eval("lambda { |y| _ = 40; x = 40;\n (x + y)\n}")
# => #<Proc:0xb7cfe9c0#(eval):1>
g.call(2)
# => 42
# Changing x does not affect it.
x = 7
g.call(3)
# => 43
Use sourcify
This will work on Ruby 1.8 or 1.9.
def save_for_later(&block)
block.to_source
end
x = 40
s = save_for_later {|y| x + y }
# => "proc { |y| (x + y) }"
g = eval(s)
# => #<Proc:0x00000100e88450#(eval):1>
g.call(2)
# => 42
See my other answer for capturing free variables.
Update:
Now you can also use the serializable_proc gem, which uses sourcify, and captures local, instance, class, and global variables.
Check out the answers to this question.
Ruby has the Marshal class that has a dump method that you can call.
Take a look here:
http://rubylearning.com/satishtalim/object_serialization.html