580 likes | 683 Views
$("#presentation") . attr ("title", " JavaScript DSLs " + " for the Client Side "). By Dionysios G. Synodinos. Overview. What is a DSL?.
E N D
$("#presentation") .attr("title", "JavaScript DSLs " + "for the Client Side") By Dionysios G. Synodinos
What is a DSL? A domain-specific language (DSL) is a programming language or executable specification language that offers, through appropriate notations and abstractions, expressive power focused on, and usually restricted to, a particular problem domain.
Characteristics • Focused expressive power. • Usually small, offering only a restricted suite of notations and abstractions. • Not necessarily Turing complete. • May contain an entire general-purpose language (GPL) as a sublanguage • Usually declarative
Advantages • Domain experts themselves can understand, validate, modify, and even develop DSL programs • DSL programs are concise, self-documenting to a large extent, and can be reused for different purposes • DSLs embody domain knowledge, and thus enable the conservation and reuse of this knowledge • DSLs allow validation and optimization at the domain level
Disadvantages • Costs of designing & implementing • Cost of maintenance • Costs of education for users • Difficulty of balancing between domain-specificity and general-purpose programming language constructs. • Potential loss of efficiency when compared with hand-coded software.
Nature of JavaScript • “Simple”, highly dynamic, object-based language • Mixture of object-based and functional programming • Takes its major ideas from the languages Self and Scheme.
Scheme • One of the two main dialects of Lisp (the other being Common Lisp) and best known for its support of functional programming. • Its philosophy is very minimalist • Provides as few primitive notions as possible • Lets everything else be provided by programming libraries
Lisp Lisp programs can manipulate source code as a data structure, giving rise to the macro systems that allow programmers to create new syntax or even new domain-specific programming languages embedded in Lisp.
JavaScript Goodness • C-like syntax • OO syntax mimics Java • Prototype based Inheritance • Dominant in HTML scripting • AJAX, Adobe AIR, Google Gears • Mozilla Rhino • XML via DOM • JSON • Only mainstream language with real specs • Java and .NET support
People usually complain about… • Lack of namespaces • method_missing() • Prototype Weirdness
Method Chaining Make modifier methods return the host object so that multiple modifiers can be invoked in a single expression. YES
Nested Function Compose functions by nesting function calls as arguments of other calls. YES
Convenient Literal Collection Expression Have lists and maps, with a concise literal syntax built-in in order to express language constructs. Lists are good for multiple items of the same thing while Maps work well for an unordered argument list YES
Closures Are fragments of code that can be easily declared in expressions and passed around as objects. For DSL purposes they are very good at providing a limited context for a section of the code. YES
Macros NO
…coping with the lack of macros outside of the language • Use a text editor snippet (e.g. Eclipse Templates) • Use a x-to-JavaScript compiler like GWT
Mimicking Macros #1 unless (conditional) { statements } if (!(conditional)) { statements } // use functional literal var unless = function(conditional, statements) { if (!(conditional)) { return statements(); } } // now call it unless(conditional, function() { statements; });
Mimicking Macros #2 unless (conditional) { statements } if (!(conditional)) { statements } var unless = function(conditional, statements) { return'if (!('+conditional+')) {'+ statements + '}'; } // use eval()eval(unless("conditional", "statements"))
Annotations An Annotation allows a programmer to attach attributes to programming constructs such as classes and methods. These annotations can be read during compilation or at runtime. YES
Example: Project JS.Class A library designed to facilitate OO development in JavaScript. It implements Ruby’s core object, module and class system and some of its metaprogramming facilities, giving you a powerful base to build well-structured OO programs.
JS.Class Supports • Classes and modules with Ruby-compatible inheritance • Subclassing and mixins • Late-binding arguments-optional super calls to parent classes and mixins • Singleton methods • included, extended and inherited hooks • Method binding • Ports of various standard Ruby modules, including Enumerable, Observable, Comparable, Forwardable
JS.Class Example #1: Classes // Define the class var Animal = newJS.Class({ initialize: function(name) { this.name = name; }, speak: function(things) { return'My name is ' + this.name + ' and I like ' + things; } }); // Create the object varnemo = new Animal(‘Lassie'); // Call class method nemo.speak('swimming') // -> "My name is Lassie and I like swimming"
JS.Class Example #2: Method Chaining that feels like Macros //Create a MethodChain object called chain var chain = newJS.MethodChain(); // Call map(), join() and replace() on it chain .map(function(s) { returns.toUpperCase() }) .join(', ') .replace(/[aeiou]/ig, '_'); // Now chain object calls the stored chain on any object you pass to its fire() method chain.fire(['foo', 'bar']) // -> "F__, B_R" A mechanism for storing a sequence of method calls and then executing that sequence on any object you like.
A general word of advice "is" was proposed to be a reserved word in ecmascript4, so using it in a DSL might be an issue.
Dojo Toolkit • Dojo is more verbose than other frameworks • Heavily uses namespaces! Dion Almear wanted to make a plugin for his editor to grey-out the string “dojo.” :) • prefers dojo.byId and dojo.query over the popular $ operator • Although Dojo was inspired by Python, AOP, PHP, Java, and a variety of functional programming language constructs like hitch, mixins, delegation, and more. • However, the Dojo team explicitly avoid using any patterns from other languages, and made great efforts to leverage the patterns unique to JavaScript.
Dojo and DSL? “Dojo takes advantage of the flexibility of JavaScript rather than trying to provide a domain specific language on top of JavaScript.” Dylan SchiemannCEO of SitePen & co-creator of the Dojo Toolkit.http://www.sitepen.com/blog/2008/10/27/debunking-dojo-toolkit-myths/
Does this mean no DSL with Dojo? JavaScript is an open language and you can poke around
$() for Dojo $ = dojo.mixin( function(){ returndojo.mixin( dojo.query.apply(this, arguments), $.fn); }, dojo, { fn: {} } );
Plugd for Dojo plugd is a collection of useful functionality built on and around Base $("p.baz") .appendTo("body") .addClass("bar") .onclick(function(e){ e.target.innerHTML = “Hello World"; }); “The API's found in plugd are loosely based on my favorite bits of jQuery” Pete Higgins
jQuery Library • Very easy and powerful for DOM manipulation • Heavily uses $() • Uses CSS selectors • $(selector) • Returns an array of elements that match the selector, • e.g. $(p a) • Feels like a CSS extension mechanism
jQuery Library cont. • $() wraps elements with additional functionality and adds several useful oparations • e.g. $("div.areaToBeRemoved").fadeOut(); • Since methods return grous of elements, you can have method chaining • e.g. $("p").addClass("test").show().html("foo");
jQuery Implements CSS Selectors • $("p > a") • $(“p:first-child") • $("tr:nth-child(1)")
jQuery has basic support for XPath • $("iframe[id^='frame']") • $("a[href$=pdf]") • $("//div ~ form")
jQuery custom selectors • $("p:even") • $("div:hidden").show(); • $("p:first").css("fontWeight","bold");
jQuery for AJAX varxhr; if (window.XMLHttpRequest) { xhr = newXMLHttpRequest(); } elseif (window.ActiveXObject) { xhr = newActiveXObject("Msxml2.XMLHTTP"); } else { thrownew Error("Ajax not supported"); } xhr.onreadystatechange = function() { if (xhr.readyState == 4) { if (xhr.status >= 200 && xhr.status < 300) { document.getElementById('myContainer') .innerHTML = xhr.responseText; } } } xhr.open('GET','/imported.html'); xhr.send(); $('#myContainer').load('imported.html'); • $("#myContainer") • .load("imported.html")
Project: Event.Behavior A Prototype extension that tries to add "natural language event programming for Prototype". Example: with(Event.Behavior){ set_style(styles).on(paragraphs).when(selects).change(); }
Event.Behavior: Basic Sentence Construction The basic rule is: one verb construct, followed by when(), followed by at least one event or condition. If no events are specified, changes() is implicit.
Event.Behavior cont. with(Event.Behavior){ add_class_name('black') .to('paragraph') .when('color_select') .is('black') add_class_name('bold') .to('paragraph') .when('weight_select') .is('bold') show('province_field') .when(‘country') .is(‘Canada') }
Project: Ojay • Provides a DSL-style API for writing specs for validating form input, handling errors when they occur, and allowing forms to be submitted using Ajax. • Is an interface that wraps the Yahoo! User Interface library in order to make code easier to read and write, by allowing more sentence-like OO syntax and minimizing repetition.
Ojay Example $('a#run-this-code').on('click', $.stopEvent) .setContent('Running...') ._('#example').animate({ height: {to: 0}, opacity: {from: 1, to: 0} }, 0.5) ._($.HTTP).GET('/service/hello.html') .insertInto('#example') ._('#example').animate({ height: {to: 80}, opacity: {from: 0, to: 1} }, 0.7);
Ojay supported CSS Selectors • document.querySelectorAll • YAHOO.util.Selector • Ext.DomQuery • Sizzle • Peppy Pluggable CSS Selector Engine used in jQuery
Project: TrimQuery Provides component that lets you have the power of SQL queries while running in a web browser. The engine supports several SQL concepts like: • INSERT, UPDATE, DELETE • SELECT ... FROM • WHERE clauses • LIKE support • ORDER BY (sorting on multiple columns, ASC and DESC) • AS (aliases) • GROUP BY, HAVING aggregation • SUM, COUNT, AVG aggregate functions • self joins • LIMIT and offsets … in the browser with standard JavaScript!
TrimQuery Example: Define Schema varcolumnDefs = { Invoice : { id : { type: "String" }, total : { type: "Number" }, custId : { type: "String" } }, Customer : { id : { type: "String" }, acctBalance : { type: "Number" } } };
TrimQuery Example cont.: Create data records vartableData = { Invoice : [ { id: 1, total: 100, custId: 10 }, { id: 2, total: 200, custId: 10 }, { id: 3, total: 300, custId: 10 }, { id: 4, total: 400, custId: 20 } ], Customer : [ { id: 10, acctBalance: 1000 }, { id: 20, acctBalance: 2000 }, { id: 30, acctBalance: 3000 } ] };