Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <h2>Functions without a name</h2> <p>Simply put, a lambda is a function without a name, or an anonymous function. A small piece of executable code, that can be passed around as if it were a variable. In JavaScript: </p> <pre class="lang-js prettyprint-override"><code>function () {}; // very simple </code></pre> <p>Let's see now some uses for these lambdas.</p> <h2>Abstracting boilerplate code</h2> <p>Lambdas may be used to abstract away boilerplate code. For example loops. We're used to write <code>for</code> and <code>while</code> loops all day long. But this is code that does not be written. We could extract the code inside the loop, the most important part of the loop, and abstract away the rest:</p> <pre class="lang-js prettyprint-override"><code>for (var i=0; i&lt;array.length; i++) { // do what something useful with array[i] } </code></pre> <p>by using the <a href="https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Array/forEach" rel="noreferrer"><code>forEach</code></a> of array objects, becomes:</p> <pre class="lang-js prettyprint-override"><code>array.forEach(function (element, index) { // do something useful with element // element is the equivalent of array[i] from above }); </code></pre> <p>The above abstraction may not be that useful, but there are other higher order functions, like <code>forEach</code>, that perform much more useful tasks. For example <a href="https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Array/filter" rel="noreferrer"><code>filter</code></a>:</p> <pre class="lang-js prettyprint-override"><code>var numbers = [1, 2, 3, 4]; var even = []; // keep all even numbers from above array for (var i=0; i&lt;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); </code></pre> <h2>Code execution delay</h2> <p>In some environments, in which the concept of event is available, we could use lambdas to respond to events that may happen at some point in time.</p> <pre class="lang-js prettyprint-override"><code>window.onload = function () { alert("Loaded"); }; window.setTimeout(function () { alert("Code executed after 2 seconds."); }, 2000); </code></pre> <p>This could have been done in some other ways, but those are rather verbose. For example, in Java there's the <code>Runnable</code> interface.</p> <h2>Factories of functions</h2> <p>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.</p> <pre class="lang-js prettyprint-override"><code>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]; }; </code></pre> <p>Later on, we may notice that we have a similar function:</p> <pre class="lang-js prettyprint-override"><code>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]; }; </code></pre> <p>There's clearly a pattern in there, so let's abstract it away. Let's use <a href="http://en.wikipedia.org/wiki/Memoization" rel="noreferrer">memoization</a>.</p> <pre class="lang-js prettyprint-override"><code>/** * @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 }); </code></pre> <p>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 <code>users</code> and <code>photos</code> global variables.</p> <p>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 <a href="http://code.activestate.com/recipes/496879/" rel="noreferrer">example on the net for memoization</a> decorators. The only difference is that in Python you most likely have a <strong>named</strong> nested function inside that decorator function. The reason being that Python only support single-expression lambdas. But the concept is the same.</p> <p>As an example of Python lambda use. The above code in which we filtered even numbers can be represented in Python like this:</p> <pre class="lang-js prettyprint-override"><code>filter(lambda x: x % 2 == 0, [1, 2, 3, 4]) </code></pre> <p>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 <code>store</code> param. This way, I have access to that param even after the <code>memoize</code> function has returned its result (a lambda).</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload