Skip to content

Instantly share code, notes, and snippets.

@fogus
Last active December 18, 2015 04:08
Show Gist options
  • Save fogus/5722992 to your computer and use it in GitHub Desktop.
Save fogus/5722992 to your computer and use it in GitHub Desktop.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>a sketch</title>
<script type="text/javascript" src="undermine.js"></script>
</head>
<body>
<center>
open the js console and play<br>
<a href="http://www.functionaljavascript.com">more about these ideas</a>
</center>
</body>
</html>
var exists = function(x) { return x != null; };
var truthy = function(x) { return (x !== false) && exists(x); };
var _filter = function(fun) {
return function(coll) {
var results = [];
if (coll == null) return results;
coll.forEach(function(value, index, list) {
if (truthy(fun.call(null, value))) results.push(value);
});
return results;
};
};
function filter(fun) {
var coll = arguments[1];
if (exists(coll)) return _filter(fun)(coll);
return _filter(fun);
}
var _map = function(fun) {
return function(coll) {
var results = [];
if (coll == null) return results;
coll.forEach(function(value, index, list) {
results.push(fun.call(null, value));
});
return results;
};
};
function map(fun) {
var coll = arguments[1];
if (exists(coll)) return _map(fun)(coll);
return _map(fun);
}
function double(n) { return 2*n; }
/*
map(double, [1,2,3])
//=> [1, 4, 9]
*/
var doubleAll = map(double);
/*
doubleAll([1,2,3]);
//=> [1, 4, 9]
*/
function greaterThan(l, r) {
return l > r;
}
function schonfinkel(fun) {
return function(first) {
return function(last) {
return fun(first, last);
};
};
};
function flip(fun) {
return function() {
return fun.call(null, arguments[1], arguments[0]);
};
}
var gt = schonfinkel(flip(greaterThan));
/*
gt(5)
//=> function(last) { ... }
gt(5)(10000000);
//=> true
gt(5)(1);
//=> false
*/
var _reduce = function(fun, seed, coll) {
var acc = seed;
coll.forEach(function(value) {
acc = fun.call(null, acc, value);
});
return acc;
};
function reduce(fun) {
var count = arguments.length;
var seed = arguments[1];
var coll = arguments[2];
var result;
switch(count) {
case 1:
result = schonfinkel(_reduce.bind(null, fun));
break;
case 2:
result = _reduce.bind(null, fun, seed);
break;
case 3:
result = _reduce(fun, seed, coll);
break;
}
return result;
}
function sum(x,y) { return x + y; }
/*
reduce(sum, 0, [1,2,3,4,5]);
//=> 15
*/
var summate = reduce(sum, 0);
/*
summate([1,2,3,4,5]);
//=> 15
*/
var pipeline = function(/*, funs */){
var funs = Array.prototype.slice.call(arguments);
return function(seed) {
return reduce(function(l,r) { return r(l); },
seed,
funs);
};
};
/*
pipeline(double)(5);
//=> 10
*/
var tasks = pipeline(
map(double)
, filter(gt(5))
);
/*
tasks([1,2,3,4,5]);
//=> [6,8,10]
*/
var moreTasks = pipeline(
tasks
, reduce(function(x,y) { return x*y }, 1)
);
/*
moreTasks([1,2,3,4,5]);
//=> 480
*/
// more ideas like this at http://www.functionaljavascript.com/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment