Roy

Brian McKenna

Java Developer

Brian McKenna

Scala Developer

Brian McKenna

Haskell Developer

Brian McKenna

JavaScript Developer
Roy

altJS language

CoffeeScript, ClojureScript, Objective-J,
HaXe, Emscripten, Fantom, JSIL,
Opa, Pit, Pyjamas...
types

Simon Peyton-Jones

“Types are, the world's
most used formal method,
by... 6 orders of magnitude...”
functional
Completely immutable
readable
“It's kind-of just JavaScript”
CoffeeScript
×
  OCaml, Haskell  
αlpha
let hundred = 100 
var hundred = 100;
// Won't compile
// console.log ("40" + 2)
let f x : Number = x


console.log (f 100)
// Won't compile:
// console.log (f "100")
var f = function(x) {
    return x;
};
console.log(f(100));
// Won't compile:
// console.log (f "100")
NumberNumber
BooleanBoolean
StringString
[Number]Array
(Number, String)Array
Function(Number,String)Function
{name: String}Object

structural types

let plusXY a = a.x + a.y
console.log (plusXY obj)
console.log (plusXY {x: 2, y: 1})
// Won't compile
// plusXY {x: 1, z: 2}
var plusXY = function(a) {
    return a.x + a.y;
};
console.log(plusXY(obj));
console.log(plusXY({
    "x": 2,
    "y": 1
}));
// Won't compile
// plusXY {x: 1, z: 2}

sum types

data Option a =
  Some a | None
var Some = function(a_0) {
    if(!(this instanceof Some)) {
        return new Some(a_0);
    }
    this._0 = a_0;
};
var None = function() {
    if(!(this instanceof None)) {
        return new None();
    }
};

pattern matching

let noneZero o = match o      
  case (Some s) = s
  case None = 0
var noneZero = function(o) {
    return (function() {
        if(o instanceof Some) {
            var s = o._0;
            return s;
        } else if(o instanceof None) {    
            return 0;
        }
    })();
}
noneZero (None ())
// 0
noneZero (Some 1)
// 1
noneZero(None());
// 0
noneZero(Some(1));
// 1

type classes

Number.prototype.isValid = function() {
    return this > 0;
};
Number.prototype.isValid = function() {
    return this > 0;
};
// ...
Number.prototype.isValid = function() {
    return this == 1;
};
typeclass IsValid #a {
  isValid: #a -> Boolean
}

instance numberIsValid = IsValid Number {
  isValid: \x -> x > 0
}

isValid 100 // true
var numberIsValid = {
    "isValid": function(x) {
        return x > 0;
    }
};

numberIsValid.isValid(100); // true
instance stringIsValid = IsValid String {
  isValid: \x -> x != ""
}

isValid "test" // true
isValid 100 // true
Escaping
Callback Hell
with monad syntax
app.get('/index', function(req, res, next) {
    User.get(req.params.userId, function(err, user) {
        if(err) return next(err);
        db.find({user: user.name}, function(err, cursor) {
            if(err) return next(err);
            cursor.toArray(function(err, items) {
                if(err) return next(err);
                res.send(items);
            });
        });
    });
});
let deferred = {
  return: \x -> $.when x
  bind: \x f -> x.pipe f
}
var deferred = {
    "return": function(x) {
        return $.when(x);
    },
    "bind": function(x, f) {
        return x.pipe(f);
    }
};
let v = do deferred
  val <- $.ajax 'examples/helloworld.roy'
  val2 <- $.ajax 'examples/alias.roy'
  return (val ++ val2)
var v = (function(){
    return deferred.bind($.ajax('examples/helloworld.roy'), function(val) {
        return deferred.bind($.ajax('examples/alias.roy'), function(val2) {
            return deferred.return(val + val2);
        });
    });
})();

modules

compile to
all the
module standards?!

Roy write-once module

import "./settings"

let appName = "App " ++ settings.name
export appName

Browser global object

(function() {
// Using browser module: "settings"
var appName = "App " + settings.name;
this["appName"] = appName;
})();

CommonJS 1.0 (node.js)

var settings = require("./settings");
var appName = "App " + settings.name;
exports["appName"] = appName;

Async module defs

define('mymodule', ['settings'],
  function(requre, exports, settings) {
    var appName = "App " + settings.name;
    exports["appName"] = appName;
  }
);
future

Functional lenses

make immutability more convenient than Haskell
let me = {name: "Brian", age: 21}
let ageLens = .age

get ageLens me // gives back 21
set ageLens 22 me // copy, updated age

Deferred type errors

blatantly copy Haskell's new feature
./roy --defer-type-errors my-program.roy
if true then
  console.log (1 + 1)
else
  console.log ("TODO" + 1)
if(true) {
  console.log(1 + 1);
} else {
  console.log((function(){
    throw new Error("String is not Number");
  })());
}
call to action
roy.brianmckenna.org
Gracias!
@puffnfresh