Giter Club home page Giter Club logo

notes's Introduction

Hierarchical composition by responsibility in JavaScript

  • Composition + Single responsibility
    • Reuse
    • Independent evolution of elements
      • Less friction to test and document
    • Clearer points of extension and modification
  • Systematic approach
    • Convention for human
    • Mechanical automation

Tower of abstraction

  • Separate definition and use Isolated definitions allow building concrete hierarchies though relational combination like normalization in relational databases
  • Separate data and functions
    • Functions or procedures generally encode information that is coupled to the run-time platform where it will be interpreted
    • Data descriptions are much less tightly coupled and it is much cheaper to map to a different encoding. For example it is relatively easy to have one data definition from which to mechanically derive:
      • The database schema
      • The html form for the UI
      • The JSON format for client/server exchange
      • Validation rules for different run-times (e.g.: JavaScript and Java)
  1. Primitives
  2. Combination: ADTs and Objects
  3. Abstracting dispatch: Generic functions

Primitives

Data
Built-in types: Undefined, Null, Boolean, String, Number, and Object
Functions
On built-in types Maximum re-usability
function distance(x0, y0, x1, y1) {
    var x = x0 - x1;
    var y = y0 - y1;
    return Math.sqrt(x * x + y * y);
}

versus

function distance(point1, point2) {
    var x = point1.x - point2.x;
    var y = point1.y - point2.y;
    return Math.sqrt(x * x + y * y);
}

// or

Point.prototype.distance = function(point) {
    var x = this.x - point.x;
    var y = this.y - point.y;
    return Math.sqrt(x * x + y * y);
};

While both define the relationship between elements, the later is coupled with the responsibility of destructuring and is tied to a specific representation.

Combination

ADTs
mapping aggregate data to functions on primitives
'use strict';

function distance(x0, y0, x1, y1) {
    var x = x0 - x1;
    var y = y0 - y1;
    return Math.sqrt(x * x + y * y);
}

function move(origin, delta) {
    return origin + delta;
}


var Point = function Point(x, y) {
    return { x: x, y: y };
};

Point.move = function movePoint(point1, point2) {
    var x = move(point1.x, point2.x);
    var y = move(point1.y, point2.y);
    return Point(x, y);
};

Point.distance = function distanceToPoint(point1, point2) {
    return distance(point1.x, point1.y, point2.x, point2.y);
};
Objects
partially applied ADTs
'use strict';

function createPointInstance(x, y) {
    var pointInstance = new Point(x, y);
    return {
        move: function move(point2) {
            return Point.move(pointInstance, point2);
        },
        distance: function distance(point2) {
            return Point.distance(pointInstance, point2);
        }
    };
}

// or

function createPointInstance(x, y) {
    var pointInstance = new Point(x, y);
    return Object.keys(Point).reduce(function r(acc, key) {
        acc[key] = Point[key].bind(null, pointInstance);
        return acc;
    }, {});
}

// or

function createInstance0(Obj /* consArgs */) {
    var consArgs = Array.prototype.slice.call(arguments, 1);
    var instance = Obj.apply(Obj, consArgs);
    return Object.keys(Obj).reduce(function r(acc, key) {
        acc[key] = Obj[key].bind(null, instance);
        return acc;
    }, {});
}

// or

function partial(instance, obj) {
    return Object.keys(obj).reduce(function r(acc, key) {
        acc[key] = obj[key].bind(null, instance);
        return acc;
    }, {});
}

function createPointInstance(x, y) {
    return partial(new Point(x, y), Point);
}

Abstracting dispatch: Generic functions

'use strict';

var functions = {
    a: function a(obj, arg) { return 'a fn; ' + obj['@type'] + '; ' + arg + ';'; },
    b: function b(obj, arg) { return 'b fn; ' + obj['@type'] + '; ' + arg + ';'; }
};

function typeSelector(meths, args) { return meths[args[0]['@type']]; }

var selector = typeSelector.bind(null, functions);

function ap(sel /* args */) {
    var args = Array.prototype.slice.call(arguments, 1);
    var fn = sel(args);
    return fn.apply(null, args);
}

var ab = ap.bind(null, selector);

var a = { '@type': 'a' };
var b = { '@type': 'b' };

console.log(ab(a, 'a args'), ab(b, 'b args'));

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.