Thanks to visit codestin.com
Credit goes to www.slideshare.net

Exciting JavaScript
 What makes it unique, how to use it.

           Eugene Lazutkin
  Dallas, TX, ClubAjax on 3/2/2010


                  1
Disclaimer

• I will use JavaScript, JS, and ECMAScript
  interchangeably.
• The material is mostly based on
  ECMAScript 3.




                      2
Why JavaScript?
• Browsers.
• CommonJS (ex-ServerJS) is gaining steam.
• CouchDB uses it to define “views”.
• Node.js with its asynchronous event-based
  I/O is red hot.
• An explosion of JavaScript run-time
  environments and libraries.

                     3
JS the Language I
• JavaScript packages a formidable set of
  tools we can leverage to reduce
  complexity.
• While it doesn’t provide a direct support
  for some programming paradigms, it has
  proper tools for us to do it.



                      4
JS the Language II
• Following paradigms can be supported:
 • Object-oriented programming (OOP).
 • Functional programming (FP).
 • Aspect-oriented programming (AOP).
 • Event-driven programming (EDP).
 • Much more.
                    5
What we did last time
• We look into the JavaScript-specific
  language facilities to see what it offers.
• We dissected OOP and AOP paradigms.
• We mapped simple OOP and AOP
  paradigms on top of available constructs.



                       6
What we found
• 1st-class functions.
• Closures.
• Hash-based extendable objects.
• Duck-typing rules!
• OOP can be made with a language, rather
  than provided by a language.


                     7
Simple OOP
// our constructor
var Person = function(name){
 // our instance-level variables
 this.name = name;
};
// our methods and class-level variables/constants
Person.prototype = {
 answer: 42,
 say: function(msg){ alert(this.name + “: “ + msg); }
};




                         8
Simple AOP
// augmenting Person’s say()
var old = Person.prototype.say;
Person.prototype.say = function(msg){
 var newMsg = msg.toUpperCase();
 old.call(this, newMsg);
};


// WARNING: this augmentation doesn’t scale up
// well, use something like dojox.lang.aop




                           9
FP
Functional approach.




         10
FP: short intro I
• It is about representing algorithms as a
  composition of functions.
• It stresses out the algorithmic part of
  programming.
• It is not about states (unlike OOP), but
  about a control flow.


                      11
FP: short intro II
• Higher-order functions:
 • Can consume other functions as
    parameters.
 • Can return functions.
 • That’s where “function as a 1st-order
    value” pays off.


                       12
FP: short intro III
• Pure functions:
 • No side-effects.
 • Why? Easier to combine.
• Recursion is important:
 • We can do it JS too.

                   13
FP in JavaScript?
• Some pieces of our program can be
  functional (e.g., stateless).
• Some side-effects can be deemed “harmless
  for our purposes”.
 • They do not affect our algorithm.

                        14
FP in JavaScript
• Practical FP in JS:
 • Use adapters to customize components.
 • Combine components using chaining.
 • Convert flow statements into functions.
• While jQuery is not an FP toolkit, it has
  popularized the style.


                     15
FP: adapter example
• Remember our hack with “self = this”? We
  can adapt our functions/methods for that:
  function hitch(obj, name){
      return function(){
       var fn = typeof name == “string” ? obj[name] : name;
       return fn.apply(obj, arguments);
      };
  }




                             16
FP: using hitch
var queue = {
 stack: [],
 memorize: function(x){ this.stack.push(x); }
};
queue.memorize(2);
// or we can use it as a function with any context
var q = hitch(queue, “memorize”);
q(2);
q(3);




                         17
FP: control flow
• Control flow can be implemented as
  higher-order functions.
 • Traditionally iteration and recursion are
    major sources of programmer’s errors.
 • Cut’n’paste frequently breaks internal
    loop variables.


                      18
FP: “array extras”
• Back in Firefox 1.5 so-called “array extras”
  were introduced:
  • forEach(), every(), some(), map(), filter(),
    indexOf(), lastIndexOf().
  • Firefox 3 added: reduce(), reduceRight().
• They allow to process arrays as streams
  eliminating direct loops.

                       19
