Skip to content

Instantly share code, notes, and snippets.

@CrossEye
Last active April 30, 2024 16:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save CrossEye/f28150a5f2f82bcc93106e262c0d0dcd to your computer and use it in GitHub Desktop.
Save CrossEye/f28150a5f2f82bcc93106e262c0d0dcd to your computer and use it in GitHub Desktop.
Simple Loop-Recur implementation
const Loop = (fn, ... init) => {
let r = fn (... init)
while (r instanceof Recur) r = fn (... r)
return r
}
const Recur = ( ...v) => Object .create (
Recur .prototype,
{[Symbol .iterator]: {value: _ => v .values ()}}
)
const count = (n) =>
Loop ((i, n) => i < n ? Recur (i + 1, n) : i, 0, n)
console .log (count (1e6)) //=> 1000000, no recursion depth limits
const fib = (n = 0) =>
Loop ((a, b, n) => n < 1 ? a : Recur (b, a + b, n - 1), 1, 1, n)
console .log (fib (15)) //=> 987
const nFibs = (n) =>
Loop ((a, b, n, r) => n < 1 ? r : Recur (b, a + b, n - 1, r .concat (a)), 1, 1, n, [])
console .log (nFibs (10)) //=> [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
// As in a mergesort
const merge = (xs, ys) => Loop (
(as, bs, i, j, rs) => i < as .length
? j < bs .length
? as [i] < bs [j]
? Recur (as, bs, i + 1, j, rs .concat (as [i]))
: Recur (as, bs, i, j + 1, rs .concat (bs [j]))
: rs .concat (as)
: rs .concat (bs),
xs, ys, 0, 0, []
)
console .log (merge ([1, 4, 9, 16, 25], [2, 3, 5, 7, 11, 13, 17, 23]))
//=> [1,2,3,4,5,7,9,11,13,16,17,23,25]
console .log (merge ([2, 3, 5, 7, 11, 13, 17, 23], [1, 4, 9, 16, 25]))
//=> [1,2,3,4,5,7,9,11,13,16,17,23,25]
console .log (merge ([], []))
//=> []
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment