Skip to content

Instantly share code, notes, and snippets.

@KMurphs
Created December 11, 2020 16:26
Show Gist options
  • Save KMurphs/7ef1817e532c5484c2d13dfe63ebab1b to your computer and use it in GitHub Desktop.
Save KMurphs/7ef1817e532c5484c2d13dfe63ebab1b to your computer and use it in GitHub Desktop.
Interesting Implementation of Stack and Queue using Functional Programming in Javascript
// https://stackoverflow.com/a/42242601/9034699
// From original answer: Stack
const stackPush = (x, xs) => f => f(x,xs)
const stackPop = s => s((x,xs) => [x,xs])
// From a looooong effort on my side.
// It is not efficient, or usable. But the goal was a proof of concept: To figure out a way to do this using similar method.
const countQ = Q => Q((prevEl, prevQ) => 1 + (prevQ ? countQ(prevQ) : 0))
const enQ = (el, Q) => f => f(el, Q, Q ? countQ(Q): 0)
const first = (Q, count) => Q((lastEl, lastQ) => (count === 0 ? lastEl : first(lastQ, count - 1)))
const deQ = Q => Q ? Q((lastEl, lastQ, lastCount) => [first(Q, lastCount), lastCount ? f => f(lastEl, lastQ, lastCount - 1) : null]) : null
@KMurphs
Copy link
Author

KMurphs commented Dec 11, 2020

My understanding:
stackPush and enQ actually define the nature of a stack and a queue respectively.
They are both functions that have closure over the arguments that were passed to stackPush and enQ

In other words,

const s = stackPush(1, emptyStack)

This means that s (the stack) is a function that remembers (aka has closure over) the arguments provided during its creation.

Now:

const s2 = stackPush(2, s)`
[el, s3] = stackPop(s2)

The s3 that is returned is exactly the same object as s and still remembers data from its original closure.

Therefore:

[el2, s4] = stackPop(s3)

will produce el2 equal to 1, and s4 equal to emptyStack

In summary, this is just a very clever use of closures to implement a stack. Maybe not practical but certainly interesting...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment