SlideShare une entreprise Scribd logo
1  sur  36
Télécharger pour lire hors ligne
Programare funcţională în Javascript
            Alexandru Badiu
Conţinut

                      Ce este programarea funcţională?
                      Funcţii de ordin înalt
                      Funcţii anonime
                      Funcţii imbricate
                      Închideri
                      Currying


Programare funcțională în Javascript - Alexandru Badiu
Funcţională?                                Ce este programarea funcţională?



                      Programarea funcţională este o paradigmă de
                      programare
                      Se pune accent pe evaluarea expresiilor şi nu pe
                      execuţia comenzilor
                      Expresiile sunt funcţii
                      Constante vs variabile
                      Lisp, Erlang, Haskell, OCaml
                      Dacă ai scris cod Javascript sau Ruby atunci
                      probabil ai folosit concepte din programarea
                      funcţională fără să ştii

Programare funcțională în Javascript - Alexandru Badiu
Paradigme?                                  Ce este programarea funcţională?



                      O paradigmă de programare e un stil de a programa
                      Concepte pentru elementele unui program (funcţii,
                      variabile, obiecte etc)
                      Concepte pentru paşii unui calcul (evaluare,
                      atribuire etc)
                      Un limbaj de programare poate oferi suport pentru
                      mai multe paradigme




Programare funcțională în Javascript - Alexandru Badiu
Procedurală                                         Ce este programarea funcţională?




                                                 #include <stdio.h>
                                                 #include <stdlib.h>

                                                 int main(void)
                                                 {
                                                   puts(quot;Hello World!quot;);
                                                   return EXIT_SUCCESS;
                                                 }


Programare funcțională în Javascript - Alexandru Badiu
OO                                            Ce este programarea funcţională?




                                class HelloWorld {
                                  static public void main( String args[] ) {
                                    System.out.println( quot;Hello World!quot; );
                                  }
                                }




Programare funcțională în Javascript - Alexandru Badiu
Logică                                             Ce este programarea funcţională?




                                             ?- write(”Hello World!”), nl.




Programare funcțională în Javascript - Alexandru Badiu
Funcţională                                          Ce este programarea funcţională?




                                                  (alert “Hello World!”)




Programare funcțională în Javascript - Alexandru Badiu
Limbaje ezoterice                                     Ce este programarea funcţională?




                                                    HAI
                                                    CAN HAS STDIO?
                                                    VISIBLE quot;HAI WORLD!quot;
                                                    KTHXBYE




Programare funcțională în Javascript - Alexandru Badiu
HTML                                          Ce este programarea funcţională?




                                <p>HTML nu este un limbaj de programare.</p>




Programare funcțională în Javascript - Alexandru Badiu
Javascript                                  Ce este programarea funcţională?




Programare funcțională în Javascript - Alexandru Badiu
Definiţie                                   Funcţii de ordin înalt



                      Funcţiile sunt de ordin înalt
                      Sunt obiecte
                      Au proprietăţi
                      Pot fi transmise altor funcţii
                      Pot fi întoarse ca rezultat
                      Pot fi create dinamic




Programare funcțională în Javascript - Alexandru Badiu
Exemple                                      Funcţii de ordin înalt


                            function say(what) {
                              console.log(what);
                            }

                            var say = function (what) {
                              console.log(what);
                            }

                            say('hello');
                            // hello
                            var spune = say;
                            spune('salut');
                            // salut

                            say = function (what) {
                              console.log('nu vreau');
                            }

                            spune('ceva');
                            // ceva



Programare funcțională în Javascript - Alexandru Badiu
Exemple                                                                Funcţii de ordin înalt


       var gen_func = function (op) {
         switch (op) {
           case '+':
             return function () { var        r = arguments[0]; for (var i=1; i<arguments.length; i++ ) r +=
       arguments[i]; return r; }
           case '-':
             return function () { var        r = arguments[0]; for (var i=1; i<arguments.length; i++ ) r -=
       arguments[i]; return r; }
           case '*':
             return function () { var        r = arguments[0]; for (var i=1; i<arguments.length; i++ ) r *=
       arguments[i]; return r; }
           case '/':
             return function () { var        r = arguments[0]; for (var i=1; i<arguments.length; i++ ) r /=
       arguments[i]; return r; }
         }
       }

       var add = gen_func('+');
       add;
       // function () { var r = arguments[0]; for (var i = 1; i < arguments.length; i++) { r +=
       arguments[i]; } return r; }
       add(1,2,3);
       // 6
       var mul = gen_func('*');
       mul(4,5,6);
       // 120




