Skip to content

Instantly share code, notes, and snippets.

@hax
Last active April 26, 2024 04:51
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hax/285172c95550d3a46c4c997a13ce3614 to your computer and use it in GitHub Desktop.
Save hax/285172c95550d3a46c4c997a13ce3614 to your computer and use it in GitHub Desktop.
An idea from combination of `[...rest, last]` syntax, reverse iterator and `function.sent`

An idea from combination of [...rest, last] syntax, reverse iterator and function.sent

Semantic

[first, second, ...rest, last2, last] = o

basically become:

const iter = o[Symbol.Iterator]()

// for backward-compatibility, [x, ...rest] don't test it
if (!iter.canSendMessageToNext) throw new TypeError()

first = iter.next('forward').value 
second = iter.next('forward').value 
last = iter.next('backward').value
last2 = iter.next('backward').value

let result = iter.next('rest')
if (result.done) {
  // allow create `rest` array directly, better perf,
  // theoretically could be any iterable,
  // but break current codes which expect `rest` always array
  // maybe new syntax like `[a, ...rest...] = o` :-)
  rest = result.value
} else {
  rest = []
  for (;;) {
    let result = iter.next('forward')
    if (result.done) break
    rest.push(result.value)
  }
}

Generator

Array.prototype.values = function *values(array) {
  // if contains function.sent, the generator object would have `canSendMessageToNext`
  for (let start = 0, end = array.length; start < end;) {  
    const op = function.sent
    if (op === 'rest') return array.slice(start, end)
    if (op === 'backward') yield array[--end]
    else yield array[start++]
  }
}

for reverse of

for reverse (x of it) {...} just call next("backward") instead of next()

ReverseIterator

Iterator.prototype.reverse = function ReverseIterator(this iter) {
  if (!iter.canSendMessageToNext) throw new TypeError() // for backward-compatibility
  return {
    canSendMessageToNext: true,
    next(op) {
      if (op === 'backward') op = 'forward'
      else if (op === 'forward') op = 'backward'
      return iter.next(op)
    },
  }
}
@hax
Copy link
Author

hax commented May 28, 2020

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