Skip to content

Instantly share code, notes, and snippets.

@th507
Last active May 21, 2018 09:28
Show Gist options
  • Save th507/f5e4ce3e12771d214b8a1245910fa8b0 to your computer and use it in GitHub Desktop.
Save th507/f5e4ce3e12771d214b8a1245910fa8b0 to your computer and use it in GitHub Desktop.
let yCombinator = f => (g => (...p) => f(g(g))(...p))(g => (...p) => f(g(g))(...p))
var factory = f => (...a) => a.length - a[0].length > 1 ? f.call.call(...a) : f.bind(null, ...a)
//
// we could add some fancy code to eliminate fn.call & fn.bind
//
// var topsy = (f => f.bind(f))(Function.call)
// var turvy = (f => f.bind(f))(Function.bind)
// var factory = f => (...a) => (a.length - a[0].length > 1 ? topsy : turvy(f, null))(...a)
//
// in fact, we could eliminate .call in the expression altogether
// var factory = ((f => g => (...a) => (a.length - a[0].length > 1 ? f : f.bind(f, f.bind, g, g.bind))(...a)()())((f => f(f.bind))(f => f.bind(f)))
let bind = yCombinator(factory)
// demo case 1: currying
let log = (a, b) => console.log(a, b)
bind(log)(null, 2, 5)
bind(log)(null)(2, 5)
bind(log)(null, 2)(5)
bind(log)(null)(2)(5)
bind(log, null, 2, 5)
bind(log, null)(2, 5)
// demo case 2: recursion
let fib = f => n => n < 3 ? 1 : ( f(n - 1) + f(n - 2) )
console.log(
yCombinator(fib)(10)
)
console.log(
yCombinator(fib)(10)
)
// demo case3: recursion and currying
let metaFib = (f, n) => n < 3 ? 1 : ( f(n - 1) + f(n - 2) )
// bind(metaFib, null) add padding context `null` to metaFib and create a high order function like `fib`
console.log(
yCombinator(bind(metaFib, null))(10)
)
console.log(
yCombinator(bind(metaFib)(null))(10)
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment