For a person without a comp-sci background, what is a lambda in the world of Computer Science?


Solution 1:

Lambda comes from the Lambda Calculus and refers to anonymous functions in programming.

Why is this cool? It allows you to write quick throw away functions without naming them. It also provides a nice way to write closures. With that power you can do things like this.

Python

def adder(x):
    return lambda y: x + y
add5 = adder(5)
add5(1)
6

As you can see from the snippet of Python, the function adder takes in an argument x, and returns an anonymous function, or lambda, that takes another argument y. That anonymous function allows you to create functions from functions. This is a simple example, but it should convey the power lambdas and closures have.

Examples in other languages

Perl 5

sub adder {
    my ($x) = @_;
    return sub {
        my ($y) = @_;
        $x + $y
    }
}

my $add5 = adder(5);
print &$add5(1) == 6 ? "ok\n" : "not ok\n";

JavaScript

var adder = function (x) {
    return function (y) {
        return x + y;
    };
};
add5 = adder(5);
add5(1) == 6

JavaScript (ES6)

const adder = x => y => x + y;
add5 = adder(5);
add5(1) == 6

Scheme

(define adder
    (lambda (x)
        (lambda (y)
           (+ x y))))
(define add5
    (adder 5))
(add5 1)
6

C# 3.5 or higher

Func<int, Func<int, int>> adder = 
    (int x) => (int y) => x + y; // `int` declarations optional
Func<int, int> add5 = adder(5);
var add6 = adder(6); // Using implicit typing
Debug.Assert(add5(1) == 6);
Debug.Assert(add6(-1) == 5);

// Closure example
int yEnclosed = 1;
Func<int, int> addWithClosure = 
    (x) => x + yEnclosed;
Debug.Assert(addWithClosure(2) == 3);

Swift

func adder(x: Int) -> (Int) -> Int{
   return { y in x + y }
}
let add5 = adder(5)
add5(1)
6

PHP

$a = 1;
$b = 2;

$lambda = fn () => $a + $b;

echo $lambda();

Haskell

(\x y -> x + y) 

Java see this post

// The following is an example of Predicate : 
// a functional interface that takes an argument 
// and returns a boolean primitive type.

Predicate<Integer> pred = x -> x % 2 == 0; // Tests if the parameter is even.
boolean result = pred.test(4); // true

Lua

adder = function(x)
    return function(y)
        return x + y
    end
end
add5 = adder(5)
add5(1) == 6        -- true

Kotlin

val pred = { x: Int -> x % 2 == 0 }
val result = pred(4) // true

Ruby

Ruby is slightly different in that you cannot call a lambda using the exact same syntax as calling a function, but it still has lambdas.

def adder(x)
  lambda { |y| x + y }
end
add5 = adder(5)
add5[1] == 6

Ruby being Ruby, there is a shorthand for lambdas, so you can define adder this way:

def adder(x)
  -> y { x + y }
end

R

adder <- function(x) {
  function(y) x + y
}
add5 <- adder(5)
add5(1)
#> [1] 6

Solution 2:

A lambda is a type of function, defined inline. Along with a lambda you also usually have some kind of variable type that can hold a reference to a function, lambda or otherwise.

For instance, here's a C# piece of code that doesn't use a lambda:

public Int32 Add(Int32 a, Int32 b)
{
    return a + b;
}

public Int32 Sub(Int32 a, Int32 b)
{
    return a - b;
}

public delegate Int32 Op(Int32 a, Int32 b);

public void Calculator(Int32 a, Int32 b, Op op)
{
    Console.WriteLine("Calculator: op(" + a + ", " + b + ") = " + op(a, b));
}

public void Test()
{
    Calculator(10, 23, Add);
    Calculator(10, 23, Sub);
}

This calls Calculator, passing along not just two numbers, but which method to call inside Calculator to obtain the results of the calculation.

In C# 2.0 we got anonymous methods, which shortens the above code to:

public delegate Int32 Op(Int32 a, Int32 b);

public void Calculator(Int32 a, Int32 b, Op op)
{
    Console.WriteLine("Calculator: op(" + a + ", " + b + ") = " + op(a, b));
}

public void Test()
{
    Calculator(10, 23, delegate(Int32 a, Int32 b)
    {
        return a + b;
    });
    Calculator(10, 23, delegate(Int32 a, Int32 b)
    {
        return a - b;
    });
}

And then in C# 3.0 we got lambdas which makes the code even shorter:

public delegate Int32 Op(Int32 a, Int32 b);

public void Calculator(Int32 a, Int32 b, Op op)
{
    Console.WriteLine("Calculator: op(" + a + ", " + b + ") = " + op(a, b));
}

public void Test()
{
    Calculator(10, 23, (a, b) => a + b);
    Calculator(10, 23, (a, b) => a - b);
}

Solution 3:

The name "lambda" is just a historical artifact. All we're talking about is an expression whose value is a function.

A simple example (using Scala for the next line) is:

args.foreach(arg => println(arg))

where the argument to the foreach method is an expression for an anonymous function. The above line is more or less the same as writing something like this (not quite real code, but you'll get the idea):

void printThat(Object that) {
  println(that)
}
...
args.foreach(printThat)

except that you don't need to bother with:

  1. Declaring the function somewhere else (and having to look for it when you revisit the code later).
  2. Naming something that you're only using once.

Once you're used to function values, having to do without them seems as silly as being required to name every expression, such as:

int tempVar = 2 * a + b
...
println(tempVar)

instead of just writing the expression where you need it:

println(2 * a + b)

The exact notation varies from language to language; Greek isn't always required! ;-)