00:08 | <rbuckton> | yeah i don't agree with the prediction Iterator and an adapter like Iterator.from feels more like TC39 blessing this as "the way", which I'm not comfortable with. |
00:13 | <rbuckton> | Augmenting IteratorPrototype and making it easier to reach for just feels like another opportunity for Array.prototype-like patching that we've been dealing with for years, especially if people start feeling like the helpers available aren't comprehensive enough. |
00:18 | <snek> | if pipeline moved forward |
00:18 | <snek> | i wouldn't be wholly against functions |
00:18 | <snek> | but without that there's no point even discussing it |
00:59 | <rbuckton> | As much as I still prefer F#-style, if pipeline could settle on a topic I'd be happy. |
01:01 | <rbuckton> | temporal achieved this by being large and complex .now() is detached into its own thing is exceedingly frustrating the times I've used it. |
01:02 | <rbuckton> | It's like 10 steps forward and 5 steps back |
01:05 | <rbuckton> | Determining whether an
But it seems like the API design is very focused on "only one way to do it", regardless of convenience. |
01:09 | <ptomato> | I don't like Temporal.Now either! but it's always been a hard requirement from the plenary AFAIU |
01:14 | <ptomato> |
isBefore / isAfter method because we had to draw the line somewhere |
01:14 | <ptomato> | you may want to subscribe to https://github.com/js-temporal/proposal-temporal-v2/issues/6 |
01:14 | <snek> | its interesting that compare is not an instance method |
01:15 | <rbuckton> | I think a more general compareTo is better. |
01:15 | <rbuckton> | its interesting that .sort() |
01:15 | <snek> | but either way i'm fine with this, people who care deeply about temporal apis are already working on this as has been linked 😄 |
01:16 | <rbuckton> | you may want to subscribe to https://github.com/js-temporal/proposal-temporal-v2/issues/6 |
01:17 | <snek> | Its good as a static method for use with |
01:17 | <snek> | but this is the sort of thing |
01:17 | <rbuckton> | Or maybe it was in matrix. I can't find the issue. |
01:17 | <snek> | i much prefer it existing at all |
01:17 | <snek> | to it going back and forth based on my opinion |
01:17 | <snek> | so 🤷 |
01:20 | <rbuckton> | I really want to introduce generic comparison (not operators) at some point, i.e.:
And allow you to pass an |
01:21 | <rbuckton> | I'd love to be able to have a Map whose keys are URL or Temporal.Instant without having to coerce to a string. |
01:21 | <Kris Kowal> | I’ve done similar work with only slightly different names. |
01:22 | <Kris Kowal> | We had a relevant conversation about deep equality at the most recent SES meeting. |
01:22 | <bakkot> | Augmenting IteratorPrototype and making it easier to reach for just feels like another opportunity for Array.prototype-like patching that we've been dealing with for years, especially if people start feeling like the helpers available aren't comprehensive enough. |
01:23 | <Kris Kowal> | SES meeting on deep equality, where we differentiate structural deep equality and deep equality protocols https://youtu.be/z_gXDSYKlWI |
01:24 | <Kris Kowal> | Equality, hash, and compare protocols are in http://www.collectionsjs.com/ |
01:25 | <Kris Kowal> | (CollectionsJS isn’t a viable project in its current form because I mispredicted some Array shims. Ooops.) |
01:26 | <rbuckton> | @esfx/equatable has definitions for equality, comparability, structural equality, and structural comparability. |
01:27 | <rbuckton> | Though my most recent npm publish (today) has a few issues I'm trying to fix. I just switched the hashCode generation to use native code on Node when possible and that's had some hiccups. |
01:28 | <Kris Kowal> | Adding protocols to the standard library probably means different Map and Set implementations or a very clever system for overloading their behavior. |
01:29 | <snek> | i really wish we had a System.hash(v) api |
01:29 | <Kris Kowal> | Collections went the cheap route of random numbers and a weak map. It predates intrinsic Map and Set, so there it does some odd stuff. But, not surfacing information divined from pointers is important. |
01:29 | <snek> | so we could write our own collections |
01:30 | <rbuckton> | Agreed. @esfx/equatable exposes a rawHash(v) API which is essentially the same. |
01:30 | <snek> | does that hash structurally or based on js identity |
01:30 | <rbuckton> | I don't use pointers, I use the same hash identity that V8 uses for objects as keys in a map. |
01:30 | <rbuckton> | JS identity. |
01:30 | <snek> | oh its a native fn? |
01:31 | <Kris Kowal> | Yeah, I suspect that’s still a side channel. |
01:31 | <snek> | feel free to delete System.hash :P |
01:31 | <rbuckton> | oh its a native fn? |
01:31 | <snek> | oh nice |
01:31 | <snek> | that's basically how v8 works anyway |
01:32 | <snek> | well not a weakmap but random numbers yes |
01:32 | <rbuckton> | At least, as soon as I finish wrangling breaking changes in my monorepo |
01:35 | <snek> | Yeah, I suspect that’s still a side channel. |
01:36 | <snek> | you can't communicate with it |
01:37 | <bakkot> | as long as it's mixed with an actually random number |
01:37 | <snek> | i think every js engine that cares about this sort of thing does that anyway |
01:37 | <snek> | due to hash collision attacks |
01:38 | <bakkot> | yeah and because getting the address of an object in memory is one gadget which is used as a step in a lot of exploits |
01:38 | <snek> | oh right yeah do not use the address lmao |
01:39 | <bakkot> | I suspect none of the major engines would do it but if were were adding something like this we'd need to have a big loud note about including a good random value as a component |
01:39 | <snek> | i hear 4 is a great random number |
01:39 | <bakkot> | and it would be another source of nondeterminism, which... we should figure out a better story about adding those in general |
01:41 | <snek> | hmmmmmmMMMMMM |
01:41 | <snek> | actually no i'm dumb |
01:41 | <snek> | i was gonna say "does the hash actually have to be a transparent value" and then i realized how useless it would be if it was opaque lul |
01:47 | <rbuckton> | It needs to be a number value (preferably uint32) to bucketize things efficiently. |
02:15 | <snek> | for the constraints of js i think it must be in u32 range otherwise you can't modulo it |
02:15 | <snek> | or bitwise it |
02:19 | <rbuckton> | and u64 is outside the range of allowable array indices |
02:32 | <rbuckton> | ok, I think I fixed my breaking changes.
There's also a |
02:33 | <Kris Kowal> | The CollectionsJS deep equality protocol carried an ibid map to break cycles and allowed an override for the contentEquals of the children. |
02:33 | <rbuckton> | I use the equality and comparison interfaces pretty heavily in the @esfx/collections-* packages as well as the @esfx/iter-* and @esfx/async-iter-* packages. |
02:34 | <rbuckton> | Mine doesn't do ad-hoc structural equality, but rather expects something that would be structurally equal to something else to explicitly implement that structural equality. |
02:35 | <rbuckton> | I haven't had much cause to use that part though, about 99% of my use cases have been shallow equality via custom Equaler and Comparer objects. |
02:38 | <rbuckton> | If I were to propose to TC39, I'd primarily focus on Equaler ({ equals(a, b), hash(x) } ) and Comparer ({ compare(a, b) } ) support in collection classes, default implementations of each that would align with existing behavior in Map and Set for keys, and a hash function reachable from somewhere (even if it's just Equaler.defaultEqualer.hash ). |
02:40 | <rbuckton> | After that, maybe Symbol.equals , Symbol.hash , and Symbol.compareTo to hook equality and comparability on an instance. But at no point would any of that affect relational operators like == , > , etc. (overloading would be far out of scope). |
03:44 | <ljharb> | Doesn’t it return an iterator instance that has the slots of a generator? |
03:58 | <bakkot> | not exactly? it returns an iterator instance that has the slots of an iterator helper |
03:58 | <bakkot> | which is not the same thing as a generator |
04:00 | <bakkot> | like you can't (function*(){})().next.call(that helper thing) ; that will not work |
04:01 | <bakkot> | I guess to be precise, the way it's written down it does have the same slots as a generator, but that's not actually observable by anything, just an editorial convenience |
04:05 | <bakkot> | anyway it is probably easier to talk about this in terms of observable behavior. there is very little observable difference between Iterator.from(x) and Iterator.from(x).map(a => a) . if there is a specific difference in observable behavior between the two you are worried about, post a code snippet and I can tell you what it does? |