By Dionysios G. Synodinos. DSL Foundation JavaScript: The Language Client-Side Frameworks The...

58
$("#presentation") .attr("title", "JavaScript DSLs " + "for the Client Side") By Dionysios G. Synodinos

Transcript of By Dionysios G. Synodinos. DSL Foundation JavaScript: The Language Client-Side Frameworks The...

$("#presentation").attr("title",

"JavaScript DSLs " +"for the Client Side")

By Dionysios G. Synodinos

Overview

DSL Foundati

on

JavaScript: The

Language

Client-Side

Frameworks

The Challeng

e for HTML 5

Create your own

JavaScript DSL

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.

Two types of DSLs

Internal•Change the feel of the host language to be better suited for a domain

External•External DSLs have their own custom syntax and you write a full parser to process them.

Well-known DSLs

Make, Ant, NAnt, Rake

•Software Builds

SQL

•Relational Data Manipulation

HQL, JPQL

•OO Data Querying

XSL

•XML Transformations

CSS

•Styling documents written in MLs

Regular Expressions

•String Identification

JavaFX Script

•Rich Internet Applications

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

… but is JavaScript any good for DSL?

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

TextualSyntactic

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

if (!(conditional)) { statements}

unless (conditional) { statements}

// use functional literalvar unless = function(conditional, statements) { if (!(conditional)) { return statements(); }}// now call itunless(conditional, function() { statements;});

Mimicking Macros #2

if (!(conditional)) { statements}

unless (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

…so what can you do will all this goodness?

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 classvar Animal = new JS.Class({ initialize: function(name) { this.name = name; },

speak: function(things) { return 'My name is ' + this.name + ' and I like ' +

things; }});

// Create the objectvar nemo = new Animal(‘Lassie');

// Call class methodnemo.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 chainvar chain = new JS.MethodChain();

// Call map(), join() and replace() on it chain

.map(function(s) { return s.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 ecmascript 4, so using it in a DSL might be an issue.

Frameworks, frameworks, frameworks…

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(){ return dojo.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 AJAXvar xhr;

if (window.XMLHttpRequest) { xhr = new XMLHttpRequest();}else if (window.ActiveXObject) { xhr = new

ActiveXObject("Msxml2.XMLHTTP");}else { throw new 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, DELETESELECT ... FROMWHERE clausesLIKE supportORDER BY (sorting on multiple columns, ASC and DESC)AS (aliases)GROUP BY, HAVING aggregationSUM, COUNT, AVG aggregate functionsself joinsLIMIT and offsets

… in the browser with standard JavaScript!

TrimQuery Example: Define Schema

var columnDefs = {Invoice : { id : { type: "String" },

total : { type: "Number" },

custId : { type: "String" } },

Customer : { id : { type: "String" },acctBalance : { type: "Number" }

}};

TrimQuery Example cont.: Create data records

var tableData = { 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 } ] };

TrimQuery Example cont.: Execute a query

// Import schemavar queryLang = TrimPath.makeQueryLang(columnDefs);

// Do a SELECT statement.var statement = queryLang.parseSQL(

"SELECT Customer.id, Customer.acctBalance, Invoice.total " +"FROM Customer, Invoice " +"WHERE Customer.id = Invoice.custId " +"ORDER BY Customer.id ASC");

// Execute queryvar results = statement.filter(tableData);

// ->[ { id: 10, acctBalance: 1000, total: 100 },// { id: 10, acctBalance: 1000, total: 200 },// { id: 10, acctBalance: 1000, total: 300 },// { id: 20, acctBalance: 2000, total: 400 } ]

New functionality in HTML 5Several new APIs are exposed to JavaScript developers and framework creators including:

Canvas for 2D Drawing

Built-in Media

Support

Offline Storage

Web Sockets

Built-in Media Support

<video src=“somevideo.ogg“ id=“myvideo“></video><script> var video = document.getElementById(“myvideo");</script><p><button type="button" onclick="video.play();">Play</button> <button type="button" onclick="video.pause();">Pause</button> <button type="button" onclick="video.currentTime = 0;">&lt;&lt; Rewind</button>

show_video(“somevideo.ogg").add_controls([’play’, ’pause’, ’rewind’]);

DSL for Media

2D Drawing with <canvas>if (canvas.getContext){

// use getContext to use the canvas for drawing var ctx = canvas.getContext('2d');

// Draw shapes ctx.fillRect(25,25,100,100); ctx.clearRect(45,45,60,60); ctx.strokeRect(50,50,50,50); }

var exampleData = [

{ time: 10, count: 7382 },{ time: 20, count: 1852 },{ time: 35, count: 2397 },{ time: 50, count: 1442 },{ time: 55, count: 1854 }

]

plot().chart_type('CurvedArea').with_data(exampleData)

Charting DSL

Web Sockets

var con = new WebSocket("ws://mywebsocket.com");con.onopen = function(evt) { alert("Connection open ..."); };con.onmessage = function(evt) { alert( "Received Message: " + evt.data); };con.onclose = function(evt) { alert("Connection closed."); };con.postMessage("Hello Web Socket! ");con.disconnect();

connect_to("ws://websocket.stockquotes.com").get_quotes("MSFT")

.when().falls_under("18$")

.action(['alert','Stock is dropping!'])

Stock Quotes

DSL

Offline Storage

db = openDatabase("dbTest", "1.0", "First Database", 300000);db.transaction(function(tx) {

tx.executeSql("SELECT * FROM MyTb”, [], function(tx, result) { alert(result.rows.item(0)['id']);

}); });

var acustomer = ['John', 'Doe', '[email protected]'];db.store(acustomer);

ORM DSL

Create your own JavaScript DSL Create the specs in natural language

Show us-state field when country select box is “US” Find DSL notation that is closest to the

problem domaincreate_dynamic_field("show", "us-state-field", "country", "USA")show("show-state-field").when("country").is("USA")

Start building the functions that get chained in an iterative and incremental manner

Having proper tests helps big time!

References

Macros in JavaScript please http://peter.michaux.ca/articles/macros-in-javascript-please

Declarative JavaScript programming http://www.dotnetjunkies.com/WebLog/anoras/archive/2004/08/09/21502.aspx

Project JS.Class http://jsclass.jcoglan.com/ Dojo Tookit http://dojotoolkit.com/ Creating Your Own $ [in Dojo]

http://dojocampus.org/content/2008/03/13/creating-your-own/

jQuery Library http://jquery.com/ Even. Behavior http://livepipe.net/extra/event_behavior Ojay http://code.google.com/p/ojay/ TrimQuery

http://code.google.com/p/trimpath/wiki/TrimQuery Metaprogramming JavaScript

http://www.adamlogic.com/wp-content/uploads/2007/03/metaprogramming-javascript.pdf