Dive into some of the clever ideas of the Elm programming language and how they can be applied to current JavaScript development.
Presented at Pandamonium 2016, an Instructure Engineering Conference.
https://pandamonium2016.sched.org/event/5w4r/what-is-elm-and-why-should-i-care
Alternate format: http://tgroshon.github.io/elm-pandamonium-pres
5. INTRO: TOOL-CHAIN
Written in Haskell
elm-make # Compiles Elm to JS
elm-package # Package Manager
elm-repl # A Read-Eval-Print-Loop
elm-reactor # Quick-start Watcher/Builder
elm # Wrapper around all the tools
OTHER TOOLS
Webpack Loader:
elm-make JS Bindings:
https://github.com/rtfeldman/elm-
webpack-loader
https://github.com/rtfeldman/node-elm-compiler
10. IA: FLOW
flowtype.org
/* @flow */
function foo(x) {
return x * 10;
}
foo('Hello, world!'); // Error: This type is incompatible with ...: string
/* @flow */
function foo(x: string, y: number): string {
return x.length * y;
}
foo('Hello', 42); // Error: number ... type is incompatible with ... string
Babel will strip it out for you:
http://babeljs.io/docs/plugins/transform-flow-strip-types/
16. SIGNAL GRAPH
(CONT'D)
An Application's signal graph can have multiple sources,
branches, and sinks.
Sources:
position : Signal (Int, Int) -- Mouse
clicks : Signal () --
dimensions : Signal (Int, Int) -- Window
Branches (Transforms):
map : (a -> b) -> Signal a -> Signal b
filter : (a -> Bool) -> a -> Signal a -> Signal a
merge : Signal a -> Signal a -> Signal a
foldp : (a -> s -> s) -> s -> Signal a -> Signal s
Sinks:
main : Signal Element -- element to be rendered to screen
port someJavaScriptFn : Signal String -- Send strings to JavaScript
19. IA: RXJS
RxJS implements Observables
/* Get stock data somehow */
var source = getAsyncStockData() // Source is an observable
source
.filter(function (quote) { // Branches
return quote.price > 30
})
.map(function (quote) {
return quote.price
})
.subscribe(function (price) { // Sink
console.log('Prices higher ' +
'than $30: $' +
price)
})
Most popular but also the largest file size (around 200kb
minified)
Can choose asynchrony between setImmediate,
setTimeout, requestAnimationFrame
20. IA: MOST.JS
Monadic Streams
most.from([1, 2, 3, 4])
.delay(1000)
.filter(function(i) {
return i % 2 === 0
})
.reduce(function(result, y) {
return result + y
}, 0)
.then(function(result) {
console.log(result)
})
Super fast and around 50kb minified, uncompressed
Consuming functions (reduce, forEach, observe)
return Promises.
21. IA: FLYD
Pronounced flu (it's Dutch)
var x = flyd.stream(10) // Create stream with initial value
var y = flyd.stream(20)
var sum = flyd.combine(function(x, y) {
return x() + y() // Calling stream without argument returns last value
}, [x, y])
flyd.on(function(s) {
console.log(s)
}, sum)
Very Simple. Modeled after Elm Signals.
Mostly just gives low-level composition constructs e.g.
combine, merge, transduce
23. TASKS
type Task x a
Represents asynchronous effects that
return value of type a but may fail with
value of type x.
Sound like Promises? They are even chainable with
andThen:
logCurrentTime : Task x ()
logCurrentTime =
getCurrentTimeTask `andThen` consoleLogTask
29. IA: PROMISES
var p = new Promise(function(resolve, reject) {
// something async happens
});
p.then(successHandlerFn, failureHandlerFn);
What can we learn from Elm?
Don't reject promises needlessly
var p = new Promise(function (resolve, reject) {
doAsync(function (err, result) {
if (err) {
return resolve({status: 'failed', data: err})
}
resolve({status: 'success', data: result})
})
})