Programare funcțională în Javascript - Alexandru Badiu
Exemple                                                    Funcţii de ordin înalt



                                   var compune = function (f, g) {
                                      return function (x) { return f(g(x)); }
                                   };

                                   var a = function (x) {
                                      return x*x;
                                   };

                                   var b = function (x) {
                                      return x/2;
                                   };

                                   var c = compune(a, b);
                                   var d = compune(b, a);

                                   c(6);
                                   // 9
                                   d(6);
                                   // 18



Programare funcțională în Javascript - Alexandru Badiu
Definiţie                                        Funcţii anonime



                      Funcţii fără nume
                      Folosite atunci când codul trebuie rulat o singură
                      dată
                      Folosite la sortări, căutari
                      Folosite la evenimente




Programare funcțională în Javascript - Alexandru Badiu
Exemple                                                Funcţii anonime




                   (function (what) { console.log(what)}) ('functie anonima');

                   // functie anonima

                   ( function (x) {
                       if (x<2) return x;
                       return x * arguments.callee(x - 1);
                   }) (3);

                   // 6




Programare funcțională în Javascript - Alexandru Badiu
Exemple                                                   Funcţii anonime




                           jQuery(quot;div.autoo-more aquot;).click(function(event) {
                             mf = jQuery(this).parent().prev();
                             mf.toggle();
                             if (mf.css('display') == 'none') {
                               jQuery(this).html('Mai multe &raquo;');
                             }
                             else {
                               jQuery(this).html('&laquo; Mai putine');
                             }
                             return false;
                           });




Programare funcțională în Javascript - Alexandru Badiu
Exemple                                                      Funcţii anonime


                                 var v = [ 6, 12, 19, 8, 40 ];
                                 v.sort();
                                 // 12,19,40,6,8

                                 v.sort(function (x, y) { return x - y; });
                                 // 6,8,12,19,40

                                 v.sort(function (x, y) { return y - x; });
                                 // 40,19,12,8,6

                                 function Cauta(v, f)
                                 {
                                   for (var i = 0; i < v.length; i++)
                                     if (f(v[i])) { return i; }
                                   return -1;
                                 }

                                 Cauta(v, function (x) { return x > 10; });
                                 // 0

                                 Cauta(v, function (x) { return x < 10; });
                                 // 3

Programare funcțională în Javascript - Alexandru Badiu
Definiţie                                           Funcţii imbricate



                      Funcţii definite în interiorul altor funcţii
                      Funcţii anonime
                      Funcţii non-anonime




Programare funcțională în Javascript - Alexandru Badiu
Exemple                                                    Funcţii imbricate




                           function imbri(){
                             var mesaj = quot;salutquot;;

                               function imbri2() {
                                  console.log(mesaj);
                               };

                               imbri2();
                           };

                           imbri();
                           // salut

                           function imbri(mesaj){
                              ( function () { console.log(mesaj); } ) (mesaj);
                           };

                           imbri(quot;testquot;);
                           // test



Programare funcțională în Javascript - Alexandru Badiu
Definiţie                                                  Închideri



                      În engleză: closures
                      Funcţiile imbricate au acces la variabilele din
                      funcţia părinte
                      Chiar şi după ce execuţia funcţiei părinte s-a
                      terminat
                      Funcţia = (Funcţia imbricată, Variabile locale)
                      Variabilele nu sunt copiate ci este păstrată o
                      referinţă




Programare funcțională în Javascript - Alexandru Badiu
Exemple                                                            Închideri



                   Funcţia întoarsă are acces la variabila msg

                               function say(what) {
                                 var msg = quot;Mesaj: quot; + what;
                                 return function () { console.log(msg); };
                               }

                               say('unu')();
                               // Mesaj: unu
                               say('doi')();
                               // Mesaj: doi

                               function say(what) {
                                 var ret = function () { console.log(msg); };
                                 var msg = quot;Mesaj: quot; + what;
                                 return ret;
                               }

                               say('unu')();
                               // Mesaj: unu
                               say('doi')();
                               // Mesaj: doi




