Accéder au contenu principal

Javascript Jems - Lambda expressions

Javascript Jems - Lambda expressions
Written by Ian Elliot   
Tuesday, 14 January 2014
Article Index
Javascript Jems - Lambda expressions
Using anonymous functions and invocation
JavaScript has lambda expressions in all but name. Find out how they work and how to use them.

Lambda expressions sound advanced and impressive and just about every language has them or is adding them. Put simply lambda expressions are something of a buzz word, so much that it's difficult to know what they really are all about. 
One place you wont hear much about lambda expressions is in JavaScript. You will hear it said that JavaScript doesn't do lambda expressions but this isn't the whole truth. 
First what is a Lambda expression?
Lambda expressions were invented by Church and Kleene, two great computer scientists, back in the 1930s. In practice this is fairly irrelevant in the sense that when most programmers use the term Lambda expression they mean a function of a number of parameters that returns a single result and can be passed to other functions.
The parameters and single result clearly aren’t a problem but what about passing a function to other functions?
This sounds more complicated but it's no problem in Javascript.
Javascript is an interpreted language and this means that it treats code and data much the same.
jemsicon

Functions As Objects

What this means in practice is that a variable can store data or code with the only real difference being that code can be executed using, for example the invocation operator ().
The usual way to define a Javascript function covers up this unity.
For example, the definition:
function test(a){
 alert(a);
}
looks like a standard function as you might find in any language but in JavaScript it is quite a lot more. 
In JavaScript a function is an object just like any other object and you can use a function anywhere you can use an object. 
This is often summarised by saying that functions in JavaScript are "first class" objects.
Contrast this to what happens in many other languages where functions are something completely different from an object and are usually thought of as being constituent parts of an object aka methods. This approach is what makes it necessary to introduce lambda expressions or something similar in these other languages. Put simply we need lambda expressions to provide us with functions that have a life for their own outside of objects and so that they can be passed around like objects.
Notice that it is possible to program in JavaScript and still come to the conclusion that functions are something special and different from objects. The reason for this is that JavaScript provides the standard syntax for a function declaration which allows you to ignore the fact that a function is an object.  
The alternative way of defining a function as a function expression makes it much clearer that it is more like an object:
var test=function(a){alert(a);};
You really can think of test as being a variable that just happens to hold a reference to a function object. 
It is important to know that JavaScript treats functions defined using the standard function definition somewhat differently to those defined in function expressions. In particular functions are subject to hoisting where function expressions are not. See JavaScript Hoisting Explained       
Of course a function object is special among objects in that it has a chunk of code, a method if you like, that you can invoke using the invocation operator on the object. 
That is test is a reference to an object and 
test("Hello") 
calls the function you defined. It really can help to think of this as the object's default method.  If you don't see what this idea is about consider adding a method to the function object:
test.myMethod=function(a){alert(a);};
You can now call myMethod using the usual:
test.myMethod("Hello");
and this makes
test("Hello");
look even more like a call to a default method. 
Finally also notice that in JavaScript object methods are just properties that happen to be function objects - nothing special here so move on...

Assigning Functions

As a function is just an object you can do anything you can do to an object to a function. 
For example you can assign one function to another using standard syntax:
var test2=test;
test2("hello2");
and this works perfectly.
Notice that while test and test2 are both references to the same function object and hence the same code, 
In short variables that happen to reference a function object behave like perfectly standard reference variables. 
In particular if you redefine test a new function object and block of code is created on the heap and test is set to point to it. The second variable, test2 still points to the original block of code and hence the old version of the function.
For example following:
test=function(){alert("Hello1");};
test2=test;
test=function(){alert("Hello2");};
test is a function that prints Hello2 but test2 is still the original function that prints Hello1, as you can confirm by using:
test();
test2();
In this sense JavaScript functions are immutable – you can’t modify them only create completely new functions. 
You can use this function reference mechanism to create something that looks like C#’s multi-target delegate function.
To call multiple functions with a single call you could use something like:
func1=function(){list of instructions 1};
func2=function(){list of instructions 2};
func3=function(){list of instructions 3};
func={func1();func2();func3()};
and to call all three functions one after another you would use:
func();
This looks like just calling the three functions one after another but of course func1, func2 and func3 are variables and hence you can dynamically change what functions are called.
You can pass parameters if you want to and pass them on to the sequence of called functions. This is all particularly useful if you want to implement a “callback” that invokes multiple functions.  If you want to allow users to add callback functions all you need to do is setup a stack or an array to store them as they are added.

Passing functions

Given you can pass an object, i.e. as a parameter, into a function it now seems entirely reasonable that  you can pass a variable that just happens to reference a function object into another function.
Recall that all parameters in JavaScript are passed by reference so just a pointer to the function is passed and this is efficient.
For example, the Array object has a method that will sort the array into order:
var list=new Array("A","AB","ABC","ABCD");
list.sort();
for(var i=0;i<list.length  ;i++){
 alert(list[i]);
}
What is perhaps slightly less well known is that the sort method can also take an optional function which it will use to compare the values of the array. This function is defined as:
function(a,b)
and it has to return a negative value if a<b, 0 if a==b and a positive value if a>b.
For example:
compare=function(a,b){
 return a.length-b.length;
}
used in
list.sort(compare);
sorts the list of strings into order based on their length alone.
Other languages that don't have first class functions have to resort to delegate types - object wrappers for functions - or lambda expressions.
----------------------------------------------------------------------------------

A more familiar alternative

Things are even simpler because you don't have to store a reference to a function to pass it to another function or to make use of it. 
In other languages this facility is often called an anonymous function. In JavaScript is is just a use of the idea of an object literal i.e an object crated on the fly as in {myProperty:"value"}.
Anywhere you can use an object reference you can use an object literal. 
JavaScript also supports anonymous functions as object litterals and you can write this sort example as:
list.sort(function(a,b){
             return a.length-b.length;});
