Last active
October 2, 2016 22:37
-
-
Save therealklanni/ae84f6a94176f02b356f to your computer and use it in GitHub Desktop.
Memoized Y-Combinator in ES6
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
| let Ym = (f, s = JSON.stringify) => (g => g(g))(x => f((...v) => (k => k in x ? x[k] : x[k] = x(x)(...v))(s(v)))) | |
| let fib = Ym(f => n => n <= 1 ? n : f(n - 1) + f(n - 2)) | |
| console.log('fib(1000)', fib(1000)) // => 4.346655768693743e+208 |
Author
Yeah, that's what I had found as well. I like putting JSON.stringify in as a default param, so we can use the abbreviated arrow function syntax. Thanks for your feedback!
Author
Updated the gist. I also removed the cache param. The cache will be stored in the anonymous function x instead.
Very clever, using the recursion function as the cache.
I'm using key in cache (now k in x) so you can store false-y values in your cache without having to calculate them over and over.
It's also possible to get rid of some extraneous parentheses, leading to:
let Ym = (f, s = JSON.stringify) => (g => g(g))(x => f((...v) => (k => k in x ? x[k] : x[k] = x(x)(...v))(s(v))));
Author
Oh, I see. I wasn't sure why you used in instead of just trying to read the cached value. Good call, I'll update the code. By the way, post your Twitter handle, so I can credit you for your contribution :)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I did a quick search on that earlier and I didn't find anything then. Apparently there's a known issue with
JSON.stringify()in that it doesn't guarantee anything about the order of object properties, so{ a: 1, b: 2 }and{ b: 2, a: 1 }stringify differently. Not a big deal for memoization, just inefficient when it happens. Also note that JSON doesn't support cycles, and I suspect anything that does would be a bit slower. If your function only takes one argument and it's guaranteed to be a number or string you can simplify it tox => xorx => "" + x, which would lead to something like:Bonus: "Look ma, no
let!"