03:30
<ljharb>
oh ok great, not sure how i missed that too
05:23
<ljharb>
altho its property descriptor isn't properly specified; it just says in a note that it's writable. i assume it's configurable and nonenumerable?
06:06
<bakkot>
ljharb: yes; see the second-last paragraph of https://tc39.es/ecma262/multipage/ecmascript-standard-built-in-objects.html#sec-ecmascript-standard-built-in-objects
06:13
<ljharb>
right, but that's a non-normative note on top of the normative default. when the descriptor isn't default, it's supposed to be specified in its entirety, like https://tc39.es/ecma262/#sec-%throwtypeerror% etc
06:16
<ljharb>
so in this case, taken.next() will throw because next returns a non-Object, and the wrapper throws on that; if i modify next to return an empty object
06:16
<ljharb>
but also, the iterator helper wrapper, nor Iterator.prototype, seems to specify a throw method, so taken.throw doesn't exist
06:16
<ljharb>
should there be a default throw method, or getter, that refers to the wrapped iterator's throw method when present?
07:24
<bakkot>

when the descriptor isn't default, it's supposed to be specified in its entirety

right, but it is default, so it's not specified at all

07:24
<bakkot>
"Every other data property described in clauses 19 through 28 and in Annex B.2 has the attributes { [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true } unless otherwise specified."
07:26
<bakkot>
so in this case, taken.next() will throw because next returns a non-Object, and the wrapper throws on that; if i modify next to return an empty object
ah yeah sorry, next should return { done: false, value: null } or something
07:26
<bakkot>
so should return for that matter
07:26
<bakkot>
*

simple test for this example:

let manualIter = {
  next(){ console.log('next'); return { done: false, value: null } },
  throw(){ console.log('not hit'); },
  return() { console.log('closing'); return {}; },
};

let taken = Iterator.from(manualIter).take(10);
taken.next(); // prints 'next'
try { taken.throw('err'); } catch (e) { console.log('caught', e); } // prints 'closing' and then 'caught err'
07:26
<bakkot>
updated my snippet
07:27
<bakkot>
but also, the iterator helper wrapper, nor Iterator.prototype, seems to specify a throw method, so taken.throw doesn't exist
hm, ok, I guess it's just .return then
07:28
<bakkot>
which does not cause an exception, but does still cause an abrupt completion
07:29
<bakkot>
*

simple test for this example:

let manualIter = {
  next(){ console.log('next'); return { done: false, value: null } },
  throw(){ console.log('not hit'); },
  return() { console.log('closing'); return {}; },
};

let taken = Iterator.from(manualIter).take(10);
taken.next(); // prints 'next'
taken.return(); // prints 'closing'
taken.next(); // returns { done: true }
07:29
<bakkot>
that makes it a little harder for a test to clearly demonstrate what's going on, but updated my snippet anyway
07:29
<bakkot>
writing tests without code to run them against is hard
23:18
<ljharb>
any reason not to name the functions some/every/filter/find take to "predicate"? "filterer" seems unnecessarily specific, and "fn" seems unnecessarily vague