Saturday, May 19, 2012

What is the equivalent of a lambda function in ruby and how is it used?

In python, you can define a lambda function with funct = lambda x: x*x, and from then on funct will be a callable function that takes one argument and returns the square of the argument. In ruby, the equivalent system is called a Proc (procedure) object.

A proc is basically just an object that takes a block at its instantiation. For example, you could say funct = Proc.new {|x| x*x}, and then funct would be a proc object equivalent to the python example above. Proc objects CANNOT be called like regular functions, however: you can't say puts funct(4), or anything like that. You CAN, however, invoke the block of the proc object with funct[4] (straight brackets) or by calling the call method: funct.call(6).

There are a couple of other notations for instantiating proc objects. If you say proc {block}, it's the exact same thing as saying Proc.new {block}. You can also say lambda {block}, which will give you almost the same proc object.

Interestingly, proc objects with lambda declarations and proc declarations are slightly different. Proc object defined procs, if passed more arguments than are accounted for in their blocks, will simply cut off the extra arguments and proceed like nothing happened. Lambda defined procs will, in the same situation, throw an ArgumentError. Example: funct[2,3,4,5] will return 4 if it was instantiated with proc {|x| x*x}, but it will ArgumentError if it was instantiated with lambda {|x| x*x}.

I am really not sure why this distinction was even included in ruby at all; perhaps it was a backwards compatibility issue, but it seems to me that any function, whether represented by an actual function or a proc object, should throw an error when given the incorrect number of arguments. Just seems like it would make bugs a lot easier to find that way. You can check whether the proc was generated with a lambda expression using the Proc.lambda? function.

Procs also have some other cool methods, specifically for hashing and finding the number of arguments and currying. I would again direct you to the ruby doc page for more info. As for the useful part...they're as useful as any other function, and maybe even more since they can me passed around. Entirely first class!

So that's what the equivalent of a lambda function is in ruby, and that's how it's useful.

No comments:

Post a Comment