01:21 | <globbot> | channel logging requested by akirose: https://freenode.logbot.info/tc39-delegates |
01:37 | <michaelficarra> | globbot is back? |
01:37 | <michaelficarra> | PogChamp it's working! https://freenode.logbot.info/tc39-delegates |
01:37 | <rkirsling> | haxjs: prior art is important like that 😅 |
01:37 | <devsnek> | test |
01:37 | <devsnek> | its fast |
01:38 | <akirose> | 🙋🏻♀️ hi friends okay i sketched out the schedule in pencil https://hackmd.io/@aki/rJFTzg8MI |
01:39 | <akirose> | haxjs: i tried to put you in your morning but should move you to end of day wednesday? |
01:39 | <haxjs> | rkirsling yeah,many people tell, all good part in js is copied from other langs, and all things js itself invented are bad part. 🤣 |
01:39 | <ljharb> | psh |
01:40 | <Bakkot> | most of the bad parts are also copied from other languages, to be fair |
01:40 | <Bakkot> | *cough Date cough* |
01:40 | <decompiled> | akirose: yayyyy for draft schedule :) |
01:40 | <devsnek> | *cough RegExp cough* |
01:40 | <michaelficarra> | most of the worst parts come from Java imo |
01:40 | <ljharb> | switch cough null cough Number cough |
01:40 | <devsnek> | *cough statements* |
01:40 | <haxjs> | yeah! like "var", it seems many old scripts all use function scope vars, no block scope var. |
01:41 | <ljharb> | old scripts only had var as an option |
01:41 | <haxjs> | I mean other script languages. |
01:42 | <ljharb> | languages where block scope was an option? |
01:42 | <haxjs> | I mean many old script languages also only have function scope vars, no block scope. So js just copied them :-P |
01:43 | <ljharb> | ah |
01:44 | <michaelficarra> | wow this is a great first conversation for our logs; delegates shitting all over the language lol |
01:44 | <haxjs> | I feel java didn't bring many bad part, the most bad from java is Date! But java depracated it in 1.1, while JS used it 20 years... So it seems we can't blame java... |
01:48 | <haxjs> | akirose pls put me to the last day if possible, it could help me to adapt to jet lag... |
01:48 | <akirose> | done |
01:48 | <haxjs> | akirose Thank you! |
01:49 | <michaelficarra> | that trichotomy is not true for NaN |
01:50 | <devsnek> | the precision is defined by the number format |
01:50 | <michaelficarra> | haxjs: I thought you weren't traveling |
01:51 | <haxjs> | michaelficarra no I weren't traveling but i still need to adjust my timezone ... starting from my 4AM is really pain... my brain acutally stop work now |
01:53 | <haxjs> | michaelficarra what trichotomy not work for NaN? I missed it |
01:54 | <michaelficarra> | a < b or a > b or a === b |
01:55 | <devsnek> | nan comparisons are always falsy |
01:56 | <haxjs> | oh :-P NaN is notanumber but typeof NaN === 'number', I won't be surprised on everything about NaN :-) |
01:56 | <bterlson> | Is it just me or is littledan using U+006F LATIN SMALL LETTER O instead of U+0030 DIGIT ZERO? |
01:56 | <akirose> | I WAS WONDERING THAT TOO |
01:56 | <devsnek> | bterlson: google "lowercase numbers" |
01:56 | <shu> | it's that font |
01:56 | <devsnek> | its the font |
01:56 | <robpalme> | name that font |
01:56 | <shu> | it has oldstyle figures by default, which is only a good idea for actual prose usually |
01:56 | <devsnek> | it's inconsola right |
01:57 | <akirose> | who's gonna tell him we can't distinguish between white & grey bgs |
01:57 | <haxjs> | it's latin small lettter? maybe 〇 ? |
01:57 | <devsnek> | i always use that font in my proposal slides |
01:57 | <jackworks> | we're not going to have a global settings on bigdecimals right? global settings are bad |
01:57 | <devsnek> | right |
01:58 | <devsnek> | robpalme: playfair display is the name of the font |
01:58 | <michaelficarra> | jackworks: what does global setting mean? |
01:59 | <devsnek> | like python's decimal.getcontext() |
01:59 | <robpalme> | jackworks: the laughter in the room when that came up is a sign that global settings would be highly unlikely to be introduced |
02:00 | <haxjs> | toJSON is really a problem |
02:00 | <jackworks> | robpalme: LOL I missed that part |
02:00 | <bterlson> | Shouldn't thinks like IEEE-754-2008 use upper case numerals or tabular figures? I'd like to see some iteration on the font this deck uses and maybe we can circle back next meeting |
02:01 | <robpalme> | fonts are normally a stage 2 concern |
02:02 | <haxjs> | wrote a idea about toJSON issue: https://gist.github.com/hax/5691ca8acdf9179e63043857cdc3616b |
02:05 | <jridgewell> | @haxjs: @michaelficarra had a proposal for serializing bigints |
02:05 | <michaelficarra> | did I? I don't remember |
02:05 | <jridgewell> | I thought? |
02:05 | <jridgewell> | Maybe not. |
02:05 | <ljharb> | that's gibson042 |
02:05 | <bterlson> | You did, it was amazing and solved all problems |
02:06 | <apaprocki> | first proposal to reach stage 5 |
02:06 | <bterlson> | unfortunately hte work was lost in the fire at TC39 HQ |
02:07 | <michaelficarra> | aww that's too bad |
02:07 | <devsnek> | i wanted the structured clone algo to move to tc39 |
02:08 | <michaelficarra> | I can't tell if I'm in #tdz or not... |
02:08 | <jridgewell> | I'm like 90% sure it was michaelficarra |
02:08 | <jridgewell> | The BigInt to variable length array proposal |
02:08 | <ljharb> | jridgewell: https://github.com/tc39/proposal-json-parse-with-source |
02:08 | <jridgewell> | That's the opposite |
02:09 | <michaelficarra> | I think it was the 10% |
02:09 | <devsnek> | v8 and gmp both use the same format for bigint serialization |
02:09 | <devsnek> | i have a gist somewhere to convert between them |
02:09 | <ljharb> | ah |
02:09 | <gibson042> | JSON-compatible BigInt serialization is easy and already available with toString; my proposal is to make deserialization possible |
02:09 | <jridgewell> | https://es.discourse.group/t/bigint-enhancements/100/2 |
02:10 | <Bakkot> | gibson042 wait, how? you can't output arbitrary-precision decimals with `JSON.stringify` |
02:10 | <devsnek> | https://gist.github.com/devsnek/49b6c63d8a9f9bf3c299a34bb51ed7eb |
02:10 | <gibson042> | yeah, that's the caveat |
02:11 | <jridgewell> | devsnek, what's that in a language I can understand? |
02:11 | <devsnek> | converts between gmplib (gnu bigint library) and v8's bigints |
02:11 | <devsnek> | using a standard format of <length, <array of u64>> |
02:12 | <devsnek> | in js the length is part of the array |
02:18 | <apaprocki> | re: adding the parameter: https://github.com/bloomberg/bde/blob/master/groups/bdl/bdldfp/bdldfp_decimalconvertutil.h#L175 |
02:18 | <apaprocki> | notes from our api for converting from binary->decimal |
02:19 | <jackworks> | devsnek: +1 I also want to have structured clone algo move into JS and I have a heavily daily usage of custom serializable classes so I also want to have a "developer defined" structured clonable feature |
02:21 | <littledan> | jackworks: Have you seen the previous efforts towards this move? |
02:22 | <rickbutton> | for reference, schemes and lisps have literal syntax for decimals |
02:22 | <rbuckton> | C# has `decimal` which is *essentially* a primitive. |
02:22 | <haxjs> | littledan it seems there is an old structured clone proposal, but inactive? |
02:22 | <rickbutton> | (and rationals/complex/etc) |
02:23 | <rbuckton> | C# also has `0.999m` |
02:24 | <bterlson> | Anyone remember my preso on decimals from like 2015? |
02:24 | <bterlson> | those were the days |
02:24 | <jackworks> | littledan: yes there was a proposal but inactive now and it just a clone of structured clone proposal. I'd like to see an enhanced one |
02:24 | <bterlson> | I recall saying something like "we've almost solved the value types framework so this work should advance quickly" |
02:24 | <devsnek> | lol |
02:25 | <apaprocki> | yes, that was always brendan's feedback :) |
02:25 | <devsnek> | i have mixed feelings about getting involved after the spicy days |
02:26 | <rbuckton> | The question is, will value types have a unique `typeof` (i.e., one for *all* value types not per-value type) |
02:26 | <devsnek> | `typeof x === 'valuetype'` |
02:26 | <devsnek> | ez |
02:26 | <michaelficarra> | devsnek: I like that I got a taste of it and I also *really* like that those days are no more |
02:26 | <haxjs> | seems anything except "function" "object" are all value types. |
02:26 | <haxjs> | though there is a hole of null. |
02:27 | <rbuckton> | I'm tinkering with a strawman for value types via the `struct` keyword (similar to how `struct` represents a "value type" in C#), which would have a `typeof` of `"struct"`. |
02:27 | <devsnek> | i think of everything in js as a heap allocation |
02:27 | <michaelficarra> | haxjs: typeof null is "object" |
02:29 | <ljharb> | primitives are arguably "value types" |
02:29 | <haxjs> | devsnek> immutable object behave same as value type so yes they can all heap allocation |
02:30 | <ljharb> | anything where `Object(x) !== x` |
02:30 | <haxjs> | ljharb yeah, this is only robust test I ever know. |
02:31 | <littledan> | jackworks: Did you follow how that worked out on the HTML side, how there was an effort to work together on this in the past? |
02:31 | <ghermeto> | rbuckton do you have any resource you can share regarding "struct"? |
02:32 | <haxjs> | ljharb some very old engine would return some alien values for `typeof` for example "unknown" :) |
02:32 | <ljharb> | indeed |
02:33 | <rbuckton> | ghermeto: So far I just have a gist where I've been tinkering with syntax. |
02:33 | <devsnek> | now when engine internal values leak out of v8 they have typeof be"undefined" |
02:33 | <devsnek> | which just makes everything more confusing |
02:33 | <rickbutton> | can people remote hear Mark? |
02:33 | <devsnek> | yes |
02:33 | <haxjs> | yes |
02:38 | <MylesBorins> | hey all. There is a large twitter dm group to coordinate activities for folks in town (both for conference and tc39) |
02:39 | <MylesBorins> | I added folks whose handles I know, but if you were not included and want to be please lmk |
02:39 | <rickbutton> | MylesBorins: my twitter is rickbutton , plz add me |
02:39 | <littledan> | BTW it was a 0 in a weird font |
02:41 | <MylesBorins> | oh no "rickbutton" cannot be messaged |
02:41 | <MylesBorins> | I added you, maybe if you add me it will work |
02:41 | <ljharb> | open up those dms |
02:41 | <MylesBorins> | (unless you have groupdms turned off) |
02:41 | <rickbutton> | i wasn't following you try again |
02:41 | <rickbutton> | shame on me |
02:42 | <jackworks> | I'm @JackWorks_fvs on twitter |
02:42 | <ljharb> | jackworks: are you here in person? |
02:42 | <MylesBorins> | rickbutton: I think you have dms disabled |
02:43 | <rickbutton> | MylesBorins moving to private IRC to note pollute channel |
02:47 | <devsnek> | should coordinate with cf folks |
02:47 | <devsnek> | they're all about this because of cf workers |
02:48 | <michaelficarra> | devsnek: mark's not on IRC |
02:48 | <devsnek> | oh |
02:48 | <michaelficarra> | you'll have to send a pigeon or something |
03:02 | <littledan> | we could also consider this an overflow item at the end of the meeting, if the timebox has run out |
03:02 | <littledan> | (although I would like to discuss this further) |
03:03 | <michaelficarra> | it's a 30m timebox, so it seems appropriate to go to overflow |
03:03 | <ljharb> | has it gone 30m yet tho? |
03:04 | <akirose> | yes |
03:04 | <ljharb> | k |
03:04 | <devsnek> | ended with 1% battery |
03:04 | <devsnek> | zoom uses all the battery |
03:35 | <zuojian> | Hello, where can I find the meeting's note? |
03:38 | <rkirsling> | zuojian: you can find it via the "meeting info" link in the channel topic |
03:39 | <zuojian> | Thanks. |
03:41 | <sffc> | Any plans for dinner tonight? |
04:11 | <sffc> | I think the plan is 7:30pm at Gyu-Kaku |
04:19 | <rkirsling> | oh man, gyu-kaku is is the best |
04:19 | <rkirsling> | s/is is/is/ |
05:12 | <sffc> | Text Myles if you want in; I think we have a reservation and seats are limited |
20:11 | <littledan> | can I just write my comments in the notes rather than taking up more time? |
20:11 | <littledan> | or, I could post it in an issue on the repo? |
20:11 | <littledan> | akirose: ystartsev ^ |
20:11 | <robpalme> | if you're happy to and it's not a stage 1 blocker, pleas eod |
20:11 | <littledan> | OK |
20:12 | <jridgewell> | Filing an issue would be good |
20:20 | <devsnek> | realms have a map with reified intrinsic names? |
20:21 | <littledan> | does anyone have use cases for differentiating the this value and global object in Realms? I coudln't find anything in the repo, and filed this issue about it https://github.com/tc39/proposal-realms/issues/217 |
20:22 | <devsnek> | littledan: isn't that how the window proxy works? |
20:22 | <littledan> | devsnek: On the web, there's only one thing you can get at |
20:22 | <devsnek> | oh ok |
20:22 | <littledan> | it's a proxy, yeah, but there aren't two separate values |
20:22 | <littledan> | I mean, there aren't two values available to JS |
20:22 | <devsnek> | right |
20:23 | <devsnek> | in node i exposed it as "global" on the new context api i'm trying to get merged in |
20:24 | <rbuckton> | littledan: There are two values (the window proxy and the target global), but the current evaluation context can only see one of them (the window proxy). |
20:25 | <littledan> | rbuckton: Right. So both the global and the this value would be the window proxy. |
20:25 | <littledan> | emulating the web isn't the use case here. I'm not sure what the use case is. |
20:26 | <rbuckton> | As far as the code under `evaluate` is concerned, yes. as far as the owner of the `Realm`, no. If you wanted to emulate a "window proxy" in your realm, you'd need to be able to access the *actual* global. |
20:27 | <littledan> | couldn't you do this by hooking two realms together, where you create a global object with the first one, and then you wrap it with a window proxy, and then you set that as the global object for the second one? |
20:27 | <rbuckton> | That sounds unnecessarily expensive. You'd end up with two sets of primordials. |
20:28 | <rbuckton> | If I were to make a change, it would be replacing `thisValue` in the realm init with a proxy handler (in which you access the actual global through proxy hooks). |
20:30 | <devsnek> | the first slide said one of the goals was supporting modules right |
20:44 | <devsnek> | numberformat is 👍🏻 |
20:44 | <ghermeto> | mmarchini here |
20:45 | <michaelficarra> | I am sooooooo hyped for Intl.DurationFormatter |
20:45 | <devsnek> | everything on intl is pretty awesome |
20:46 | <devsnek> | except for Intl.v8BreakIterator |
20:46 | <devsnek> | :P |
20:46 | <rbuckton> | +1 for DurationFormatter, although I'd also like to see some kind of "time ago" or "time until"-style format as well. |
20:47 | <michaelficarra> | my interns were asking me for exactly DurationFormatter last week and I had nothing for them |
20:48 | <michaelficarra> | I love the format of this update, holy crap it's good |
20:49 | <devsnek> | yes |
20:49 | <michaelficarra> | kudos to sffc for making this super easy to follow |
20:50 | <akirose> | always |
20:50 | <akirose> | sffc's slides & presentations are always clear and easy to follow <3 |
20:51 | <devsnek> | 🎉 🎉 |
20:52 | <devsnek> | lol speaking of Intl.v8BreakIterator |
20:53 | <akirose> | caridy: did you catch that point of order? |
20:54 | <robpalme> | we need your slides, carridy |
20:59 | <caridy> | oh, sorry, it was linked from the readme of the proposal |
21:00 | <caridy> | https://github.com/tc39/proposal-realms/#presentations |
21:00 | <devsnek> | thank you |
21:00 | <devsnek> | in the future could you link it in the agenda? |
21:02 | <caridy> | oh, sure! I can do that too. |
21:03 | <devsnek> | thanks! |
21:03 | <ljharb> | caridy: added them to the agenda |
21:03 | <michaelficarra> | I already did it for you caridy |
21:03 | <michaelficarra> | btw the note takers are doing an excellent job this meeting! |
21:04 | <devsnek> | i just saw an Intl.Locale slide |
21:05 | <devsnek> | i see it again |
21:06 | <akirose> | jackworks: if we're ready for you, would you be able to go for lunch? |
21:11 | <michaelficarra> | 🤔 I wonder who's going to be the first non-delegate to join... |
21:11 | <Bakkot> | does globbot count? |
21:11 | <michaelficarra> | no |
21:11 | <devsnek> | we already know who |
21:12 | <devsnek> | <-- |
21:12 | <michaelficarra> | devsnek: you have +v, you don't count either |
21:12 | <michaelficarra> | also don't tell aki |
21:13 | <devsnek> | 👀 |
21:13 | <ljharb> | also you're in the openjs foundation |
21:14 | <devsnek> | i'm not a delegate of the openjs foundation though |
21:14 | <michaelficarra> | shh yes you are |
21:14 | <akirose> | aren't you an "invited expert" |
21:14 | <devsnek> | that's my understanding |
21:14 | <robpalme> | rbuckton: are you good to go straight after lunch with resource mgmt? that will be 12:30 hawaii time. |
21:14 | <rbuckton> | That's fine with me. |
21:17 | <robpalme> | thank yo! |
21:22 | <devsnek> | uhoh https://gc.gy/48642746.png |
21:24 | <Bakkot> | devsnek that's allowed |
21:24 | <Bakkot> | I think |
21:24 | <devsnek> | if you mean engine262, that's the current spec |
21:24 | <devsnek> | i was looking more at the undefined/null split |
21:25 | <Bakkot> | the undefined/null split is also allowed I think |
21:25 | <ljharb> | by virtue of "any crazy extension is allowed"? |
21:25 | <Bakkot> | yup |
21:25 | <Bakkot> | "caller" is one of the canonical crazy extensions |
21:25 | <devsnek> | this is a weird area |
21:26 | <akirose> | "one of the canonical crazy extensions" 👌🏻 |
21:27 | <devsnek> | i just like that the spec uses the same "ThrowTypeError" function for so many different things |
21:27 | <devsnek> | "The caller, callee, and arguments properties may not be accessed on functions or the arguments objects for calls to them" |
21:30 | <devsnek> | point of order |
21:33 | <michaelficarra> | devsnek: yes? |
21:33 | <devsnek> | michaelficarra: shane had a point of order |
21:33 | <devsnek> | about who was talking |
21:33 | <devsnek> | i think the queue was updated |
21:33 | <akirose> | we good devsnek |
21:33 | <ystartsev> | akirose: will SES be done today? |
21:34 | <jackworks> | akirose: oops I'm in Shanghai can't go for lunch for you, it's 5am now in my place 🤣 |
21:34 | <akirose> | haha i know jackworks lol i meant presenting before/after we took a break |
21:34 | <akirose> | but also i'd love to get lunch 😂 |
21:35 | <ystartsev> | jackworks: damn, i can't make it past 3 am |
21:35 | <ystartsev> | i hope its the morning end of 5 am, not the night |
21:35 | <haxjs> | I'm eating my breakfast now, never east breakfast in 5am :) |
21:36 | <ystartsev> | im sitting in darkness o_o the evening drags on. there is no food |
21:36 | <ystartsev> | okok this should probably be in temporal dead zone |
21:37 | <rbuckton> | I need to grab myself some lunch. I should be back before the break is up |
22:36 | <akirose> | oh shit ystartsev i missed your earlier question |
22:36 | <akirose> | yeah i'm moving SES to tomorrow |
22:36 | <ystartsev> | ok, thanks akirose |
22:37 | <littledan> | hmm, I wonder if `using` could be spelled `try`... |
22:37 | <devsnek> | uh oh |
22:37 | <akirose> | O_O |
22:37 | <ystartsev> | try try? |
22:37 | <littledan> | (sorry, will follow up in issues) |
22:37 | devsnek | ducks |
22:54 | <cmorningstar> | akirose does Mark know you're moving the SES presentation? I don't think he's following IRC |
22:55 | <akirose> | yeah and also the schedule is linked in the reflector |
22:55 | <cmorningstar> | (y) |
23:03 | <littledan> | `try expr` is free (if we require parens around an object literal), and we could permit it before declarations |
23:04 | <littledan> | `try const foo = bar;`, `try fooBar;`, `fn(try foo);` |
23:04 | <littledan> | (I also like Ron's answer) |
23:06 | <Bakkot> | I am a lot happier with the try-block form than the using-declaration form, personally |
23:06 | <Bakkot> | I'm curious how others feel |
23:06 | <devsnek> | i kinda want to explore the expression form more |
23:06 | <ljharb> | i like the using form, that can appear anywhere in a block |
23:11 | <robpalme> | ms person === "dean tribble" |
23:12 | <ljharb> | ms like microsoft? dean doesn't work for microsoft |
23:12 | <rbuckton> | he did many years ago |
23:12 | <ljharb> | ah |
23:16 | <shu> | rbuckton: is the awkwardness of having to name intermediates the only motivation for `using value` over only having `using const`? |
23:17 | <devsnek> | `using const _unused = ...` |
23:19 | <rbuckton> | It's not awkwardness. For cases like locking, you would be introducing an unused binding. IF you have multiple of these, you end up with a lot of unused bindings that clutter the scope. Also, you often have to contend with linters that error on unused bindings, meaning that many developers would have to add a fair amount of `// eslint-ignore`-like comments to their code for what would essentially have been: |
23:19 | <rbuckton> | ``` |
23:19 | <rbuckton> | try using(mutex.lock()) { |
23:19 | <rbuckton> | ... |
23:19 | <rbuckton> | } |
23:19 | <rbuckton> | ``` |
23:20 | <shu> | rbuckton: i don't think linting is a real argument, since it'll still be syntactically distinguished with `using` |
23:20 | <shu> | rbuckton: as for "many unused bindings", this is not borne out by practice in large C++ code bases i've worked in |
23:20 | <rbuckton> | If we had resolved the destructuring issue to the stage1 semantics, we could have considered `using const {} = expr`, though that still feels odd. |
23:22 | <rbuckton> | shu: There was a reason we allowed `catch {}` without a binding. I'd very much like this feature to have a form that doesn't introduce a binding. |
23:23 | <shu> | i think the difference is the syntax cost for removing the binding for catch is much lower |
23:23 | <devsnek> | i can confirm i would use the bindingless version |
23:23 | <rbuckton> | shu: I've written a fair bit of JS code using async coordination primitives for synchronizing access to resources using async functions and make heavy use of the bindingless form for locking. |
23:23 | <devsnek> | and i don't know the state of the web locks api |
23:23 | <devsnek> | but i bet people using that would want to use it too |
23:24 | <rbuckton> | I would heavily use it with https://www.npmjs.com/package/@esfx/async |
23:24 | <devsnek> | is there some concern that iterator helpers is not going to happen?' |
23:24 | <rbuckton> | (which is a version of my old `prex` async coordination package). |
23:25 | <Bakkot> | devsnek no I just want them to happen in the right order |
23:25 | <devsnek> | k |
23:26 | <shu> | rbuckton: is there a stronger argument than "i would use it"? i mean i would use it with just the `using const` form for sure, since in my experience naming your RAII bindings is not really a big deal |
23:26 | <shu> | i think dan or someone earlier suggested just `using const (expr)` and not also `using value` and that is more preferable to me |
23:27 | <devsnek> | i can also confirm that its awkward in rust to need to name scoped allocations |
23:27 | <devsnek> | `let _ = ...` |
23:27 | <rbuckton> | shu: There's a *significant* amount of C# code written using C#'s version `using (expr) { ... }` |
23:27 | <shu> | that's not apples to apples? |
23:27 | <rbuckton> | `using const (expr)` is kind of interesting. |
23:28 | <rbuckton> | shu: The prior art in C# is where I pulled a lot of these concepts from, so I think it's applicable. |
23:28 | <shu> | rbuckton: using (expr) is a scope introduction form as well |
23:30 | <rbuckton> | shu: Yes. that was my question earlier. I see two paths forward: |
23:30 | <rbuckton> | 1. Only `using const` and `using value` forms (no `try using` form). |
23:30 | <rbuckton> | 1. `try using (const ...)`, `try using (expr)` and `using const` forms (no `using value`) (essentially the same as C# 8). |
23:30 | <rbuckton> | (why do I expect markdown numbered lists to work in IRCCloud)... |
23:32 | <devsnek> | lol |
23:33 | <shu> | rbuckton: i like a subset of the first 1. with only a binding form. if a bindingless form is overwhelmingly preferred by committee, that we only introduce a single syntax form |
23:34 | <littledan> | Object.keys is already a thing. Do we have any data on how slow are idioms using Object.keys? |
23:34 | <devsnek> | object.keys ain't that slow |
23:34 | <shu> | rbuckton: my objections are pretty weak |
23:35 | <shu> | rbuckton: i love RAII |
23:35 | <rbuckton> | shu: A bindingless form is important to several of the use cases that motivated my proposing this feature. I very much want some bindingless form to survive. |
23:35 | <littledan> | I can understand the argument that this propsal expresses intent better (modulo that I don't understand whether that's true or not) but I'm surprised that performance is used so much as a justification |
23:36 | <shu> | it seems slower than the previous version? |
23:39 | <littledan> | iterator helpers could be used with Object.keys and friends with Iterator.from() |
23:39 | <littledan> | I think the iterator helpers proposal is sort of predicated on the idea that this is a reasonable idiom |
23:40 | <littledan> | (which I think it is) |
23:40 | <shu> | i also do think it is a reasonable idiom. reality is that people do use objects for small-ish collections and will continue to |
23:41 | <rbuckton> | JSON `reviver` is *very* hard to use on any non-trivial JSON object graph. (without the proposed changes to JSON.parse). |
23:41 | <Bakkot> | I expect code bases which are using iterator helper to have a lot of `Thing.from(Iterator.from(obj).foo().bar())` |
23:41 | <Bakkot> | for node lists of whatever |
23:42 | <Bakkot> | *or whatever |
23:42 | <ystartsev> | rbuckton: do you think the reviver proposal in json parse helps this at all? |
23:42 | <Bakkot> | and having `Object.fromEntries(Iterator.from(Object.entries(obj)).foo().bar())` seems pretty much fine |
23:42 | <Bakkot> | it matches that pattern |
23:42 | <rbuckton> | ystartsev: For the most part, yes. It's definitely a step in the right direction. |
23:42 | <Bakkot> | where Object.iterateEntries() does not match that pattern |
23:42 | <ystartsev> | rbuckton: i would rather support that then, if that is the case that is really being solved |
23:43 | <ljharb> | Bakkot: `Object.fromEntries(Object.iterateEntries(obj).foo().bar())`? |
23:43 | <devsnek> | Iterator.from |
23:43 | <ljharb> | Bakkot: you wouldn't necessarily use Iterator.from if you're getting an iterator from a builtin |
23:43 | <devsnek> | foo and bar are iterator prototype methods |
23:43 | <ystartsev> | devsnek: iterator.from wont work in this case i think |
23:43 | <devsnek> | oh i see what you did nvm |
23:43 | <ljharb> | right but all the builtins are going to spit out Iterators already |
23:43 | <ljharb> | Iterator.from is for coercing user types |
23:43 | <devsnek> | i thought ljharb did Object.entries() |
23:43 | <Bakkot> | ljharb you would use a prototype method or Iterator.from, I expect |
23:43 | <ljharb> | just like you wouldn't use Array.from or Promise.resolve if you already know it's an array or a promise for sure |
23:44 | <devsnek> | i wouldn't do Iterator.from([].values()) |
23:44 | <Bakkot> | I don't know that (e.g.) node lists expose a prototype method exposing an iterator |
23:44 | <Bakkot> | except for [Symbol.iterator] |
23:44 | <devsnek> | yeah you'd use Iterator.from on a node list |
23:44 | <Bakkot> | and I will absolutely use Iterator.from() over an explicit [Symbol.iterator] |
23:44 | <devsnek> | that's why its there |
23:44 | <devsnek> | 👍🏻 |
23:44 | <michaelficarra> | agreed |
23:44 | <ljharb> | Bakkot: agreed on that part |
23:44 | <devsnek> | well also to cover iterators that don't inherit from Iterator.prototype |
23:45 | <ljharb> | Bakkot: but if you're using anything that spits out an iterator, you wouldn't want or need Iterator.from |
23:45 | <Bakkot> | presumably only user iterators will fail to inherit from Iterator.prototype |
23:45 | <ljharb> | * a real iterator |
23:45 | <ljharb> | Bakkot: right |
23:45 | <ljharb> | you might use it like `[].concat(x)` or `Promise.resolve(x)` to not have to think about it, sure |
23:45 | <Bakkot> | ljharb right but most things don't spit out iterators |
23:45 | <Bakkot> | they spit out nodelists |
23:45 | <Bakkot> | or whatever |
23:45 | <ljharb> | matchAll, values/keys/entries on things |
23:45 | <ljharb> | but yes that's true |
23:45 | <ljharb> | obv if you have an iterable you'd use Iterator.from |
23:47 | <rbuckton> | I'm still a little unsure of iterator helpers. It still feels like its the wrong abstraction (i.e. operate over an "iterator" rather than an "iterable"). |
23:47 | <ljharb> | there's no inheritance chain for "iterable"s |
23:48 | <rbuckton> | Yeah, I know that. |
23:48 | <ljharb> | i definitely think that things that take iterators should always take iterables; but i don't see any other way for the helpers proposal to work |
23:48 | <devsnek> | you'd need a chain builder |
23:48 | <ljharb> | Iterator.from is that builder |
23:48 | <devsnek> | no like IterableBuilder(iterator).filter().map()[Symbol.iterator]() |
23:49 | <devsnek> | for ron's pattern |
23:49 | <ljharb> | ah |
23:49 | <rbuckton> | devsnek: That's what my `iterable-query` package does: |
23:49 | <rbuckton> | ``` |
23:49 | <rbuckton> | const { from } = require("iterable-query"); |
23:49 | <rbuckton> | from(x).filter(...).map(...).toArray(); |
23:49 | <rbuckton> | ``` |
23:49 | <rbuckton> | But it operates over iterables, not iterators. |
23:49 | <devsnek> | iterators are iterables |
23:49 | <ljharb> | `from` takes an iterable; but filter and map are surely operating on iterators? |
23:49 | <devsnek> | but i get your point |
23:49 | <Bakkot> | for things where you are coercing back at the end, it seems like you should absolutely be operating on iterators, not iterables |
23:49 | <rbuckton> | devsnek: not precisely. |
23:49 | <Bakkot> | you shouldn't need to build up the whole collection every time |
23:49 | <rbuckton> | built-in iterators are iterables. |
23:50 | <devsnek> | iterators are iterable by the definition of iterable in this language |
23:50 | <ljharb> | no |
23:50 | <devsnek> | oh i see what you mean |
23:50 | <devsnek> | fair enough |
23:50 | <rbuckton> | User-defined iterators aren't iterables (which was mentioned above). |
23:50 | <ljharb> | all built-in iterators happen to be iterables |
23:50 | <ljharb> | iterators have "next", iterables have Symbol.iterator |
23:50 | <rbuckton> | TypeScript calls them "IterableIterator"s |
23:50 | <Bakkot> | I have very rarely seen someone define an iterator without using a generator |
23:50 | <devsnek> | you won't get very far if your iterator isn't iterable though |
23:51 | <devsnek> | since for loops won't accept it |
23:51 | <littledan> | the reviver thing seems like a red herring; there are other reasons you might iterate over an object (e.g., they have really nice literals to use in JS). But that's why we have Object.keys/values/entries |
23:52 | <rbuckton> | If you look at C#/.NET's `Enumerable` class or RX, iterating over (or subscribing to) those chained operations by default result in re-executing each step in the chain against the original collection source. |
23:52 | <ljharb> | devsnek: for..of takes non-iterable iterators |
23:52 | <Bakkot> | ljharb wait does it? |
23:52 | <Bakkot> | how does that work? |
23:52 | <ljharb> | hm |
23:52 | <ljharb> | wait maybe not, one sec |
23:53 | <devsnek> | https://engine262.js.org/#gist=66a1fede0f3a2fa776e3c99dacd87b81 |
23:53 | <ljharb> | ok no, it doesn't, i was fooled by an inherited Symbol.iterator method |
23:53 | <devsnek> | lol |
23:53 | <rbuckton> | `for..of`takes iterables. The iterators those iterables produce don't themselves need to be iterable. |
23:53 | <Bakkot> | even when you try to get a non-iterable iterator you can't :P |
23:53 | <rbuckton> | `for..of` never directly calls `next`. |
23:53 | <devsnek> | huh |
23:54 | <devsnek> | it calls it in the head of the loop |
23:54 | <ljharb> | rbuckton: wait what? |
23:54 | <rbuckton> | It indirectly calls `next`. |
23:54 | <devsnek> | it does IteratorNext/IteratorStep |
23:54 | <devsnek> | because we have a helper |
23:54 | <devsnek> | but that still seems pretty direct to me |
23:54 | <ljharb> | rbuckton: ah ok |
23:54 | <rbuckton> | `for (const x of y)` doesn't call` next` on `y`, it calls `next` on the result of `y[Symbol.iterator]()`. |
23:54 | <ljharb> | yeah i'd call that directly calling it |
23:54 | <ljharb> | right |
23:55 | <michaelficarra> | ugh I can't believe it's taken us this long to add these |
23:56 | <rbuckton> | ``` |
23:56 | <rbuckton> | for (const x of { [Symbol.iterator]() { return { next() { return { done: true }; } }; } }) { } |
23:56 | <rbuckton> | ``` |
23:56 | <rbuckton> | Works fine, the iterator returned from `[Symbol.iterator]` doesn't need to itself have a `[Symbol.iterator]`. |
23:56 | <rkirsling> | I wish we could replace the "Logical" in this proposal name but I don't have a better idea offhand and I guess it doesn't really matter wrt the ultimate spec/impl change s |
23:56 | <michaelficarra> | rkirsling: what's wrong with logical? |
23:56 | <michaelficarra> | they're the logical operators |
23:56 | <devsnek> | i'd call it "getting the rest of the binary operators" |
23:56 | <rkirsling> | but ?? isn't truth-oriented |
23:57 | <rkirsling> | which is what "logical" really means |
23:57 | <michaelficarra> | sorry, it *used to be* the logical operators |
23:57 | <rkirsling> | yes, that part is very true :D |
23:57 | <rbuckton> | rkirsling: it sort of is, but the "truth" is the truth of "is the operand null or undefined". |
23:57 | <ljharb> | they're not really logical operators tho, they're value selection operators |
23:57 | <ljharb> | imo logical operators produce booleans |
23:58 | <rbuckton> | Sure |
23:58 | <devsnek> | short circuiting binary operators take it or leave it |
23:58 | <rbuckton> | Fair enough. |
23:58 | <rbuckton> | devsnek: Wordy, but I like it. |
23:58 | <rbuckton> | ljharb: `"" || 1` does not produce a boolean. |
23:58 | <devsnek> | i think that's ljharb's point |
23:58 | <rkirsling> | I had brought this up here: https://github.com/tc39/proposal-nullish-coalescing/pull/50 |
23:58 | <ljharb> | rbuckton: that's because it's not a logical operator |
23:59 | <ljharb> | rbuckton: in a language where || is a logical operator, it produces true or false |
23:59 | <rbuckton> | "logical-ish operators" |
23:59 | <rkirsling> | but I don't think in this case it'll have an impact on spec names anyway |
23:59 | <ljharb> | it's a value selection operator. |
23:59 | <rkirsling> | (I should verify) |
23:59 | <devsnek> | rkirsling: it got removed |
23:59 | <devsnek> | because of the parens thing |
23:59 | <michaelficarra> | the semantics in this proposal appear obviously correct |
23:59 | <rkirsling> | devsnek: what did? |
23:59 | <devsnek> | the name "ShortCircuitExpression" |