views:

200

answers:

5
+5  Q: 

Lambda functions

I'm really interested how lambda functions are used. Does it make sense to use them in a modern, high-level programming language like php? If yes, why?

Is this really just a function embedded in a function (like this) or is there more behind them?

+7  A: 

A lambda term represents a function as a value. It can be passed around exactly as a value (as it is one) and yet applied by giving it some arguments. Named functions are just names that map to lambda terms, either as constants or variables (depending on the language details).

And yes, they are quite prevalent in high-level programming languages. For example, all functions in JavaScript are actually lambda terms stored in variables.

Donal Fellows
+4  A: 

A lambda function is an object (or value). It can be passed as an argument to another function, or returned from one.

map(lambda x: x**2, [1,2,3,4])

It doesn't need a name; when you create one with (e.g. in Python) lambda x: x**2, you have the lambda function right there. Contrast that with the more conventional:

def square(x):
    return x**2

Perhaps most importantly, you can construct them during runtime.

def make_exp_function(n):
    return lambda x: x**n

square = make_exp_function(2)
cube = make_exp_function(3)
for i in range(100):
    f = make_exp_function(i)
    print f(2)
Edmund
+2  A: 

It's basically syntactic sugaring, what you would write in 10 lines with delegates and what have you, can be done in a one-line lambda expression. The main thing to take into account for me, is when working with multiple developers on the same project, that you have to make sure its readability is still clear.

You could attach an event inline Button1_Click += (sender, eventArgs) => { //myCode };

But you won't be able to reuse the event, and if there's a lot of code in there, it won't help in keeping your code transparant.

You could also create a lambda for retrieving data from a List<>, but that can become quite unclear when there's a lot of parameters, where a nice LINQ Query can be a lot more clear.

It's mostly a personal choice but I must say I have used it quite a few times :)

Hope this helps a little, Sam

Sam
+5  A: 

While PHP supports anonymous functions, they are not actually closures -- so you miss the most interesting part.

In JavaScript (and languages that support "lambdas" The Right Way) you can return a function from a function, and the returned one would be able to access the enclosing context even after the outer function has finished execution. Example:

function counter(start){
    return function() {
        return start++;
    };
};

var f = counter(1);
alert( f() ); // now it's 1
alert( f() ); // now it's 2
alert( f() ); // now it's 3
var g = counter(10);
alert( g() ); // now it's 10
alert( g() ); // now it's 11
alert( f() ); // now it's 4!
mishoo
+1 for closures
Luc
While anonymous functions aren't closures by default, PHP does support explicit closure creation (with the keyword "use"). See more at http://blog.igstan.ro/2009/04/lambdas-and-closures-in-php-53.html
Flavius Stef
Cool, I didn't know that. The syntax is a bit ugly, but it's good to see that PHP catches up.
mishoo
+3  A: 

There are two important things about lambda functions (at least the way the term is commonly used):

  1. They can be passed around. A function can take a lambda function as an argument or return a lambda function.

  2. They have access to the scope where they're defined. So, for example, the lambda function can access the enclosing function's arguments.

For a basic example of how this is useful, I'll write a filter function in Ruby:

def filter(array, &lambda_function)
  new_array = []
  for item in array
    new_array.push(item) if lambda_function[item]
  end
  return new_array
end

$people_array = #imagine I have an array of Person objects here

def find_people_richer_than(threshold)
  return filter($people_array) {|person| person.wealth >= threshold}
end

Our filter doesn't know what criteria we're going to use for filtering. That logic is all contained in the block (Ruby's version of a lambda function) that we pass in. But notice that even though the lambda function is actually called inside filter, it still knows the threshold from the place where it was defined.

Chuck