Skip to content

Instantly share code, notes, and snippets.

type UserInput = { x: Int, y: Int, jump: Bool }
type Direction = { x: Int, y: Int }
directions : Signal Direction
directions = merge Keyboard.arrows Keyboard.wasd
jump : Signal Bool
jump = Keyboard.space
@hughfdjackson
hughfdjackson / inferring-purity.md
Created May 23, 2014 10:57
inferring-purity.md

It would be useful to be able to infer whether or not an expression is pure - even in languages with rampant side-effectfulness and mutability, such as JavaScript. Here's my ad-hoc thoughts on how it might be achieved.

Terms

A pure expression is denoted as P -> x - that is, an expression that evaluates to x deterministically. A non pure expression that mutates a value is M[y] -> x, where M is the 'type', y is the mutated value, and x is the return value.

Rules

An expression made up of pure expressions is pure

// direct definition
def printPerson(person: { name: String }): Unit = {
println (person.name)
}
printPerson({ name: 'foo' }) // prints 'foo'
// with a structural alias
type Person = {
name: String
var library = [ { title: 'SICP', isbn: '0262010771', ed: 1 },
{ title: 'SICP', isbn: '0262510871', ed: 2 },
{ title: 'Joy of Clojure', isnb: '1935182641', ed: 1 }
];
var eventStream = new MyEventStream();
var fetchDataFromServer = function(id){ return /* some promise thing */ };
var getExtraDataForStream = function(data){ return fetchDataFromServer(data.id) };
var enhancedStream = eventStream.map(getExtraDataForStream);
enhanceStream.on('data', console.log); // augmented data printed.
// is maybe a functor if it doesn't try-catch?
// Functor law (in haskell):
fmap id = id
fmap (p . q) = (fmap p) . (fmap q)
// in js:
func.map(_.identity) === _.identity(func)
func.map(_.compose(a, b)) === func.map(b).map(a)
var Sandbox = function(val, err){
this.val = val;
this.err = err;
}
Sandbox.prototype.map = function(fn){
if ( this.err ) return this;
try {
return new Sandbox(fn(this.val));
var opLift = require('op-lift')
var opAll = function(operator){
var args = Array.prototype.slice.call(arguments)
var opFn = opLift(operator)
for ( var i = 0, len = args.length; i < len - 1; i += 1)
if ( opFn(args[i], args[i + 1]) ) return false
return true
}
var isInOrder = function(){
var args = Array.prototype.slice.call(arguments)
for ( var i = 0, len = args.length; i < len - 1; i += 1) if ( args[i] > args[i + 1] ) return false
return true
}
var identity = function(a){ return a }
var f = identity
function Parent() {
this.testMethod();
}
function Child() {
Parent.call(this);
}
Child.prototype.testMethod = function(){
console.log('yuuuup')