This last example looks a lot more like the sort of typical use that lambda expression are put to in other languages.
In say C# you could write the same thing using
list.sort((a,b) => a.length-b.length)
and the expression (a,b) => a.length-b.length is a lambda expression. Notice that apart from being a little more compact - no need for the keywords function and return - it is more or less the same. 
Thus JavaScript with its first class functions or functions as objects doesn't really need lambda expressions or it already has them depending on your point of view.

jemsicon

Of course there is nothing stopping you from creating your own functions that accept other functions. As long as you have fully accepted the "functions are just objects" idea you probably don't need to see an example of how to do this but for completeness:
Say=function(t){
 t();
}
This will simply call any function that you pass to it. If you define:
Hello=function(){
 alert("Hello");
}
Then
Say(Hello);
will call the Hello function and display an alert.
Notice that you have to pass the variable that references the function without accidentally invoking the function.
That is  don’t write:
Say(Hello());
by mistake as this would call the Hello function and then pass its result to the Say function which as a string couldn't be called as a function.
You need to distinguish very clearly between passing a function and passing the result of a function to another function.

Function Invocation ()

You also need to get into the habit of thinking of the () brackets as being the function invocation operator. When ever you use () following an expression it calls the function that is the result of the expression.
For example you can write:
(Say)(Hello);
or even:
Say=function(t){
 t();
}(Hello);
The round brackets at the end of the function definition call the function as soon as it has been defined. 
This is usually called an "Immediately Invoked Function Expression" or IIFE and it is very useful and used a lot in idiomatic JavaScript.
This instant function evaluation can be useful when you want to pass the result of a "lambda expression".
For example:
alert(function sum(a,b){return a+b;}(1,2));
Here we have a lambda expression, the sum function being defined and evaluated in a single step.
The result, 3 in this case is passed to the alert function.
Although this example isn’t particularly useful it does become useful when combined with other Javascript features such as closure – more of which another time.

Summary

So what to take away -
In JavaScript functions are function objects and they can be created and used in the same way.
The only difference between an object and a function object is that a function object has a default method i.e. the code that is usually considered to be the function. 
Once you understand JavaScript's first class functions you realize that you don't need to introduce anything extra to the language such as lambda expressions, delegates or anonymous functions to do the same tasks. 
Superficially a function object literal looks a lot like a lambda expression and it can mostly be used in exactly the same way.
This means you can pass functions to other functions store them in arrays and generally make use of them as standard objects.

Related Articles


To be informed about new articles on I Programmer, install the I Programmer Toolbar, subscribe to the RSS feed, follow us on, Twitter, FacebookGoogle+ or Linkedin,  or sign up for our weekly newsletter.

Commentaires

Posts les plus consultés de ce blog

easy drag-and-drop website builder

WINDOWS MAC LINUX WEB IPHONE ANDROID PRODUCTIVITY DEVELOPMENT GAMES SOCIAL BUSINESS Lists Sign up Login Crowdsourced software recommendations Which app do you want to replace? Find apps 32 Like Mobirise Create cutting-edge, beautiful websites that look amazing on any devices and browsers.  Created by Mobirise Website Builder Free   Open Source   Mac OS X   Windows   Android     Mobirise - is a super easy drag-and-drop website builder. Drop the blocks you like into your page, edit content inline and publish - no technical skills required. Develop bootstrap-based, fully responsive sites that look amazing on any devices and browsers. Preview how your website will appear on smartphones, tablets and desktops directly in the visual editor. Free for commercial and personal use. Download for Windows, Mac, Android. Boost your ranking - Sites made with Mobirise ar...

L’ARCHITECTURE REST EXPLIQUÉE EN 5 RÈGLES

L’ARCHITECTURE REST EXPLIQUÉE EN 5 RÈGLES par Nicolas Hachet     17 commentaires   Confirmé ,  PHP     architecture ,  REST     Permalink REST (Representational State Transfer) ou RESTful  est un style d’architecture permettant de construire des applications (Web, Intranet, Web Service). Il s’agit d’un ensemble de conventions et de bonnes pratiques à respecter et non d’une technologie à part entière. L’architecture REST utilise les spécifications originelles du protocole HTTP , plutôt que de réinventer une surcouche (comme le font SOAP ou XML-RPC par exemple). Règle n°1 : l’URI comme identifiant des ressources Règle n°2 : les verbes HTTP comme identifiant des opérations Règle n°3 : les réponses HTTP comme représentation des ressources Règle n°4 : les liens comme relation entre ressources Règle n°5 : un paramètre comme jeton d’authentification Les 5 règles à suivre pour implémenter REST Règle n°1 : l’URI comme iden...

Dîner des philosophes

Dîner des philosophes Le problème du «  dîner des philosophes  » est un cas d'école classique sur le partage de ressources en  informatique système . Il concerne l' ordonnancement  des  processus et l'allocation des ressources à ces derniers. Ce problème a été énoncé par  Edsger Dijkstra 1 . Sommaire    [ masquer ]  1 Le problème 2 Remarques 3 Solutions 3.1 La solution de Chandy/Misra 3.2 Solution dans le cas pair 3.2.1 Preuve de l'exactitude de cette solution 4 Notes et références 5 Voir aussi 5.1 Articles connexes 5.2 Lien externe Le problème [ modifier  |  modifier le code ] Illustration du problème La situation est la suivante : cinq philosophes (initialement mais il peut y en avoir beaucoup plus) se trouvent autour d'une table ; chacun des philosophes a devant lui un plat de spaghetti ; à gauche de chaque plat de spaghetti se trouve une fourchette. Un phi...