FP: process arrays
• “Array extras” allows writing very compact
  neatly piped data processing:
  var data = [...];
  var result = data.
   map(function(x){ return x * x; }).
   filter(function(x){ return x % 2 == 1; }).
   reduce(function(a, b){ return a + b; });




                           20
More on FP
• jQuery uses similar techniques on
  NodeList with great success.
• I wrote a blog post about FP in JS and how
  it is implemented in Dojo:
 • http://lazutkin.com/blog/2008/jan/12/
    functional-fun-javascript-dojo/


                      21
Inventory (cont.)
    Dynamic language.




           22
Code generation I
• JavaScript can compile text to an
  executable code with two constructs:
  • eval() – compile a string as JavaScript. Any
    valid JavaScript can be compiled.
  • new Function() – compile a function.
• We can generate code for fun and profit!
                      23
Code generation II
• Some environments do not allow code
  generation.
 • Sandboxes can prohibit it for security
    reasons.
 • ES5 strict mode doesn’t allow it. It works
    in ES5 strict mode with some caveats.
 • All browsers in normal mode support it.
                     24
Introspection I
• “for-in” loop enumerates all keys in an
  object.
  • Some keys can be hidden.
• Function.toString() can return a source
  code for a function.
  • Some implementations (e.g., mobile) do
    not support this feature.

                      25
Introspection II
• Function has some additional properties
  like “name” or “length”.
  • Some browsers do not support them.
• ES5 strict mode doesn’t allow inspection of
  “arguments.caller” and “arguments.callee”.



                     26
CG advantage
• Having CG around opens new vistas:
 • We can generate code custom-tailored
    (optimized) to a specific task completely
    on the fly.
 • We can use Domain-Specific Languages
    (DSL) to simplify our problems at hand.


                     27
DSL
Domain-specific languages and code generation.




                     28
Implementing DSL I
• DSL can be implemented in several layers:
 • By providing objects and libraries specific
    for our problem area.
    • Example: HTML DOM.
    • Example: CSS.
    • Example: JSON.
                     29
Implementing DSL II
• If our language supports it, we can provide
  special language constructs to make our
  tasks simpler:
  • Example: regular expressions in
    JavaScript.
  • Example: NodeList and jQuery, or
    dojo.query, or similar facilities of other
    libraries for HTML DOM and CSS.

                      30
Implementing DSL III
• Finally we can implement our own custom
  language, and interpret it, or compile it to
  our implementation language.
• Trade-offs are easy to assess: cost of
  abstraction (e.g., compile time) vs. run time.



                      31
HTML as DSL
// let’s “program” a list
var list = “
<ul>
 <li>Mike</li>
 <li>Bob</li>
</ul>”;
// let’s “interpret” it
ourDomNode.innerHTML = list;
// let’s read it back
var text = ourDomNode.innerHTML;




                            32
CSS as DSL
// CSS selector is used in dojo.query
// (all major libraries can do that nowadays)
dojo.query(“.myClass li”).
 style({
  color: “blue”,
  background: “yellow”
 });




                         33
JSON as DSL
// Let’s produce some JSON
var str = JSON.stringify({
 answer: 42,
 array: [1, 2, 3, 4],
 subObject: {name: “Mike”}
});


// old-school JSON “interpretation”
// (WARNING: don’t do it at home!)
var obj = eval(“(“ + str + ”)”);




                             34
DSL: lambdas I
• Our functional example (slide 20) was as
  compact as possible in JavaScript. But
  imagine that we had a way to reduce the
  functions we used?
• We could have something like that:
  var result =
   data.map(“x * x”).filter(“x % 2 == 1”).reduce(“+”);




                         35
DSL: lambdas II
• Oliver Steele came up with a simple set of
  rules for such language:
  • If lambda ends with an operator, it is a
    place for an implicit argument:
    • “2+”     function(x){ return 2 + x; }



                      36
DSL: lambdas III
• If lambda starts with an operator, it is a
  place for an implicit argument:
  • “+2”     function(x){ return x + 2; }

  • “+”     function(x, y){ return x + y; }

  • “/2+”     function(x, y){ return x / 2 + y; }


                       37
