Last active
November 4, 2017 02:23
-
-
Save sundarj/1939f3de25640d5db9f506cfa900e2a1 to your computer and use it in GitHub Desktop.
some clojure.core-ish functions implemented in javascript, with profuse examples
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
console.clear() | |
function identity (x) { | |
return x | |
} | |
function add (x, y) { | |
return parseFloat(x) + parseFloat(y) | |
} | |
function inc (x) { | |
return add(x, 1) | |
} | |
function dec (x) { | |
return add(x, -1) | |
} | |
function merge (x, y) { | |
return Object.assign({}, x, y) | |
} | |
function type (x) { | |
return Object.prototype.toString.call(x) | |
} | |
function isPlainObject (x) { | |
return type(x) === "[object Object]" | |
} | |
function isUndefined (x) { | |
return type(x) === "[object Undefined]" | |
} | |
function isArray (x) { | |
return type(x) === "[object Array]" | |
} | |
function isString (x) { | |
return type(x) === "[object String]" | |
} | |
function isSet (x) { | |
return type(x) === "[object Set]" | |
} | |
function seq (coll) { | |
let sequence | |
if (isPlainObject(coll)) { | |
sequence = Object.entries(coll) | |
} | |
else { | |
sequence = Array.from(coll) | |
} | |
return sequence | |
} | |
console.groupCollapsed("seq") | |
console.log(seq({a: 2, b: 6})) | |
console.log(seq(new Map([[1, 2], [3, 4]]))) | |
console.groupEnd() | |
function first (coll) { | |
return seq(coll)[0] | |
} | |
function second (coll) { | |
return seq(coll)[1] | |
} | |
const key = first | |
const val = second | |
function comp (f, g) { | |
return function (...args) { | |
return f(g(...args)) // this is why it's right-to-left | |
} | |
} | |
console.groupCollapsed("comp") | |
console.log(comp(inc, inc)(5)) | |
console.log(comp(dec, dec)(5)) | |
console.groupEnd() | |
function juxt (f, g) { | |
return function (...args) { | |
return [f(...args), g(...args)] | |
} | |
} | |
console.groupCollapsed("juxt") | |
console.log(juxt(inc, dec)(7)) | |
console.log(juxt(key, comp(inc, val))(["a", 1])) | |
console.groupEnd() | |
function conj (coll, x) { | |
let res | |
if (isPlainObject(coll)) { | |
const [key, val] = x | |
res = merge(coll, {[key]: val}) | |
} | |
else if (isArray(coll) || isString(coll)) { | |
res = coll.concat(x) | |
} | |
else if (isSet(coll)) { | |
res = coll.add(x) | |
} | |
return res | |
} | |
console.groupCollapsed("conj") | |
console.log(conj("hell", "o")) | |
console.log(conj({a: 2}, ["b", 6])) | |
console.groupEnd() | |
function reduce (f, init, coll) { | |
return seq(coll).reduce(f, init) | |
} | |
console.groupCollapsed("reduce") | |
console.log(reduce((acc, x) => acc + x.length, 0, "sup nigga")) | |
console.log(reduce((acc, x) => acc + val(x), 0, {a: 2, b: 6})) | |
console.groupEnd() | |
function into (to, transducer, from) { | |
if (isUndefined(from)) { | |
from = transducer | |
transducer = identity | |
} | |
return reduce(transducer(conj), to, from) | |
} | |
console.groupCollapsed("into") | |
console.log(into({}, [["a", 2], ["b", 6]])) | |
console.log(into([], {a: 2, b: 6})) | |
console.log(into(new Set, [1, 1, 2, 3])) | |
console.groupEnd() | |
function map (f) { | |
return function transducer (reducer) { | |
return function transformed_reducer (acc, x) { | |
return reducer(acc, f(x)) | |
} | |
} | |
} | |
console.groupCollapsed("map transducer") | |
// 0, [], and (new Set) are `acc`, 1 is `x` | |
console.log(map(inc)(add)(0, 1)) | |
console.log(map(inc)(conj)([], 1)) | |
console.log(map(dec)(conj)(new Set, 1)) | |
console.groupEnd() | |
console.groupCollapsed("into with transducer") | |
console.log(into(new Set, map(inc), [1, 1, 3, 5])) | |
console.log(into({}, map(juxt(comp(inc, val), key)), {a: 2, b: 6})) | |
console.groupEnd() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment