code: function primes(limit) {
      if (limit != null) {
          // https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes
          return defer(function* () {
              let set = Array.from(range(3, (limit / 2) - 1, 2));
              let curr = 3;
              const sqrtLimit = Math.sqrt(limit);
              yield 2;
              let lastIndex = 0;
              while (curr <= sqrtLimit) {
                  yield curr;
                  set = set.splice(0, lastIndex).concat(set.splice(lastIndex + 1).filter(s => s % curr !== 0));
                  lastIndex = set.findIndex(s => s > curr);
                  if (lastIndex == null) {
                      return;
                  }
                  curr = set[lastIndex];
              }
              yield curr;
              yield* set.slice(lastIndex + 1);
          });
      }
      return defer(function* () {
          const previousPrimes = [2, 3];
          yield 2;
          yield 3;
          for (let curr = 5;; curr += 2) {
              let allowed = true;
              const sqrt = Math.sqrt(curr);
              for (const prime of previousPrimes) {
                  if (prime > sqrt) {
                      break;
                  }
                  else if (curr % prime === 0) {
                      allowed = false;
                      break;
                  }
              }
              if (allowed) {
                  previousPrimes.push(curr);
                  yield curr;
              }
          }
      });
  }
docs: Generate a sequence of primes. Limit that sequence to primes below the specified amount if provided, otherwise generate an infinite sequence of primes
  (Will become progressively more performance intensive for each prime)