IT story

모두가 계속 말하는이 '람다'는 무엇입니까?

hot-time 2020. 8. 31. 08:27
반응형

모두가 계속 말하는이 '람다'는 무엇입니까?


모두가 계속 말하는이 '람다'는 무엇입니까? 많은 사람들이 그것을 좋아하는 것 같지만, 내가 모을 수있는 것은 단지 많은 줄의 코드를 하나의 표현식에 넣는 방법뿐입니다.

누군가가 그 진정한 가치에 대해 가르쳐 줄 수 있습니까?


이름없는 기능

간단히 말해 람다는 이름이없는 함수이거나 익명 함수입니다. 변수 인 것처럼 전달할 수있는 작은 실행 코드입니다. JavaScript에서 :

function () {}; // very simple

이제 이러한 람다에 대한 몇 가지 용도를 살펴 보겠습니다.

상용구 코드 추상화

Lambda는 상용구 코드를 추상화하는 데 사용할 수 있습니다. 예를 들어 루프. 우리는 하루 종일 쓰기 forwhile반복에 익숙합니다 . 그러나 이것은 작성되지 않은 코드입니다. 루프의 가장 중요한 부분 인 루프 내부의 코드를 추출하고 나머지는 추상화 할 수 있습니다.

for (var i=0; i<array.length; i++) {
    // do what something useful with array[i]
}

forEach배열 객체 를 사용하면 다음 과 같습니다.

array.forEach(function (element, index) {
   // do something useful with element
   // element is the equivalent of array[i] from above
});

위의 추상화는 그다지 유용하지 않을 수 있지만 forEach훨씬 더 유용한 작업을 수행하는 다른 고차 함수 (예 :)가 있습니다. filter:

var numbers = [1, 2, 3, 4];
var even    = [];

// keep all even numbers from above array
for (var i=0; i<numbers.length; i++) {
    if (numbers[i] % 2 === 0) {
        even.push(numbers[i]);
    }
}

alert(even);

// Using the filter method
even = [1, 2, 3, 4].filter(function (number) {
    return number % 2 === 0;
});

alert(even);

코드 실행 지연

이벤트 개념을 사용할 수있는 일부 환경에서는 람다를 사용하여 특정 시점에 발생할 수있는 이벤트에 응답 할 수 있습니다.

window.onload = function () {
    alert("Loaded");
};

window.setTimeout(function () {
    alert("Code executed after 2 seconds.");
}, 2000);

This could have been done in some other ways, but those are rather verbose. For example, in Java there's the Runnable interface.

Factories of functions

Until this point, we only used lambdas for its syntactic sugar capabilities mostly. But there are situations where lambdas can be much more useful. For example we may have functions that return lambdas. Let's say we have a function that we want its return values to be cached.

var users = [];
var getUser = function (name) {
    if (! users[name]) {
        // expensive operations to get a user. Ajax for example
        users[name] = user_from_ajax;
    }

    return users[name];
};

Later on, we may notice that we have a similar function:

var photos = [];
var getPhoto = function (name) {
    if (! photo[name]) {
        // expensive operations to get a user. Ajax for example
        photos[name] = photo_from_ajax;
    }

    return photos[name];
};

There's clearly a pattern in there, so let's abstract it away. Let's use memoization.

/**
 * @param {Array}     store Data structure in which we cache lambda's return values
 * @param {Function}  lambda
 * @return {Function} A function that caches the result of calling the lambda param
 */
var memoize = function (store, lambda) {
    // return a new lambda
    return function (name) {
        if (! store[name]) {
            // Execute the lambda and cache the result
            store[name] = lambda(name);
        }

        return store[name];
    };
};

var getUsers = memoize([], function (name) {
    // expensive operations to get a user. Ajax for example
});

var getPhotos = memoize([], function (name) {
    // expensive operations to get a photo. Ajax for example
});

As you can see, by using lambdas, we were able to abstract away the caching/memoization logic. If for the other example there were some workarounds, I believe that this particular problem is hardly solved using other techniques. We managed to extract some important boilerplate code into a single place. Not to mention that we got rid of the users and photos global variables.

Looking at your profile I see that you're mostly a Python user. For the above pattern, Python has the concept of decorators. There are lots of example on the net for memoization decorators. The only difference is that in Python you most likely have a named nested function inside that decorator function. The reason being that Python only support single-expression lambdas. But the concept is the same.

As an example of Python lambda use. The above code in which we filtered even numbers can be represented in Python like this:

filter(lambda x: x % 2 == 0, [1, 2, 3, 4])

Anyway, lambdas are not that powerful without closures. Closures is what makes the concept of lambdas so powerful. In my memoization example I have used closures to create a closure around the store param. This way, I have access to that param even after the memoize function has returned its result (a lambda).


The term "lambda" is used to refer to an anonymous function, usually a closure. They're useful because they allow you to write functions that use other functions without bloating your code unnecessarily. For example, in Ruby:

(1..100).select {|num| num % 2 == 0}

