

Opa developer turned technical evangelist
@MLstate (2009-2012)








function showTodoList(items) {
mkSingleTodo = function(item) {
<li>{item}</li>
}
#todos = <ul>{List.map(mkSingleTodo, items)}</>
}
showTodoList(items) =
mkSingleTodo = item -> <li>{item}</li>
#todos = <ul>{List.map(mkSingleTodo, items)}</>
package just.an.example // declaringimport stdlib.widgets.{button, bootstrap.*, dateprinter} // importing
module ModuleA {
function foo() { … }
}
module ModuleB {
private module InnerModule { … }
function bar() { ModuleA.foo(); }
}

| client | ⇔ | server | ⇔ | database |
|
|
|
type user = { int id, int age, string name }database example { user /me user /users[{id}] // id is the primary key }
/example/me/age++
minors = /example/users[age < 18]
users_segment = /example/users[age < 18 or age > 35;
skip 100; limit 50; order +age, -id]
#greeting = <div>You're visitor no. #{/mydb/counter}</>
Q: DOM + DB? Where will this run? Client? Server?
A: Both
client function runInTheBrowser() { … }server function runOnTheBackend() { … }exposed function markAsClientsAccessible() { … }
function getCenter(shape) {
return shape.center;
}
circle = {center: {x: 10, y: 10}};
✔ getCenter(circle) = {x: 10, y: 10}
✔ getCenter({circle with color: "red"}) = {x: 10, y: 10}
✘ getCenter({name: "Joe"}) ↦ compilation error
✘ getCenter({centre: {x: 1, y: 1}}) ↦ compilation error
function string toString({name: string, age: int, ...} person) {
return "{person.name}, born in {2013 - person.age}";
}
personToString({name: "John Doe", age: 23}) = "John Doe, born in 1990"
type point = {float x, float y}
type shape = {circle, point center} or {square, point ul, point dr};
function point getCenter(shape s) {
match (s) {
case ~{circle, center}: center
case ~{square, ul, dr}: …
}
}
✔ getCenter({circle, center: {x: 10., y: 10.}}) = {x: 10., y: 10.}
✔ getCenter({square, ul: {x: 1., y: 2.}, dr: {3., 4.}}) = {x: 2., y: 3.}
✘ getCenter({point, center: {x: 2., y: 13.}) ↦ compilation error
✘ getCenter({circle, center: {x: "zero", y: 1.}) ↦ compilation error
function page() {
userInput = "<script type=\"text/javascript\">alert('Pwned!')</script>"
<div>{userInput}</>
}
Server.start(Server.http, {title: "Test", page: page})
<div id="test">
<script type="text/javascript">
//<![CDATA[
document.getElementById('test').innerHTML =
"<script type='text/javascript'>alert('Pwned!')</script>";
//]]>
</script>
abstract class Shape {
public static double distance(Shape s1, Shape s2) { return s1.distanceTo(s2); }
protected abstract double distanceTo(Shape s);
abstract double distanceToCircle(Shape s);
abstract double distanceToSquare(Shape s);
}
class Circle extends Shape {
Point center;
double radius;
protected double distanceTo(Shape s) { return s.distanceToCircle(this); }
protected double distanceToCircle(Shape s) { … }
protected double distanceToSquare(Shape s) { … }
}
class Square extends Shape {
Point ul;
Point dr;
protected double distanceTo(Shape s) { return s.distanceToSquare(this); }
protected double distanceToCircle(Shape s) { … }
protected double distanceToSquare(Shape s) { … }
}
type shape = {circle, center: Point, radius: float}
or {square, ul: Point, dr: Point}
function distance(shape s1, shape s2) {
match (s1, s2) {
case {s1={circle ...}, s2={square ...}}
case {s1={square ...}, s2={circle ...}}: …
case {s1={circle ...}, s2={circle ...}}: …
case {s1={square ...}, s2={square ...}}: …
}
}
abstract class Shape {
public static double distance(Shape s1, Shape s2) {
return s1.distanceTo(s2);
}
protected abstract double distanceTo(Shape s);
abstract double distanceToCircle(Shape s);
abstract double distanceToSquare(Shape s);
}
class Circle extends Shape {
Point center;
double radius;
protected double distanceTo(Shape s) {
return s.distanceToCircle(this);
}
protected double distanceToCircle(Shape s) { … }
protected double distanceToSquare(Shape s) { … }
}
class Square extends Shape {
Point ul;
Point dr;
protected double distanceTo(Shape s) {
return s.distanceToSquare(this);
}
protected double distanceToCircle(Shape s) { … }
protected double distanceToSquare(Shape s) { … }
}
type shape = {circle, center: Point, radius: float}
or {square, ul: Point, dr: Point}
function distance(shape s1, shape s2) {
match (s1, s2) {
case {s1={circle ...}, s2={square ...}}
case {s1={square ...}, s2={circle ...}}: …
case {s1={circle ...}, s2={circle ...}}: …
case {s1={square ...}, s2={square ...}}: …
}
}

$scope.name = 'Bob';
<!-- 1-way data-binding -->
Hello, {{name}}
<!-- 2-way data-binding -->
Your name: <input ng-model="name" />
http://jsfiddle.net/koper/uMYbH/

function ColorsCtrl($scope) {
$scope.colors = ['blue', 'red', 'green'];
}
<table ng-controller="ColorsCtrl">
<tr><th>Color</th></tr>
<tr ng-repeat="color in colors">
<td ng-bind="color"></td>
</tr>
</table>
http://jsfiddle.net/koper/Atf7U/
function ColorsCtrl($scope) {
$scope.colors = ['blue', 'red', 'green'];
$scope.mkBackgroundColor = function(color) {
return {'background-color': color};
}
$scope.duplicate = function(color) {
$scope.colors.push(color);
}
}
<table ng-controller="ColorsCtrl">
<tr><th>Color</th><th>Name</th></tr>
<tr ng-repeat="color in colors">
<td ng-style="mkBackgroundColor(color)"
ng-click="duplicate(color)">
</td>
<td ng-bind="color"></td>
</tr>
</table>
[ { name: 'Apple Inc', price: 525.63 },
{ name: 'Facebook Inc', price: 49.42 },
{ name: 'Google Inc', price: 1024.95 } ];
<button ng-click="randomize()">Randomize</button>
<table>
<tr><th>Name</th><th>Price</th></tr>
<tr ng-repeat="company in companies">
<td ng-bind="company.name"></td>
<td ng-bind="company.price | currency"></td>
</tr>
</table>
function StocksCtrl($scope) {
$scope.companies = StocksFetcher.get();
$scope.randomize = function() { ... }
}
app.module('components', [])
.directive('tabs', function() {
// ...
})
.directive('pane', function() {
// ...
});
<tabs ng-app="components">
<pane title="Tab 1">Engaging content</pane>
<pane title="Tab 2">Even more engaging content</pane>
</tabs>
http://jsfiddle.net/koper/WQPHz/
function FooService() { … }
module.service('Foo', FooService);
function BarController($window, $http, Foo) { … }
Also:
✔ Models as POJOs ➦ easy logic testing
✔ DOM restricted to directives ➦ most tests DOM-free