DSL: lambdas IV
• If lambda contains “->” it means it is a full-
  blown function:
  • “a, b -> a + b”
   • function(a, b){ return a + b; }
  • “a, b -> Math.min(a, b)”
   • function(a, b){ return Math.min(a, b); }
                       38
DSL: lambdas V
• Otherwise all different identifiers in a string
  starting with a lower-case symbol assumed
  to be arguments:
  • “x + y”     function(x, y){ return x + y; }

• Obviously all reserved words (like “this”)
  are not considered to be arguments.


                      39
DSL: lambdas VI
• dojox.lang.functional implements
  Oliver’s lambda specification.
 • They can be used consistently in any
    functions provided by this package.
 • Special compilation helpers are provided.

                     40
DSL: using lambdas I
• lambda() is a function to convert from
  lambda strings to functions.
• Let’s rewrite our example:
  var result = data.map(lambda(“x * x”)).
   filter(lambda(“x % 2 == 1”)).
   reduce(lambda(“+”));




                           41
DSL: using lambdas II
• Better, but not an ideal.
• Let’s implement functions, which can take
  either a function or a lambda string:
  var forEach = function(a, f){
   return a.forEach(typeof f == “string” ? lambda(f): f);
  };
  // and so on for other functions




                            42
DSL: using lambdas III
• Now we can reimplement the example:
  var result = map(data, “x * x”);
  result = filter(result, “x % 2 == 1”);
  result = reduce(result, “+”);

• I would say it is much better, yet chaining
  would be a better solution.
• You can do it as an exercise.
                             43
DSL: results I
• While our code is more compact and more
  readable, it takes a hit to compile a lambda.
• While the hit is relatively small, we can
  amortize it by pre-calculating a lambda:
  var f = lambda(“x * x”);
  var result = map(data, f);




                               44
DSL: results II
• Lambdas are harder to debug because we
  don’t have a direct correspondence with
  the code.
• We can mitigate it by using small concise
  expressions. (That’s the idea anyway).



                     45
Conclusion
• JavaScript has a lot of potential from the
  language point of view.
• We just opening it up for real large scale
  development.
• Over time we will see more and more non-
  browser JavaScript-based projects, and
  more complex browser-based apps.


                      46
About me
• I am an independent software developer.
• My web site:
 • http://lazutkin.com
• Follow me on Tweeter:
 • http://twitter.com/uhop

                    47

