How Are Lambdas Useful

How are lambdas useful?

Are you talking about lambda expressions? Like

lambda x: x**2 + 2*x - 5

Those things are actually quite useful. Python supports a style of programming called functional programming where you can pass functions to other functions to do stuff. Example:

mult3 = filter(lambda x: x % 3 == 0, [1, 2, 3, 4, 5, 6, 7, 8, 9])

sets mult3 to [3, 6, 9], those elements of the original list that are multiples of 3. This is shorter (and, one could argue, clearer) than

def filterfunc(x):
return x % 3 == 0
mult3 = filter(filterfunc, [1, 2, 3, 4, 5, 6, 7, 8, 9])

Of course, in this particular case, you could do the same thing as a list comprehension:

mult3 = [x for x in [1, 2, 3, 4, 5, 6, 7, 8, 9] if x % 3 == 0]

(or even as range(3,10,3)), but there are many other, more sophisticated use cases where you can't use a list comprehension and a lambda function may be the shortest way to write something out.

  • Returning a function from another function

      >>> def transform(n):
    ... return lambda x: x + n
    ...
    >>> f = transform(3)
    >>> f(4)
    7

    This is often used to create function wrappers, such as Python's decorators.

  • Combining elements of an iterable sequence with reduce()

      >>> reduce(lambda a, b: '{}, {}'.format(a, b), [1, 2, 3, 4, 5, 6, 7, 8, 9])
    '1, 2, 3, 4, 5, 6, 7, 8, 9'
  • Sorting by an alternate key

      >>> sorted([1, 2, 3, 4, 5, 6, 7, 8, 9], key=lambda x: abs(5-x))
    [5, 4, 6, 3, 7, 2, 8, 1, 9]

I use lambda functions on a regular basis. It took me a while to get used to them, but eventually I came to understand that they're a very valuable part of the language.

Do lambda expressions have any use other than saving lines of code?

Lambda expressions do not change the set of problems you can solve with Java in general, but definitely make solving certain problems easier, just for the same reason we’re not programming in assembly language anymore. Removing redundant tasks from the programmer’s work makes life easier and allows to do things you wouldn’t even touch otherwise, just for the amount of code you would have to produce (manually).

But lambda expressions are not just saving lines of code. Lambda expressions allow you to define functions, something for which you could use anonymous inner classes as a workaround before, that’s why you can replace anonymous inner classes in these cases, but not in general.

Most notably, lambda expressions are defined independently to the functional interface they will be converted to, so there are no inherited members they could access, further, they can not access the instance of the type implementing the functional interface. Within a lambda expression, this and super have the same meaning as in the surrounding context, see also this answer. Also, you can not create new local variables shadowing local variables of the surrounding context. For the intended task of defining a function, this removes a lot of error sources, but it also implies that for other use cases, there might be anonymous inner classes which can not be converted to a lambda expression, even if implementing a functional interface.

Further, the construct new Type() { … } guarantees to produce a new distinct instance (as new always does). Anonymous inner class instances always keep a reference to their outer instance if created in a non-static context¹. In contrast, lambda expressions only capture a reference to this when needed, i.e. if they access this or a non-static member. And they produce instances of an intentionally unspecified identity, which allows the implementation to decide at runtime whether to reuse existing instances (see also “Does a lambda expression create an object on the heap every time it's executed?”).

These differences apply to your example. Your anonymous inner class construct will always produce a new instance, also it may capture a reference to the outer instance, whereas your (Developer o1, Developer o2) -> o1.getName().compareTo(o2.getName()) is a non-capturing lambda expression that will evaluate to a singleton in typical implementations. Further, it doesn’t produce a .class file on your hard drive.

Given the differences regarding both, semantic and performance, lambda expressions may change the way programmers will solve certain problems in the future, of course, also due to the new APIs embracing ideas of functional programming utilizing the new language features. See also Java 8 lambda expression and first-class values.


¹ From JDK 1.1 to JDK 17. Starting with JDK 18, inner classes may not retain a reference to the outer instance if it is not used. For compatibility reasons, this requires the inner class not be serializable. This only applies if you (re)compile the inner class under JDK 18 or newer with target JDK 18 or newer. See also JDK-8271717

What exactly is lambda in Python?

Lambda is more of a concept or programming technique then anything else.

Basically it's the idea that you get a function (a first-class object in python) returned as a result of another function instead of an object or primitive type. I know, it's confusing.

See this example from the python documentation:

def make_incrementor(n):
return lambda x: x + n
f = make_incrementor(42)
f(0)
>>> 42
f(1)
>>> 43

So make_incrementor creates a function that uses n in it's results. You could have a function that would increment a parameter by 2 like so:

f2 = make_incrementor(2)
f2(3)
>>> 5

This is a very powerful idea in functional programming and functional programming languages like lisp & scheme.

Hope this helps.

What is a lambda (function)?

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

What exactly DOES a Lambda do?

In your example lambda x: x+1 will take an argument x and return x+1, equivalent to def foo(x): return x+1, these are also called anonymous functions.

Lambdas are extremely useful while passing a function as an argument. Let's give you an example. Suppose you have a 2D list of tuples:

l = [('a',2),('b',3),('c',1)]

And you want to sort the list using the second item in each tuple. Manually it will take a lot of code to do this manually, but with lambdas you can pass a lambda function as a key to sort method or sorted() like this:

l.sort(key=lambda x: x[1])

And there are more examples!!!



Related Topics



Leave a reply



Submit