Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Building DSLs with JavaScript and CoffeeScript

Building DSLs with JavaScript and CoffeeScript

Web developers are integration specialists; tying plugins, scripts and frameworks together into a web application that works. Thinking in terms of abstractions, by condensing many low-level ideas into fewer high-level ideas, allows us to simplify our code and reason about it with less cognitive overhead. In this session we will examine a few techniques for building abstractions on top of popular JavaScript frameworks by building a Domain Specific Language and bringing some convention to our code.

David Mosher

January 09, 2015
Tweet

More Decks by David Mosher

Other Decks in Technology

Transcript

  1. Goals: Theory + Practical Examples What is a DSL? As

    a web developer, why should I care? What practical ways can I apply this knowledge?
  2. Domain Specific Language “Small languages, focused around a specific aspect

    of a software system” ~ Martin Fowler http://martinfowler.com/books/dsl.html
  3. Characteristics “You can't build a whole program with a DSL”

    ~ Martin Fowler http://martinfowler.com/books/dsl.html
  4. External “language that's parsed independently of the host general purpose

    language” http://martinfowler.com/books/dsl.html
  5. External - CSS ruleset : selector [ ‘,’ S* selector

    ]* ‘{‘ S* declaration [ ‘;’ S*declaration ]* ‘}’ S* ; selector : simple_selector [ combinator selector | S+ [ combinator? selector ]? ]? ; simple_selector : element_name [ HASH | class | attrib | pseudo ]* | [ HASH | class | attrib | pseudo ]+ ; class : ‘.’ IDENT ; element_name : IDENT | ‘*’ ; attrib : ‘[‘ S* IDENT S* [ [ ‘=’ | INCLUDES | DASHMATCH ] S* [ IDENT | STRING ] S* ‘]’ ; pseudo : ‘:’ [ IDENT | FUNCTION S* [IDENT S*] ‘)’ ] ;
  6. Internal “form of API in a host general purpose language”

    http://martinfowler.com/books/dsl.html
  7. Internal - Procedural Code http://martinfowler.com/bliki/FluentInterface.html function makeNormal(Customer customer) { Order

    o1 = new Order(); customer.addOrder(o1); OrderLine line1 = new OrderLine(1, Product.find("widget")); o1.addLine(line1); OrderLine line2 = new OrderLine(2, Product.find("pants")); o1.addLine(line2); OrderLine line3 = new OrderLine(3, Product.find("cows")); o1.addLine(line3); line2.setSkippable(true); o1.setRush(true); }
  8. A Question of Value “I use to say, ‘I can

    bend space and time with .toString() and .eval()…
  9. A Question of Value “I’ve come to realize that it’s

    generally better to not bend space and time in JavaScript.” ~ Marak Squires
  10. Focus Areas 1. convention over configuration 2. meaningful semantics 3.

    fluent interfaces 4. extensions to libraries 5. abstractions
  11. Namespacing window.app = { views: { config: {}, }, …

    } // myView.js app = app || {}; app.views = app.views || {}; app.views.myView = {};
  12. Method Chaining: Not Fluency // underscore var childrenOf = function(rootId)

    { return _(navItems).chain().where({parentId: rootId, hidden:false}).map(function(child) { return { title: child.label, url: child.url, ordinal: child.sequence, state: child.name }; }).sortBy(function(child) { return child.ordinal; }).value(); }; // lodash var childrenOf = function(rootId) { return _(navItems).where({parentId: rootId, hidden:false}).map(function(child) { return { title: child.label, url: child.url, ordinal: child.sequence, state: child.name }; }).sortBy(function(child) { return child.ordinal; }); };
  13. Procedural Code http://martinfowler.com/bliki/FluentInterface.html function makeNormal(Customer customer) { Order o1 =

    new Order(); customer.addOrder(o1); OrderLine line1 = new OrderLine(1, Product.find("widget")); o1.addLine(line1); OrderLine line2 = new OrderLine(2, Product.find("pants")); o1.addLine(line2); OrderLine line3 = new OrderLine(3, Product.find("cows")); o1.addLine(line3); line2.setSkippable(true); o1.setRush(true); }
  14. Cost of Implementation “The price of this fluency is more

    effort, both in thinking and in the API construction itself. Coming up with a nice fluent API requires a good bit of thought.” ~ Martin Fowler http://martinfowler.com/bliki/FluentInterface.html
  15. Recap 1. convention over configuration 2. meaningful semantics 3. fluent

    interfaces 4. extensions to libraries 5. abstractions
  16. Values to keep in mind 1. reduce cognitive load 2.

    improve understanding 3. reveal intent