This will create an array containing the even numbers between 1 and 100. We don't have to write out an explicit loop — the select method takes a function that it uses to test the values, so all we need is our custom logic. This allows us to greatly customize the method with practically no effort or overhead. Basically, we can compose functions out of smaller functions.

That's just an easy example of what they can do. The ability to pass functions as data is really powerful and functional language programmers routinely do some really amazing things with it.


"Lambda" maybe just too few. Take a look at Lambda calculus. It's useful in functional programming.

And functional programming is yet another programming paradigm (like procedural, or object-oriented).


Lambdas in .NET are quite often referred to as "syntactic sugar". They do not directly affect the functionality however they make the language easier for people to use.

When you have understood the power of using them I am sure you will find that you will be writing less code compared to the old style way using delegates / anonymous methods.


Dr Dobbs Journal has a useful article introducing lambda expressions (within the context of C++ but I think you can apply the principles to any language).

As the article says: "A lambda expression is a highly compact expression that does not require a separate class/function definition."

So using the examples of listings 1 & 2 from DDJ instead of writing:

std::for_each( vec.begin(), vec.end(), print_to_stream<std::string>(std::cout));

Which requires a separate class definition like:

template <typename T, typename Stream> class print_to_stream_t {
  Stream& stream_;
public:
  print_to_stream_t(Stream& s):stream_(s) {}
  void operator()(const T& t) const {
    stream_ << t;
  }
};
template <typename T,typename Stream> 
print_to_stream_t<T,Stream>   print_to_stream(Stream& s) {
  return print_to_stream_t<T,Stream>(s);
}

Using the Boost lambda library this can become:

std::for_each(vec.begin(),vec.end(),std::cout << _1);

Which keeps the definition inline.

The article also explains some more applications of lambda expressions.

I think a key point in the DDJ article is "Typically, lambda expressions are used when small and not overly complex functions are needed at the call site. If the function were nontrivial, you wouldn't want a lambda expression but a normal function or a function object."


If you've ever worked with functions/methods that use function pointers, delegates, strategy or observer pattern/event handling, and thought to yourself "I'm writing this whole function just to use it just once - to pass it to this method; I wish I could just write it in place, rather than clutter my code" - that's where you might use Lambda functions. Languages that support this construct also usually heavily take advantage of the concept of passing functions as parameters, particularly in regards to working with lists (first class functions and higher order functions). This is especially true for functional languages, which rely on function composition rather than memory modification for computations. In some cases (in languages such as Python), the use of lambda functions with list comprehensions is also considered more readable than the equivalent foreach loop.


'lambda' qua word is terminology from the days when computer science types were as likely to be trained in math or logic than have a computer science degree. Some of them cooked up a paradigm called 'functional programming', quite different from imperative and quite powerful too. AFAIK that is the milieu where the term came into use.

Mathematicians and logicians are given to using weird words.

'lambda' sounds really esoteric - as if they are a very strange and special thing. Really, if you write JavaScript for a web browser application and use the "var foo=function() {...}" idiom, you've been using lambda functions all along.


A lambda expression is a simple form of function. The idea is that something of the form on the left (equivalent to parameters) becomes something of the form on the right (equivalent to the body).

for example, in c sharp:

x => x * x

is a lambda to square a value. Something of the form

x

becomes something of the form

x * x

"A lambda expression is an anonymous function that can contain expressions and statements, and can be used to create delegates or expression tree types.

All lambda expressions use the lambda operator =>, which is read as "goes to". The left side of the lambda operator specifies the input parameters (if any) and the right side holds the expression or statement block. The lambda expression x => x * x is read "x goes to x times x."

from MSDN


For a full explanation about Lambda expressions, also check out Wikipedia. (Scroll down to the Lambda calculus and programming languages part.) Lambda expressions aren't that new and they aren't just part of C# but something that has been introduced to computing almost 80 years ago! Lambda expressions are the basis for functional programming.

It's value? Well, considering that it's actually quite old, I would say: very valuable for anyone doing calculations.


If you are into Java, you've heared a lot about lambdas or closures in the last couple of month, because there were different proposals for adding this feature to Java 7. however, I think the comitee dropped it. One of the proposals is from Neal Gafter and explained in great detail here: javac.info. This helped me understanding the use cases and advantages (especially over inner classes)


You'll find all you need to know (about C# Lambdas) for a start here:
Lambda expressions


For java lambdas, this might be a good starting point:

http://rodrigouchoa.wordpress.com/2014/09/10/java-8-lambda-expressions-tutorial/


Yes, it is just a way of cramming lots of lines of code into a single expression. But being such an efficient cramming, it enables some new ways of structuring your program.

Often one would avoid writing delegates or callbacks and revert to procedural style simply because it's too much work to declare new functions or classes for a single expression.

Lambda expressions make it worthwhile to use callbacks even for tiniest tasks, which might make code more clear. Might not.

참고URL : https://stackoverflow.com/questions/1085875/what-is-this-lambda-everyone-keeps-speaking-of

반응형