Exciting JavaScript - Part II

  • 1.
    Exciting JavaScript Whatmakes it unique, how to use it. Eugene Lazutkin Dallas, TX, ClubAjax on 3/2/2010 1
  • 2.
    Disclaimer • I willuse JavaScript, JS, and ECMAScript interchangeably. • The material is mostly based on ECMAScript 3. 2
  • 3.
    Why JavaScript? • Browsers. •CommonJS (ex-ServerJS) is gaining steam. • CouchDB uses it to define “views”. • Node.js with its asynchronous event-based I/O is red hot. • An explosion of JavaScript run-time environments and libraries. 3
  • 4.
    JS the LanguageI • JavaScript packages a formidable set of tools we can leverage to reduce complexity. • While it doesn’t provide a direct support for some programming paradigms, it has proper tools for us to do it. 4
  • 5.
    JS the LanguageII • Following paradigms can be supported: • Object-oriented programming (OOP). • Functional programming (FP). • Aspect-oriented programming (AOP). • Event-driven programming (EDP). • Much more. 5
  • 6.
    What we didlast time • We look into the JavaScript-specific language facilities to see what it offers. • We dissected OOP and AOP paradigms. • We mapped simple OOP and AOP paradigms on top of available constructs. 6
  • 7.
    What we found •1st-class functions. • Closures. • Hash-based extendable objects. • Duck-typing rules! • OOP can be made with a language, rather than provided by a language. 7
  • 8.
    Simple OOP // ourconstructor var Person = function(name){ // our instance-level variables this.name = name; }; // our methods and class-level variables/constants Person.prototype = { answer: 42, say: function(msg){ alert(this.name + “: “ + msg); } }; 8
  • 9.
    Simple AOP // augmentingPerson’s say() var old = Person.prototype.say; Person.prototype.say = function(msg){ var newMsg = msg.toUpperCase(); old.call(this, newMsg); }; // WARNING: this augmentation doesn’t scale up // well, use something like dojox.lang.aop 9
  • 10.
  • 11.
    FP: short introI • It is about representing algorithms as a composition of functions. • It stresses out the algorithmic part of programming. • It is not about states (unlike OOP), but about a control flow. 11
  • 12.
    FP: short introII • Higher-order functions: • Can consume other functions as parameters. • Can return functions. • That’s where “function as a 1st-order value” pays off. 12
  • 13.
    FP: short introIII • Pure functions: • No side-effects. • Why? Easier to combine. • Recursion is important: • We can do it JS too. 13
  • 14.
    FP in JavaScript? •Some pieces of our program can be functional (e.g., stateless). • Some side-effects can be deemed “harmless for our purposes”. • They do not affect our algorithm. 14
  • 15.
    FP in JavaScript •Practical FP in JS: • Use adapters to customize components. • Combine components using chaining. • Convert flow statements into functions. • While jQuery is not an FP toolkit, it has popularized the style. 15
  • 16.
    FP: adapter example •Remember our hack with “self = this”? We can adapt our functions/methods for that: function hitch(obj, name){ return function(){ var fn = typeof name == “string” ? obj[name] : name; return fn.apply(obj, arguments); }; } 16
  • 17.
    FP: using hitch varqueue = { stack: [], memorize: function(x){ this.stack.push(x); } }; queue.memorize(2); // or we can use it as a function with any context var q = hitch(queue, “memorize”); q(2); q(3); 17
  • 18.
    FP: control flow •Control flow can be implemented as higher-order functions. • Traditionally iteration and recursion are major sources of programmer’s errors. • Cut’n’paste frequently breaks internal loop variables. 18
  • 19.
    FP: “array extras” •Back in Firefox 1.5 so-called “array extras” were introduced: • forEach(), every(), some(), map(), filter(), indexOf(), lastIndexOf(). • Firefox 3 added: reduce(), reduceRight(). • They allow to process arrays as streams eliminating direct loops. 19
  • 20.
    FP: process arrays •“Array extras” allows writing very compact neatly piped data processing: var data = [...]; var result = data. map(function(x){ return x * x; }). filter(function(x){ return x % 2 == 1; }). reduce(function(a, b){ return a + b; }); 20
  • 21.
    More on FP •jQuery uses similar techniques on NodeList with great success. • I wrote a blog post about FP in JS and how it is implemented in Dojo: • http://lazutkin.com/blog/2008/jan/12/ functional-fun-javascript-dojo/ 21
  • 22.
    Inventory (cont.) Dynamic language. 22
  • 23.
    Code generation I •JavaScript can compile text to an executable code with two constructs: • eval() – compile a string as JavaScript. Any valid JavaScript can be compiled. • new Function() – compile a function. • We can generate code for fun and profit! 23
  • 24.
    Code generation II •Some environments do not allow code generation. • Sandboxes can prohibit it for security reasons. • ES5 strict mode doesn’t allow it. It works in ES5 strict mode with some caveats. • All browsers in normal mode support it. 24
  • 25.
    Introspection I • “for-in”loop enumerates all keys in an object. • Some keys can be hidden. • Function.toString() can return a source code for a function. • Some implementations (e.g., mobile) do not support this feature. 25
  • 26.
    Introspection II • Functionhas some additional properties like “name” or “length”. • Some browsers do not support them. • ES5 strict mode doesn’t allow inspection of “arguments.caller” and “arguments.callee”. 26
  • 27.
    CG advantage • HavingCG around opens new vistas: • We can generate code custom-tailored (optimized) to a specific task completely on the fly. • We can use Domain-Specific Languages (DSL) to simplify our problems at hand. 27
  • 28.
  • 29.
    Implementing DSL I •DSL can be implemented in several layers: • By providing objects and libraries specific for our problem area. • Example: HTML DOM. • Example: CSS. • Example: JSON. 29
  • 30.
    Implementing DSL II •If our language supports it, we can provide special language constructs to make our tasks simpler: • Example: regular expressions in JavaScript. • Example: NodeList and jQuery, or dojo.query, or similar facilities of other libraries for HTML DOM and CSS. 30
  • 31.
    Implementing DSL III •Finally we can implement our own custom language, and interpret it, or compile it to our implementation language. • Trade-offs are easy to assess: cost of abstraction (e.g., compile time) vs. run time. 31
  • 32.
    HTML as DSL //let’s “program” a list var list = “ <ul> <li>Mike</li> <li>Bob</li> </ul>”; // let’s “interpret” it ourDomNode.innerHTML = list; // let’s read it back var text = ourDomNode.innerHTML; 32
  • 33.
    CSS as DSL //CSS selector is used in dojo.query // (all major libraries can do that nowadays) dojo.query(“.myClass li”). style({ color: “blue”, background: “yellow” }); 33
  • 34.
    JSON as DSL //Let’s produce some JSON var str = JSON.stringify({ answer: 42, array: [1, 2, 3, 4], subObject: {name: “Mike”} }); // old-school JSON “interpretation” // (WARNING: don’t do it at home!) var obj = eval(“(“ + str + ”)”); 34
  • 35.
    DSL: lambdas I •Our functional example (slide 20) was as compact as possible in JavaScript. But imagine that we had a way to reduce the functions we used? • We could have something like that: var result = data.map(“x * x”).filter(“x % 2 == 1”).reduce(“+”); 35
  • 36.
    DSL: lambdas II •Oliver Steele came up with a simple set of rules for such language: • If lambda ends with an operator, it is a place for an implicit argument: • “2+” function(x){ return 2 + x; } 36
  • 37.
    DSL: lambdas III •If lambda starts with an operator, it is a place for an implicit argument: • “+2” function(x){ return x + 2; } • “+” function(x, y){ return x + y; } • “/2+” function(x, y){ return x / 2 + y; } 37
  • 38.
    DSL: lambdas IV •If lambda contains “->” it means it is a full- blown function: • “a, b -> a + b” • function(a, b){ return a + b; } • “a, b -> Math.min(a, b)” • function(a, b){ return Math.min(a, b); } 38
  • 39.
    DSL: lambdas V •Otherwise all different identifiers in a string starting with a lower-case symbol assumed to be arguments: • “x + y” function(x, y){ return x + y; } • Obviously all reserved words (like “this”) are not considered to be arguments. 39
  • 40.
    DSL: lambdas VI •dojox.lang.functional implements Oliver’s lambda specification. • They can be used consistently in any functions provided by this package. • Special compilation helpers are provided. 40
  • 41.
    DSL: using lambdasI • lambda() is a function to convert from lambda strings to functions. • Let’s rewrite our example: var result = data.map(lambda(“x * x”)). filter(lambda(“x % 2 == 1”)). reduce(lambda(“+”)); 41
  • 42.
    DSL: using lambdasII • Better, but not an ideal. • Let’s implement functions, which can take either a function or a lambda string: var forEach = function(a, f){ return a.forEach(typeof f == “string” ? lambda(f): f); }; // and so on for other functions 42
  • 43.
    DSL: using lambdasIII • Now we can reimplement the example: var result = map(data, “x * x”); result = filter(result, “x % 2 == 1”); result = reduce(result, “+”); • I would say it is much better, yet chaining would be a better solution. • You can do it as an exercise. 43
  • 44.
    DSL: results I •While our code is more compact and more readable, it takes a hit to compile a lambda. • While the hit is relatively small, we can amortize it by pre-calculating a lambda: var f = lambda(“x * x”); var result = map(data, f); 44
  • 45.
    DSL: results II •Lambdas are harder to debug because we don’t have a direct correspondence with the code. • We can mitigate it by using small concise expressions. (That’s the idea anyway). 45
  • 46.
    Conclusion • JavaScript hasa lot of potential from the language point of view. • We just opening it up for real large scale development. • Over time we will see more and more non- browser JavaScript-based projects, and more complex browser-based apps. 46
  • 47.
    About me • Iam an independent software developer. • My web site: • http://lazutkin.com • Follow me on Tweeter: • http://twitter.com/uhop 47