Skip to content

Instantly share code, notes, and snippets.

@sundarj
Last active November 4, 2017 02:23
Show Gist options
  • Save sundarj/1939f3de25640d5db9f506cfa900e2a1 to your computer and use it in GitHub Desktop.
Save sundarj/1939f3de25640d5db9f506cfa900e2a1 to your computer and use it in GitHub Desktop.
some clojure.core-ish functions implemented in javascript, with profuse examples
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