Programare funcțională în Javascript - Alexandru Badiu
Exemple                                                                           Închideri



                     Acelaşi lucru este valabil şi pentru funcţii declanşate
                     de evenimente
                 function sendRequest(url,callback,postData) {
                   var req = createXMLHTTPObject();
                   if (!req) { return; }
                   var method = (postData) ? quot;POSTquot; : quot;GETquot;;
                   req.open(method,url,true);
                   req.setRequestHeader('User-Agent','XMLHTTP/1.0');

                     if (postData) {
                       req.setRequestHeader('Content-type','application/x-www-form-urlencoded');
                     }
                     req.onreadystatechange = function () {
                       if (req.readyState != 4) return;
                       if (req.status != 200 && req.status != 304) {
                         alert('HTTP error ' + req.status);
                         return;
                       }
                       callback(req);
                     }
                     if (req.readyState == 4) return;
                     req.send(postData);
                 }


Programare funcțională în Javascript - Alexandru Badiu
Exemple                                                      Închideri



                   Mai multe funcţii imbricate au acces la aceeaşi
                   închidere

                                        function setup() {
                                          var num = 21;
                                          afiseaza = function () {
                                            console.log(num);
                                          }
                                          incrementeaza = function () {
                                            num++;
                                          }
                                        }

                                        setup();
                                        afiseaza();
                                        // 21
                                        incrementeaza();
                                        afiseaza();
                                        // 22

                                        setup();
                                        afiseaza();
                                        // 21



Programare funcțională în Javascript - Alexandru Badiu
Gotchas                                                            Închideri



                   Ce este afisat?


                               function pregateste_functii(num) {
                                 var res = [];
                                 for (var i=0; i<num; i++) {
                                   res.push(function () { console.log(i); });
                                 }
                                 return res;
                               }

                               var funcs = pregateste_functii(4);
                               for (var i=0; i<funcs.length; i++) {
                                 funcs[i]();
                               }




Programare funcțională în Javascript - Alexandru Badiu
Gotchas                                                            Închideri



                   Ce este afisat?

                               function pregateste_functii(num) {
                                 var res = [];
                                 for (var i=0; i<num; i++) {
                                   res.push(function () { console.log(i); });
                                 }
                                 return res;
                               }

                               var funcs = pregateste_functii(4);
                               for (var i=0; i<funcs.length; i++) {
                                 funcs[i]();
                               }

                               //   4
                               //   4
                               //   4
                               //   4


