I am trying to understand why do we really need lambda or proc in ruby (or any other language for that matter)?
#method
def add a,b
c = a+b
end
#using proc
def add_proc a,b
f = Proc.new {|x,y| x + y }
f.call a,b
end
#using lambda function
def add_lambda a,b
f = lambda {|x,y| x + y}
f.call a,b
end
puts add 1,1
puts add_proc 1,2
puts add_lambda 1,3
I can do a simple addition using: 1. normal function def, 2. using proc and 3. using lambda.
But why and where use lambda in the real world? Any examples where functions cannot be used and lambda should be used.
It's true, you don't need anonymous functions (or lambdas, or whatever you want to call them). But there are a lot of things you don't need. You don't need classes—just pass all the instance variables around to ordinary functions. Then
class Foo
attr_accessor :bar, :baz
def frob(x)
bar = baz*x
end
end
would become
def new_Foo(bar,baz)
[bar,baz]
end
def bar(foo)
foo[0]
end
# Other attribute accessors stripped for brevity's sake
def frob(foo,x)
foo[0] = foo[1]*x
end
Similarly, you don't need any loops except for loop...end
with if
and break
. I could go on and on.1 But you want to program with classes in Ruby. You want to be able to use while
loops, or maybe even array.each { |x| ... }
, and you want to be able to use unless
instead of if not
.
Just like these features, anonymous functions are there to help you express things elegantly, concisely, and sensibly. Being able to write some_function(lambda { |x,y| x + f(y) })
is much nicer than having to write
def temp(x,y)
x + f(y)
end
some_function temp
It's much bulkier to have to break off the flow of code to write out a def
fed function, which then has to be given a useless name, when it's just as clear to write the operation in-line. It's true that there's nowhere you must use a lambda, but there are lots of places I'd much rather use a lambda.
Ruby solves a lot of the lambda-using cases with blocks: all the functions like each
, map
, and open
which can take a block as an argument are basically taking a special-cased anonymous function. array.map { |x| f(x) + g(x) }
is the same as array.map(&lambda { |x| f(x) + g(x) })
(where the &
just makes the lambda "special" in the same way that the bare block is). Again, you could write out a separate def
fed function every time—but why would you want to?
Languages other than Ruby which support that style of programming don't have blocks, but often support a lighter-weight lambda syntax, such as Haskell's \x -> f x + g x
, or C#'s x => f(x) + g(x);
2. Any time I have a function which needs to take some abstract behavior, such as map
, or each
, or on_clicked
, I'm going to be thankful for the ability to pass in a lambda instead of a named function, because it's just that much easier. Eventually, you stop thinking of them as somehow special—they're about as exciting as literal syntax for arrays instead of empty().append(1).append(2).append(3)
. Just another useful part of the language.
1: In the degenerate case, you really only need eight instructions: +-<>[].,
. <>
move an imaginary "pointer" along an array; +-
increment and decrement the integer in the current cell; []
perform a loop-while-non-zero; and .,
do input and output. In fact, you really only need just one instruction, such as subleq a b c
(subtract a
from b
and jump to c
if the result is less than or equal to zero).
2: I've never actually used C#, so if that syntax is wrong, feel free to correct it.