Programare funcțională în Javascript - Alexandru Badiu
Gotchas                                                            Închideri



                   this nu se comporta ca în alte limbaje
                   În acest caz this.loaded se referă la ajax_ob.loaded
                         AclinkESM.prototype.loadTemplates = function () {
                           if (this.individual_templates) {
                             this.templates = [];

                                jQuery.ajax({
                                  url: this.config.t_dir + 'anunt-container.ejs',
                                  processData: true,
                                  dataType: quot;textquot;,
                                  success: function(data, status){
                                    this.templates['anunt-container.ejs'] = data;
                                    this.loaded++;
                                  }
                                });
                                this.toload++;
                                ...



Programare funcțională în Javascript - Alexandru Badiu
Gotchas                                                            Închideri



                   Soluţia: copierea lui this în altă variabilă, tipic that
                   sau self

                         AclinkESM.prototype.loadTemplates = function () {
                           var that = this;
                           if (this.individual_templates) {
                             this.templates = [];

                                jQuery.ajax({
                                  url: this.config.t_dir + 'anunt-container.ejs',
                                  processData: true,
                                  dataType: quot;textquot;,
                                  success: function(data, status){
                                    that.templates['anunt-container.ejs'] = data;
                                    that.loaded++;
                                  }
                                });
                                this.toload++;
                                ...


Programare funcțională în Javascript - Alexandru Badiu
Definiţie                                             Currying


                      Numit după Haskell Curry
                      Evaluarea parţială a funcţiilor
                      Modifică scope-ul la rulare
                      Matematic:
                           f (X x Y) -> Z
                           curry(f):X -> (Y -> Z)
                      Non matematic:
                                       console.log(aduna(2, 3));
                                       // 5
                                       var aduna4 = aduna(4);
                                       console.log(aduna4(10));
                                       // 14

Programare funcțională în Javascript - Alexandru Badiu
Implementare                                                      Currying


                   Varianta simplă
                                    function aduna(a) {
                                      return function (b) { return a + b; };
                                    }

                                    var aduna4 = aduna(4);
                                    var aduna10 = aduna(10);

                                    aduna4(5);
                                    // 9
                                    aduna10(5);
                                    // 15


                   Ideal ar fi să putem aplica procedeul la orice funcţie,
                   fără să o modificăm
                                     function aduna(a, b) {
                                       return a + b;
                                     }
                                     var aduna4 = aduna.curry(4);
Programare funcțională în Javascript - Alexandru Badiu
Implementare                                                        Currying


                              Function.prototype.curry = function() {
                                var fn = this, args = [];

                                 for (var i = 0; i < arguments.length; i++)
                                   args.push(arguments[i]);

                                 return function() {
                                    for (var i = 0; i < arguments.length; i++)
                                      args.push(arguments[i]);
                                    return fn.apply(window, args);
                                 };
                              };

                              function aduna(a, b) {
                                return a + b;
                              }

                              a = aduna.curry(5);
                              b = aduna.curry(10);
                              a(10); // 15
                              b(10); // 20


Programare funcțională în Javascript - Alexandru Badiu
Implementare                                                        Currying


                   Uneori este utilă schimbarea scope-ului
                   bind din Prototype, dojo.lang.curry
                              Function.prototype.curry = function(scope) {
                                var fn = this, args = [];
                                var scope = scope || window;

                                 for (var i = 1; i < arguments.length; i++)
                                   args.push(arguments[i]);

                                 return function() {
                                    for (var i = 0; i < arguments.length; i++)
                                      args.push(arguments[i]);
                                    return fn.apply(scope, args);
                                 };
                              };




Programare funcțională în Javascript - Alexandru Badiu
Exemple                                                                     Currying



                   function sayHello(msg) {
                     console.log(msg + 'n You clicked on ' + this.id);
                   }

                   var el1 = document.getElementById('element1');
                   var el2 = document.getElementById('element2');

                   el1.addEventListener('click', sayHello.curry(el1, 'Hello'), false);
                   el2.addEventListener('click', sayHello.curry(el2, 'Salut'), false);

                   function update(elem, data) {
                     $(elem).html(data);
                   }

                   $.get(quot;foo.phpquot;, update.curry(window, 'elem1'));
                   $.get(quot;bar.phpquot;, update.curry(window, 'elem2'));

                   function update(data) {
                     $(this).html(data);
                   }

                   $.get(quot;foo.phpquot;, update.curry($('elem1')));
                   $.get(quot;bar.phpquot;, update.curry($('elem2')));




Programare funcțională în Javascript - Alexandru Badiu
Resurse
                   http://www.joelonsoftware.com/items/2006/08/01.html
                   http://osteele.com/archives/2007/07/functional-javascript
                   http://invisibleblocks.wordpress.com/2007/02/23/functional-
                   programming-in-javascript-and-ruby/




Programare funcțională în Javascript - Alexandru Badiu
?
 Alexandru Badiu
 i@voidberg.org
http://voidberg.org

Contenu connexe

Plus de Alexandru Badiu

Plus de Alexandru Badiu (7)

Learning the basics of the Drupal API
Learning the basics of the Drupal APILearning the basics of the Drupal API
Learning the basics of the Drupal API
 
What's new in the Drupal 7 API?
What's new in the Drupal 7 API?What's new in the Drupal 7 API?
What's new in the Drupal 7 API?
 
Drupal, Android and iPhone
Drupal, Android and iPhoneDrupal, Android and iPhone
Drupal, Android and iPhone
 
Publish and Subscribe
Publish and SubscribePublish and Subscribe
Publish and Subscribe
 
Using Features
Using FeaturesUsing Features
Using Features
 
Drupal and Solr
Drupal and SolrDrupal and Solr
Drupal and Solr
 
Prezentare Wurbe
Prezentare WurbePrezentare Wurbe
Prezentare Wurbe
 

Concepte de programare functionala in Javascript

  • 1. Programare funcţională în Javascript Alexandru Badiu
  • 2. Conţinut Ce este programarea funcţională? Funcţii de ordin înalt Funcţii anonime Funcţii imbricate Închideri Currying Programare funcțională în Javascript - Alexandru Badiu
  • 3. Funcţională? Ce este programarea funcţională? Programarea funcţională este o paradigmă de programare Se pune accent pe evaluarea expresiilor şi nu pe execuţia comenzilor Expresiile sunt funcţii Constante vs variabile Lisp, Erlang, Haskell, OCaml Dacă ai scris cod Javascript sau Ruby atunci probabil ai folosit concepte din programarea funcţională fără să ştii Programare funcțională în Javascript - Alexandru Badiu
  • 4. Paradigme? Ce este programarea funcţională? O paradigmă de programare e un stil de a programa Concepte pentru elementele unui program (funcţii, variabile, obiecte etc) Concepte pentru paşii unui calcul (evaluare, atribuire etc) Un limbaj de programare poate oferi suport pentru mai multe paradigme Programare funcțională în Javascript - Alexandru Badiu
  • 5. Procedurală Ce este programarea funcţională? #include <stdio.h> #include <stdlib.h> int main(void) { puts(quot;Hello World!quot;); return EXIT_SUCCESS; } Programare funcțională în Javascript - Alexandru Badiu
  • 6. OO Ce este programarea funcţională? class HelloWorld { static public void main( String args[] ) { System.out.println( quot;Hello World!quot; ); } } Programare funcțională în Javascript - Alexandru Badiu
  • 7. Logică Ce este programarea funcţională? ?- write(”Hello World!”), nl. Programare funcțională în Javascript - Alexandru Badiu
  • 8. Funcţională Ce este programarea funcţională? (alert “Hello World!”) Programare funcțională în Javascript - Alexandru Badiu
  • 9. Limbaje ezoterice Ce este programarea funcţională? HAI CAN HAS STDIO? VISIBLE quot;HAI WORLD!quot; KTHXBYE Programare funcțională în Javascript - Alexandru Badiu
  • 10. HTML Ce este programarea funcţională? <p>HTML nu este un limbaj de programare.</p> Programare funcțională în Javascript - Alexandru Badiu
  • 11. Javascript Ce este programarea funcţională? Programare funcțională în Javascript - Alexandru Badiu
  • 12. Definiţie Funcţii de ordin înalt Funcţiile sunt de ordin înalt Sunt obiecte Au proprietăţi Pot fi transmise altor funcţii Pot fi întoarse ca rezultat Pot fi create dinamic Programare funcțională în Javascript - Alexandru Badiu
  • 13. Exemple Funcţii de ordin înalt function say(what) { console.log(what); } var say = function (what) { console.log(what); } say('hello'); // hello var spune = say; spune('salut'); // salut say = function (what) { console.log('nu vreau'); } spune('ceva'); // ceva Programare funcțională în Javascript - Alexandru Badiu
  • 14. Exemple Funcţii de ordin înalt var gen_func = function (op) { switch (op) { case '+': return function () { var r = arguments[0]; for (var i=1; i<arguments.length; i++ ) r += arguments[i]; return r; } case '-': return function () { var r = arguments[0]; for (var i=1; i<arguments.length; i++ ) r -= arguments[i]; return r; } case '*': return function () { var r = arguments[0]; for (var i=1; i<arguments.length; i++ ) r *= arguments[i]; return r; } case '/': return function () { var r = arguments[0]; for (var i=1; i<arguments.length; i++ ) r /= arguments[i]; return r; } } } var add = gen_func('+'); add; // function () { var r = arguments[0]; for (var i = 1; i < arguments.length; i++) { r += arguments[i]; } return r; } add(1,2,3); // 6 var mul = gen_func('*'); mul(4,5,6); // 120 Programare funcțională în Javascript - Alexandru Badiu
  • 15. Exemple Funcţii de ordin înalt var compune = function (f, g) { return function (x) { return f(g(x)); } }; var a = function (x) { return x*x; }; var b = function (x) { return x/2; }; var c = compune(a, b); var d = compune(b, a); c(6); // 9 d(6); // 18 Programare funcțională în Javascript - Alexandru Badiu
  • 16. Definiţie Funcţii anonime Funcţii fără nume Folosite atunci când codul trebuie rulat o singură dată Folosite la sortări, căutari Folosite la evenimente Programare funcțională în Javascript - Alexandru Badiu
  • 17. Exemple Funcţii anonime (function (what) { console.log(what)}) ('functie anonima'); // functie anonima ( function (x) { if (x<2) return x; return x * arguments.callee(x - 1); }) (3); // 6 Programare funcțională în Javascript - Alexandru Badiu
  • 18. Exemple Funcţii anonime jQuery(quot;div.autoo-more aquot;).click(function(event) { mf = jQuery(this).parent().prev(); mf.toggle(); if (mf.css('display') == 'none') { jQuery(this).html('Mai multe &raquo;'); } else { jQuery(this).html('&laquo; Mai putine'); } return false; }); Programare funcțională în Javascript - Alexandru Badiu
  • 19. Exemple Funcţii anonime var v = [ 6, 12, 19, 8, 40 ]; v.sort(); // 12,19,40,6,8 v.sort(function (x, y) { return x - y; }); // 6,8,12,19,40 v.sort(function (x, y) { return y - x; }); // 40,19,12,8,6 function Cauta(v, f) { for (var i = 0; i < v.length; i++) if (f(v[i])) { return i; } return -1; } Cauta(v, function (x) { return x > 10; }); // 0 Cauta(v, function (x) { return x < 10; }); // 3 Programare funcțională în Javascript - Alexandru Badiu
  • 20. Definiţie Funcţii imbricate Funcţii definite în interiorul altor funcţii Funcţii anonime Funcţii non-anonime Programare funcțională în Javascript - Alexandru Badiu
  • 21. Exemple Funcţii imbricate function imbri(){ var mesaj = quot;salutquot;; function imbri2() { console.log(mesaj); }; imbri2(); }; imbri(); // salut function imbri(mesaj){ ( function () { console.log(mesaj); } ) (mesaj); }; imbri(quot;testquot;); // test Programare funcțională în Javascript - Alexandru Badiu
  • 22. Definiţie Închideri În engleză: closures Funcţiile imbricate au acces la variabilele din funcţia părinte Chiar şi după ce execuţia funcţiei părinte s-a terminat Funcţia = (Funcţia imbricată, Variabile locale) Variabilele nu sunt copiate ci este păstrată o referinţă Programare funcțională în Javascript - Alexandru Badiu
  • 23. Exemple Închideri Funcţia întoarsă are acces la variabila msg function say(what) { var msg = quot;Mesaj: quot; + what; return function () { console.log(msg); }; } say('unu')(); // Mesaj: unu say('doi')(); // Mesaj: doi function say(what) { var ret = function () { console.log(msg); }; var msg = quot;Mesaj: quot; + what; return ret; } say('unu')(); // Mesaj: unu say('doi')(); // Mesaj: doi Programare funcțională în Javascript - Alexandru Badiu
  • 24. Exemple Închideri Acelaşi lucru este valabil şi pentru funcţii declanşate de evenimente function sendRequest(url,callback,postData) { var req = createXMLHTTPObject(); if (!req) { return; } var method = (postData) ? quot;POSTquot; : quot;GETquot;; req.open(method,url,true); req.setRequestHeader('User-Agent','XMLHTTP/1.0'); if (postData) { req.setRequestHeader('Content-type','application/x-www-form-urlencoded'); } req.onreadystatechange = function () { if (req.readyState != 4) return; if (req.status != 200 && req.status != 304) { alert('HTTP error ' + req.status); return; } callback(req); } if (req.readyState == 4) return; req.send(postData); } Programare funcțională în Javascript - Alexandru Badiu
  • 25. Exemple Închideri Mai multe funcţii imbricate au acces la aceeaşi închidere function setup() { var num = 21; afiseaza = function () { console.log(num); } incrementeaza = function () { num++; } } setup(); afiseaza(); // 21 incrementeaza(); afiseaza(); // 22 setup(); afiseaza(); // 21 Programare funcțională în Javascript - Alexandru Badiu
  • 26. Gotchas Închideri Ce este afisat? function pregateste_functii(num) { var res = []; for (var i=0; i<num; i++) { res.push(function () { console.log(i); }); } return res; } var funcs = pregateste_functii(4); for (var i=0; i<funcs.length; i++) { funcs[i](); } Programare funcțională în Javascript - Alexandru Badiu
  • 27. Gotchas Închideri Ce este afisat? function pregateste_functii(num) { var res = []; for (var i=0; i<num; i++) { res.push(function () { console.log(i); }); } return res; } var funcs = pregateste_functii(4); for (var i=0; i<funcs.length; i++) { funcs[i](); } // 4 // 4 // 4 // 4 Programare funcțională în Javascript - Alexandru Badiu
  • 28. Gotchas Închideri this nu se comporta ca în alte limbaje În acest caz this.loaded se referă la ajax_ob.loaded AclinkESM.prototype.loadTemplates = function () { if (this.individual_templates) { this.templates = []; jQuery.ajax({ url: this.config.t_dir + 'anunt-container.ejs', processData: true, dataType: quot;textquot;, success: function(data, status){ this.templates['anunt-container.ejs'] = data; this.loaded++; } }); this.toload++; ... Programare funcțională în Javascript - Alexandru Badiu
  • 29. Gotchas Închideri Soluţia: copierea lui this în altă variabilă, tipic that sau self AclinkESM.prototype.loadTemplates = function () { var that = this; if (this.individual_templates) { this.templates = []; jQuery.ajax({ url: this.config.t_dir + 'anunt-container.ejs', processData: true, dataType: quot;textquot;, success: function(data, status){ that.templates['anunt-container.ejs'] = data; that.loaded++; } }); this.toload++; ... Programare funcțională în Javascript - Alexandru Badiu
  • 30. Definiţie Currying Numit după Haskell Curry Evaluarea parţială a funcţiilor Modifică scope-ul la rulare Matematic: f (X x Y) -> Z curry(f):X -> (Y -> Z) Non matematic: console.log(aduna(2, 3)); // 5 var aduna4 = aduna(4); console.log(aduna4(10)); // 14 Programare funcțională în Javascript - Alexandru Badiu
  • 31. Implementare Currying Varianta simplă function aduna(a) { return function (b) { return a + b; }; } var aduna4 = aduna(4); var aduna10 = aduna(10); aduna4(5); // 9 aduna10(5); // 15 Ideal ar fi să putem aplica procedeul la orice funcţie, fără să o modificăm function aduna(a, b) { return a + b; } var aduna4 = aduna.curry(4); Programare funcțională în Javascript - Alexandru Badiu
  • 32. Implementare Currying Function.prototype.curry = function() { var fn = this, args = []; for (var i = 0; i < arguments.length; i++) args.push(arguments[i]); return function() { for (var i = 0; i < arguments.length; i++) args.push(arguments[i]); return fn.apply(window, args); }; }; function aduna(a, b) { return a + b; } a = aduna.curry(5); b = aduna.curry(10); a(10); // 15 b(10); // 20 Programare funcțională în Javascript - Alexandru Badiu
  • 33. Implementare Currying Uneori este utilă schimbarea scope-ului bind din Prototype, dojo.lang.curry Function.prototype.curry = function(scope) { var fn = this, args = []; var scope = scope || window; for (var i = 1; i < arguments.length; i++) args.push(arguments[i]); return function() { for (var i = 0; i < arguments.length; i++) args.push(arguments[i]); return fn.apply(scope, args); }; }; Programare funcțională în Javascript - Alexandru Badiu
  • 34. Exemple Currying function sayHello(msg) { console.log(msg + 'n You clicked on ' + this.id); } var el1 = document.getElementById('element1'); var el2 = document.getElementById('element2'); el1.addEventListener('click', sayHello.curry(el1, 'Hello'), false); el2.addEventListener('click', sayHello.curry(el2, 'Salut'), false); function update(elem, data) { $(elem).html(data); } $.get(quot;foo.phpquot;, update.curry(window, 'elem1')); $.get(quot;bar.phpquot;, update.curry(window, 'elem2')); function update(data) { $(this).html(data); } $.get(quot;foo.phpquot;, update.curry($('elem1'))); $.get(quot;bar.phpquot;, update.curry($('elem2'))); Programare funcțională în Javascript - Alexandru Badiu
  • 35. Resurse http://www.joelonsoftware.com/items/2006/08/01.html http://osteele.com/archives/2007/07/functional-javascript http://invisibleblocks.wordpress.com/2007/02/23/functional- programming-in-javascript-and-ruby/ Programare funcțională în Javascript - Alexandru Badiu
  • 36. ? Alexandru Badiu i@voidberg.org http://voidberg.org