01:00 | <jkup> | yulia: Ashley Claymore Rob Palmer this is what I was referring to https://firefox-source-docs.mozilla.org/devtools-user/custom_formatters/index.html |
01:03 | <yulia> | heck, added 2022. nice |
01:06 | <msaboff> | Add your name, etc to today's notes. |
01:10 | <littledan> | I really like Mark’s thing of recording and posting his presentations. It’d be great if we can make this an option for presenters all the time, and post the presentations to a TC39 YouTube channel, for presenters who want it. |
01:12 | <Andreu Botella (at TC39, 🕐 JST)> | would that make it harder to remove sections from the notes, since the video would also need to be edited? |
01:12 | <bakkot> | yes, but we only very rarely do that, and mostly for entire items rather than small parts of a presentation |
01:12 | <Justin Ridgewell> | Strings will deoptimize pretty quickly once you store non-utf8 bytes |
01:13 | <Justin Ridgewell> | And assembling them byte by byte is not very fast |
01:13 | <Andreu Botella (at TC39, 🕐 JST)> | In typical implementations, I don't think that's true, since all engines have Latin-1 and UTF-16 representations, but not UTF-8 |
01:14 | <canadahonk> | used strings personally before and it is not nice. works but :/ |
01:15 | <Justin Ridgewell> | In typical implementations, I don't think that's true, since all engines have Latin-1 and UTF-16 representations, but not UTF-8 |
01:16 | <Chris de Almeida> | I really like Mark’s thing of recording and posting his presentations. It’d be great if we can make this an option for presenters all the time, and post the presentations to a TC39 YouTube channel, for presenters who want it. |
01:16 | <Mathieu Hofman> | Also you can't build a real TypedArray with a string backing, so might as well shim it with a mutable array buffer copy |
01:16 | <Andreu Botella (at TC39, 🕐 JST)> | Is V8’s one-byte string Latin1? When I wrote the UTF-8 parser, it would create 2 byte strings once you went over 0x80 |
01:17 | <Andreu Botella (at TC39, 🕐 JST)> | a Latin-1 string representation is identical to a byte array, where the Unicode character values would just be the byte values |
01:19 | <Marja Hölttä> | v8 has two types of strings, one-byte (latin1) and two-byte (not quite utf-16 but ucs... something... maybe ucs-2) |
01:20 | <Marja Hölttä> | and interestingly, it also has an utf-8 decoder which is used during streaming parsing, it can do stuff like pause mid-character if we need to wait for more data from the network. so in that case we don't use chromium's utf-8 decoder but our own |
01:22 | <Andreu Botella (at TC39, 🕐 JST)> | v8 has two types of strings, one-byte (latin1) and two-byte (not quite utf-16 but ucs... something... maybe ucs-2) |
01:26 | <Chris de Almeida> | please add your name to the attendees list of today's notes doc |
01:26 | <Richard Gibson> | I don't know if WTF-16 is the right term for that (https://simonsapin.github.io/wtf-8/#ill-formed-utf-16) |
01:28 | <Justin Ridgewell> | a Latin-1 string representation is identical to a byte array, where the Unicode character values would just be the byte values ONE_BYTE_STRING representation. |
01:28 | <Justin Ridgewell> | and interestingly, it also has an utf-8 decoder which is used during streaming parsing, it can do stuff like pause mid-character if we need to wait for more data from the network. so in that case we don't use chromium's utf-8 decoder but our own |
01:29 | <bakkot> | if you do it in the next 10 seconds i don't have to redact the logs |
01:29 | <bakkot> | yay |
01:29 | <Marja Hölttä> | Justin Ridgewell: no, not that one. maybe there is another one you wrote :) |
01:29 | <ryzokuken> | 🙇♂️ |
01:29 | <Marja Hölttä> | too many utf-8 decoders |
01:30 | <canadahonk> | sorry 🙈 |
01:30 | Chris de Almeida | shows canadahonk to the shamecube |
01:30 | <Michael Ficarra> | we need regular reminders that this is a public channel |
01:30 | <Justin Ridgewell> | Justin Ridgewell: no, not that one. maybe there is another one you wrote :) |
01:32 | <bakkot> | 2017-12-11, nice |
01:32 | <Marja Hölttä> | Justin Ridgewell: nope, this one: https://source.chromium.org/chromium/chromium/src/+/main:v8/src/parsing/scanner-character-streams.cc;l=507 .. and... i wrote it :D |
01:32 | <Marja Hölttä> | we can unify these if your version can also pause mid-character to wait for more data |
01:32 | <Chris de Almeida> | bakkot: the notes link made it to the archive 😭😭😭 |
01:33 | <bakkot> | sadness |
01:35 | <Justin Ridgewell> | we can unify these if your version can also pause mid-character to wait for more data |
01:35 | <Marja Hölttä> | based on very quick googling it seems that the difference between UCS-2 and UTF-16 is more than treating the ill-formed strings but my knowledge level is getting very shaky here |
01:35 | <Marja Hölttä> | ahh it has been rewritten since, okay that's good, i think 2 utf-8 decoders are enough for chromium |
01:35 | <Justin Ridgewell> | UCS-2 allows lone surrogates, UTF-16 doesn't |
01:36 | <Justin Ridgewell> | They’re the same otherwise |
01:38 | <Marja Hölttä> | google says "UCS-2 is fixed width, UTF-16 is variable width with a minimum of two bytes and a maximum of four bytes." << what about this part? no idea what v8 does here |
01:38 | <littledan> | A related interesting API proposal https://gist.github.com/domenic/a9343fa787ba54b4ba3a60882c49cc32?permalink_comment_id=4394695#gistcomment-4394695 |
01:38 | <Rob Palmer> | Can anyone dialled in share the TCQ on Teams? |
01:39 | <jkup> | It was up for a second |
01:39 | <littledan> | IMO it’s more parsimonious to have a separate method |
01:40 | <Justin Ridgewell> | google says "UCS-2 is fixed width, UTF-16 is variable width with a minimum of two bytes and a maximum of four bytes." << what about this part? no idea what v8 does here |
01:41 | <littledan> | I think the meaning of ucs2 has changed over time. It was designed in the days when all code points fit in 16 bits. Since then, it has been redefined to mean, potentially ill-formed utf16 |
01:41 | <Justin Ridgewell> | Yah, basically that ^ |
01:42 | <littledan> | JS generally does not check for well-formed-ness so you could (informally) say it works in the ucs2 encoding rather than utf16 |
01:46 | <Marja Hölttä> | oh, and wtf-16 says it's the name kinda corresponding to that evolved usage of ucs-2. yess, not confusing at all. okay. |
01:50 | <Marja Hölttä> | ok how did we end up here? what does "Strings will deoptimize pretty quickly once you store non-utf8 bytes" mean? one thing that's not great about onebyte vs twobyte is that if you have one non-onebyte character in your string, the whole string has to be stored as a twobyte and it's slightly unnecessary overhead. |
01:50 | <Marja Hölttä> | (but i don't see a way around it in the current world unless we add utf-8 strings and... i don't think anyone wants to... strings are incredibly complex as is) |
01:52 | <Michael Ficarra> | @Marja Hölttä ropes of mixed 1-byte and 2-byte sections |
01:53 | <Marja Hölttä> | true, could also do that! |
01:53 | <littledan> | No I wasn’t talking about volatile read-only views on an underlying changing ArrayBuffer |
01:53 | <Justin Ridgewell> | ok how did we end up here? what does "Strings will deoptimize pretty quickly once you store non-utf8 bytes" mean? one thing that's not great about onebyte vs twobyte is that if you have one non-onebyte character in your string, the whole string has to be stored as a twobyte and it's slightly unnecessary overhead. String.fromCharCode(0x80) returned a 2-byte string representation |
01:54 | <Justin Ridgewell> | 0x80 being an illegal UTF-8 lead byte |
01:55 | <Justin Ridgewell> | You can construct strings in memory that holds any byte sequence, you just can’t transfer that string over the wire |
01:55 | <Justin Ridgewell> | A UTF-8 parser on the other end will replace bad byte sequences with the Replacement Char |
01:56 | <littledan> | I am also OK keeping the rw lock stuff outside of this proposal but I think it could make it more usable for certain cases, which could allow some more zero copy in practice. Not needed for the motivating embedded case though. |
01:57 | <Andreu Botella (at TC39, 🕐 JST)> | (but i don't see a way around it in the current world unless we add utf-8 strings and... i don't think anyone wants to... strings are incredibly complex as is) |
01:59 | <littledan> | I am very happy that the wasm memory control stuff is getting attention |
02:00 | <Mathieu Hofman> | I took a quick look, and it looks like it's basically trying to specify a full MMU ? |
02:01 | <shu> | it's a pretty open question but in the limit, yeah, systems people are gonna want full control |
02:01 | <shu> | i haven't heard anything too concrete yet |
02:01 | <yulia> | yeah i think they are still exploring quite a bit. |
02:03 | <littledan> | I hope we get the capability to set up memory protection for the first page so I can get a segfault in Wasm for derefencing a null pointer |
02:04 | <shu> | As a... Unix user, I want my programs to SIGSEV, so th bus error |
02:11 | <littledan> | It would be really interesting to hear a presentation about how various approaches to polyfills work, since it seems to drive a lot of our designs |
02:15 | <littledan> | In general it’s good to find reasons which could be motivating for others, but it also is interesting to learn what the proponents are motivated by. |
02:19 | <keith_miller> | Isn't the clamping just value & 256 ? |
02:19 | <shu> | yeah i am confused |
02:19 | <keith_miller> | Or is there some other part that's not quite that? |
02:20 | <Justin Ridgewell> | Isn't the clamping just value & 255 |
02:20 | <keith_miller> | Err sorry |
02:20 | <keith_miller> | Yeah |
02:20 | <Andreu Botella (at TC39, 🕐 JST)> | or value % 256 |
02:21 | <littledan> | That’s how normal uint8arrays work; I thought clamped was different |
02:21 | <littledan> | What if we added a Math.clamp method? I think that would be a broadly useful utility. |
02:21 | <Justin Ridgewell> | ^CSS did, not us |
02:21 | <yulia> | right but what are we solving exactly rn? |
02:22 | <ljharb> | so the spec logic is https://tc39.es/ecma262/#sec-touint8clamp |
02:22 | <ljharb> | if all those steps are just value & 255 then an editorial cleanup would certainly have helped :-) |
02:22 | <shu> | wait, why isn't that algorithm steps? |
02:22 | <shu> | you said it wans't described in algo steps |
02:22 | <rbuckton> | Is that clamping or does that allow overflow/underflow? |
02:22 | <Justin Ridgewell> | if all those steps are just |
02:22 | <ljharb> | yes, my mistake, it is algorithm steps |
02:22 | <littledan> | right but what are we solving exactly rn? |
02:23 | <Michael Ficarra> | FYI we also didn't get a summary for the previous topic |
02:24 | <yulia> | is math.clamp more general than the dataview methods? i'm not opposed to it, would be good to see which everyday things are being improved |
02:24 | <yulia> | i think the spec has a oneliner note using modulo |
02:24 | <keith_miller> | Wait sorry it's not value & 255 lol I'm too tired it's if (number > 255) return 255; if (number < 0) return 0; return number; |
02:24 | <shu> | wait taking a step back |
02:24 | <yulia> | https://tc39.es/ecma262/#clamping |
02:24 | <shu> | why did we add uint8clamp TAs to begin with? |
02:24 | <shu> | something textures? |
02:24 | <keith_miller> | I think for textures/colors or something yeah |
02:25 | <Justin Ridgewell> | Wait sorry it's not |
02:25 | <canadahonk> | is math.clamp more general than the dataview methods? i'm not opposed to it, would be good to see which everyday things are being improved |
02:25 | <littledan> | is math.clamp more general than the dataview methods? i'm not opposed to it, would be good to see which everyday things are being improved |
02:26 | <yulia> | sure, that sounds fine |
02:26 | <shu> | written it at least a few times for webapps in the past |
02:26 | <rbuckton> | yulia: I have code that could make use of consistent names for data view methods for the purpose of dynamic dispatch, were it to be rewritten to use dynamic dispatch: https://github.com/esfx/esfx/blob/main/packages/struct-type/src/internal/numbers.ts#L122-L133 one data point may not necessarily be compelling, however. |
02:26 | <ljharb> | here's my summary:
lmk if i'm missing anything |
02:27 | <canadahonk> | there is a ~new math.clamp proposal that lacks a champion btw |
02:27 | <ljharb> | Yeah it doesn’t really have to do with data views, it’s just like you give a min and max and return one of those if you are out of bounds |
02:27 | <canadahonk> | there is a ~new math.clamp proposal that lacks a champion btw |
02:28 | <yulia> | if you had math.clamp you could use math.floor with it, no? |
02:28 | <Michael Ficarra> | https://github.com/Richienb/proposal-math-clamp which I may if no one else wants :^) |
02:29 | <ljharb> | and ceil if negative, sure. Math.clamp helps me compose the logic for sure. |
02:29 | <shu> | Number.setFPUControlWord so we can change the rounding mode to round half to even |
02:31 | <keith_miller> | Is Math.clamp sufficiently more powerful than Math.min(Math.max(x, lower), upper) ? |
02:32 | <rbuckton> | It's sufficiently easier to get right the first time |
02:33 | <canadahonk> | also something something performance probably better? |
02:33 | <keith_miller> | Ehh, I think I'd screw up the argument order too though |
02:33 | <keith_miller> | On 8 hours of sleep over 3 days |
02:33 | <keith_miller> | Performance is probably the same |
02:33 | <canadahonk> | 2 func calls vs 1? |
02:34 | <keith_miller> | It would be inlined and optimized in most JIT engines anyway |
02:35 | <rbuckton> | I imagine signature help in an IDE is more reliable for something that reads Math.clamp(value: number, min: number, max: number) then trying to figure out the correct order for Math.min(x: number, y: number) and Math.max(x: number, y: number) . |
02:35 | <littledan> | Yeah I don’t think this is a thing to decide on perf but rather developer mental model |
02:35 | <canadahonk> | agree, but I mean it definitely wouldn't be a downside at least, only possible benefit (afaik) |
02:37 | <jkup> | clamp seems nice, especially combining it with round/floor |
02:51 | <ljharb> | liquid volume remains solidly imperial for cooking, in the US |
02:52 | <ljharb> | also gasoline and milk |
02:52 | <rbuckton> | liquid volume remains solidly imperial for cooking, in the US |
02:52 | <ljharb> | hm, maybe i don't bake with the newest recipes, but i still see them all in imperial |
02:52 | <rbuckton> | also gasoline and milk |
02:52 | <shu> | wait what |
02:52 | <shu> | liter is an imperial unit? |
02:53 | <ljharb> | soda is non-imperial |
02:53 | <ljharb> | gas/milk is imperial |
02:53 | <rbuckton> | No, I'm saying soda is not generally measured in imperial units |
02:53 | <shu> | oh i got it reversed |
02:53 | <shu> | right |
02:53 | <Chris de Almeida> | you don't use volume in baking |
02:53 | <rkirsling> | what a plot twist that soda is an unamerican drink |
02:53 | <ljharb> | like a teaspoon of oil or something? |
02:54 | <ljharb> | a cup of water, etc |
02:54 | <rbuckton> | you don't use volume in baking |
02:54 | <Michael Ficarra> | I think the british baking show has rubbed off on americans and now they all use metric units when baking |
02:54 | <Chris de Almeida> | it's always by weight if you're doing it right... but it does help that 1ml === 1g |
02:54 | <ljharb> | maybe yall are doing fancier baking than me, but ive not yet heard americans using metric for baking |
02:54 | <ryzokuken> | for water |
02:54 | <Chris de Almeida> | yes |
02:55 | <rbuckton> | I'm finding myself using metric more and more as I venture deeper and deeper into the 3D printing world |
02:55 | <Chris de Almeida> | if you see a baking recipe and it's giving volume measurements, throw it in the trash |
02:57 | ljharb | nervously glances at literally every cake mix box in safeway |
02:57 | <Chris de Almeida> | cake mix?! /scoff |
02:57 | <Michael Ficarra> | A BOX?! |
02:57 | <Michael Ficarra> | jesus |
02:58 | <shu> | what, you want your cake mix in a paper bag? |
02:58 | <Chris de Almeida> | unserious cake mixers itc |
03:00 | <ljharb> | wait what else would cake mix come in but a box |
03:01 | <kriskowal> | 50# sacks |
03:01 | <ljharb> | i mean it's bagged inside the box ofc, like cereal |
03:01 | <canadahonk> | usage="cake-mix" |
03:01 | <ptomato> | wait what else would cake mix come in but a box |
03:01 | <Richard Gibson> | aluminum cans |
03:01 | <Michael Ficarra> | it wouldn't be cake mix and it wouldn't be in a box, it would be raw ingredients |
03:01 | <Chris de Almeida> | the rawest |
03:01 | <ljharb> | ok, calm down, you baking elitists |
03:02 | <Chris de Almeida> | if you're not milling your own flour are you really a baker? |
03:02 | <kriskowal> | that would be a miller |
03:03 | <ljharb> | https://abcnews.go.com/Lifestyle/man-spends-months-1500-make-sandwich-scratch/story?id=33802231 |
03:03 | <kriskowal> | …molar, müller, mollino, etc |
03:03 | <kriskowal> | https://abcnews.go.com/Lifestyle/man-spends-months-1500-make-sandwich-scratch/story?id=33802231 |
03:39 | <Chris de Almeida> | looking for folks to help with the notes starting in 20 mins |
03:58 | <Chris de Almeida> | 👀 |
03:59 | <Chengzhong Wu> | +1 |
04:01 | <Chengzhong Wu> | do we need consensus for stage 0? |
04:01 | <Ashley Claymore> | could someone on the team's call copy the link to the slides? I'm assuming if I join I won't be able to see previous chat history |
04:02 | <Chris de Almeida> | https://docs.google.com/presentation/d/1yakKCsS3pR0T7eJcaJD2ZUzK6xG6FcoFnrmngkJUcEo/edit#slide=id.g2fa19dd416b_0_181 |
04:04 | <Ashley Claymore> | ta |
04:04 | <Chris de Almeida> | We regret to inform that the Observable topic has been withdrawn due to availability issues. |
04:17 | <rkirsling> | "30m stage 0 update" is a pretty wild concept |
04:18 | <ljharb> | if we're getting an item more than once at committee then it's really not stage 0, it's stage 1 |
04:18 | <ljharb> | because we're spending time exploring the problem |
04:19 | <Ross Kirsling> | that is also how I feel |
04:19 | <Chris de Almeida> |
|
04:43 | <waldemar> | What if the module exports then ? |
04:43 | <Ashley Claymore> | that's coming up |
04:44 | <hax (HE Shi-Jun)> | What if the module exports then 😭 |
04:45 | <hax (HE Shi-Jun)> | I always think it's a mistake. |
04:45 | <waldemar> | Yeah. That seems a bit troublesome… |
04:47 | <hax (HE Shi-Jun)> | So I really hope we can fix it (not sure why Symbol.unthenable was rejected...) |
04:48 | <ljharb> | web compat, people were already relying on thenable modules in production |
04:49 | <Andreu Botella (at TC39, 🕐 JST)> | web compat, people were already relying on thenable modules in production |
04:49 | <hax (HE Shi-Jun)> | web compat, people were already relying on thenable modules in production |
04:50 | <hax (HE Shi-Jun)> | Is it a real production or just toy project? |
04:50 | <ljharb> | i'm not sure we ever dug into it, we just heard claims that they were i think |
04:51 | <Andreu Botella (at TC39, 🕐 JST)> | would it be hard to feature detect that? |
04:51 | <Andreu Botella (at TC39, 🕐 JST)> | well, I meant, hard to know how much it's used |
04:52 | <hax (HE Shi-Jun)> | I really think relying on the such bad semantics (static import and dynamic import give u different things) in production is very very weird... |
04:54 | <canadahonk> | are there any known demands for import.defer? |
04:57 | <Justin Ridgewell> | @nicolo-ribaudo we can hear you typing |
05:00 | <Mathieu Hofman> | Is it a real production or just toy project? |
05:01 | <Mathieu Hofman> | I'm not on the call now, what is the problem with lazy evaluating on export access? |
05:01 | <bakkot> | thenables |
05:03 | <Justin Ridgewell> | Specifically the promise resolution of the dynamic import triggers the evaluation |
05:04 | <Mathieu Hofman> | I understand that. But it just means that only thenable modules wouldn't be lazy evaluated. More precisely the promise logic doing get then would trigger their evaluation |
05:05 | <Mathieu Hofman> | It wouldn't affect any other kind of modules |
05:05 | <bakkot> | any property access triggers evaluation |
05:05 | <bakkot> | and you have to access .then |
05:06 | <Mathieu Hofman> | Right so what's the problem to trigger evaluation of thenable modules |
05:06 | <Ashley Claymore> | it triggers all modules |
05:06 | <bakkot> | Promise.resolve(foo) accesses foo.then |
05:06 | <bakkot> | regardless of whether foo has a .then |
05:06 | <Mathieu Hofman> | I'm just saying if the module is non thenable, it wouldn't trigger evaluation. All good |
05:07 | <bakkot> | any property access triggers evaluation |
05:07 | <bakkot> | the property does not have to exist to trigger evaluation |
05:07 | <bakkot> | and sticking the module namespace object into a promise triggers access of .then |
05:07 | <bakkot> | and dynamic import sticks the module namespace object into a promise |
05:07 | <Mathieu Hofman> | But that's what I'm asking. Why can't we defer evaluation to access of a known export |
05:08 | <shu> | when would you trigger the evaluation |
05:09 | <Mathieu Hofman> | You don't need to evaluate to know what is exported |
05:09 | <shu> | Promise.resolve accesses .then, it doesn't ask if it has a .then |
05:09 | <Mathieu Hofman> | When you do get then or any prop access for known exports |
05:09 | <shu> | which Promise.resolve does, it gets .then |
05:10 | <shu> | what is happening |
05:10 | <ljharb> | i think what mathieu is suggesting is that we change promise resolution so that for a deferred namespace object, it doesn't access .then unless that's an export of the module? |
05:11 | <Chris de Almeida> | I see stuff dropping off the queue, but we have time to continue discussion |
05:11 | <shu> | where do you put this, inside step 9 of https://tc39.es/ecma262/#sec-promise-resolve-functions? |
05:11 | <bakkot> | I assumed the idea was that you'd know the names before triggering evaluation |
05:11 | <bakkot> | I don't know if that's true |
05:12 | <ljharb> | where do you put this, inside step 9 of https://tc39.es/ecma262/#sec-promise-resolve-functions? |
05:12 | <shu> | seems wacky |
05:12 | <ljharb> | anything that touches thenable modules is indeed wacky |
05:13 | <Ashley Claymore> | I don't know if that's true |
05:14 | <littledan> | web compat, people were already relying on thenable modules in production |
05:16 | <littledan> | About the use cases for import.defer: we had an internal meeting in Bloomberg before TC39, and we couldn’t come up with a real use case. The case Ashley raised doesn’t occur in our infrastructure—it is very hypothetical. Personally I think removing the dynamic import.defer feature and not doing this namespace censorship is the right tradeoff for avoiding complexity |
05:17 | <yulia> | i feel like you can get what you want with dynamic import + static defer inside the dynamically imported graph |
05:17 | <yulia> | but let me check internally as well, we might have a use case. at the moment i can't think of anything |
05:17 | <ljharb> | i guess you could maybe get it with import() of a data URI that does a static deferred import and re-export? |
05:17 | <yulia> | yeah exactly |
05:18 | <Mathieu Hofman> | Sorry afk, will formulate more clearly soon |
05:18 | <yulia> | because import.defer is fundamentally different from the static import defer: static import defer is always a module graph edge. In the case of import.defer we are deferring the module root |
05:21 | <sffc> | I want to see a future where WASM module instantiation is handled transparently in the ESM universe. WASM source imports are a step in the right direction, but I want to see instantiation handled via import defer at some point. And dynamic loading of WASM sources is definitely a use case. |
05:24 | <littledan> | I want to see a future where WASM module instantiation is handled transparently in the ESM universe. WASM source imports are a step in the right direction, but I want to see instantiation handled via import defer at some point. And dynamic loading of WASM sources is definitely a use case. |
05:24 | <littledan> | The problem is the function coloring… |
05:30 | <nicolo-ribaudo> | I assumed the idea was that you'd know the names before triggering evaluation There are two possible implementations of this proposal:
With the second approach you can get the list of exports in this pre-execution phase, but it's more metadata you have to maintain. Bundlers are very similar to to the second case, except that they currently need no metadata: the way to bundle deferred modules is to wrap them in a function, and thus:
|
05:30 | <nicolo-ribaudo> | Import source + import() covers some of these cases though const wasm = import.source(...) + WebAssembly.instantiate(wasm) covers it in a sync way |
05:31 | <littledan> | Well, also |
05:32 | <nicolo-ribaudo> | Oh true -- it only covers the many of the cases but not all of them |
05:35 | <Duncan MacGregor> | It was briefly mentioned. Ah, found it in the automated transcript.
|
05:35 | <littledan> | I want to see a future where WASM module instantiation is handled transparently in the ESM universe. WASM source imports are a step in the right direction, but I want to see instantiation handled via import defer at some point. And dynamic loading of WASM sources is definitely a use case. |
05:42 | <Mathieu Hofman> | I assumed the idea was that you'd know the names before triggering evaluation |
05:44 | <yulia> | The problem is the function coloring… |
05:44 | <ptomato> | are any slides intended to be shared right now? |
05:44 | <yulia> | because thats a good point, import.source and then import later is possibly another solution? |
05:45 | <shu> | i don't really see the priority on making evaluation-phase wasm ESM integration work well |
05:45 | <shu> | you gotta do something to pass in the imports |
05:45 | <shu> | it seems like it's just composed import.source then an instantiate |
05:46 | <shu> | the hard problems about actually making wasm modules participate in the module graph is solved by import.source |
05:46 | <Ashley Claymore> | This exactly. My understanding is that all exported names of a module are known without evaluating the module. That means technically we could model this as an object with known props and the first access (get, gOPD) on one of these props would trigger the evaluation of the module. That way the import.defer of a non thenable module does not trigger the evaluation of the module. But if the module is thenable, then of course the regular promise logic will trigger evaluation when it does a get of then |
05:48 | <Ashley Claymore> | dropping import.defer looks like it has more of a win |
05:48 | <Mathieu Hofman> | I thought that static analyzability of module exports was one of the main point of ESM? Are you saying you want to import.defer other module types where export names are not known ahead of time? |
05:49 | <Ashley Claymore> | Tools like Babel will transform ESM to CommonJS one module at a time, without that global info |
05:50 | <Ashley Claymore> | it's doable, but adds complexity to tooling. Dropping import.defer is a solution that reduces complexity instead of moving it. |
06:50 | <rbuckton> | bigint could never have been JSSugar due to operator overloading. Neither could decimal as a primitive. |
06:50 | <nicolo-ribaudo> | Unless we introduce escaped operators like "a \+ b" that desugars to a.add(b) :) |
06:51 | <Ashley Claymore> | beyond operator overloading, it's AO impacting. new primitives change the core AOs of the language |
06:52 | <shu> | absent type-driven stuff, you can be like ocaml and have +. |
06:54 | <Justin Ridgewell> | I was discussing with Yulia last night that you could import + from ‘js:operators’ , and have that perform the left + right -> left.add(right) change |
06:54 | <yulia> | 👀 what happened in shibuya should stay in shibuya (for now) |
06:54 | <yulia> | or in TDZ |
06:54 | <Justin Ridgewell> | Requires coordination from the “core”, but we could then add new number types pretty easily |
06:55 | <yulia> | until we have something more concrete at least. context: this needs a lot more thought before we consider it as a serious proposal |
06:55 | <Chengzhong Wu> | I was discussing with Yulia last night that you could |
06:55 | <yulia> | also i had. lot of drinks |
06:56 | <Justin Ridgewell> | It wouldn’t be checked per operand types. Import + , and now all + in the file are left.add(right) |
06:56 | <yulia> | but yea ast rewriting, ill talk about it when my thing comes up |
06:58 | <nicolo-ribaudo> | but yea ast rewriting, ill talk about it when my thing comes up |
06:58 | <yulia> | if you haven't read rewriting the technical interview you really should, but thats a digression |
06:58 | <Chris de Almeida> | what I am trying to say is I want to date JSSugar before marrying. thank you Ashley for helping to clarify my intent there |
06:59 | <yulia> | Chris de Almeida: you've been dating for years |
06:59 | <jkup> | if you haven't read rewriting the technical interview you really should, but thats a digression |
06:59 | <Chris de Almeida> | but surely there is some delta from our current process that we could PoC |
07:00 | <Chris de Almeida> | for example maybe a proposal that would involve a split, or could involve a split |
07:01 | <Chris de Almeida> | but if the response is that it's already so close to what we do, per what Shu was saying, then that's fine |
07:01 | <yulia> | concretely I could see the following: new syntax for JSSugar gets the following restrictions
And, with this, we say that new syntax has a wait time of at least 3 years before landing in browsers |
07:08 | <ljharb> | couldn't we say that right now, for syntax stage 2.7 features that they need 3 years (as usable transpilations) before being eligible for stage 3? (ie, without any sugar/core/js0 stuff) |
07:09 | <shu> | no, because then people might not ever adopt it at scale and we never get a meaningful signal |
07:09 | <shu> | it's not baking time with committee that's needed |
07:09 | <shu> | it's baking time with the world |
07:09 | <yulia> | yeah it should be considered finished |
07:11 | <Justin Ridgewell> | Someone is attributuing @justingrant's comments on JS0 to me in the notes |
07:11 | <Justin Ridgewell> | Please use JGT for Justin Grant |
07:12 | <jkup> | Does JSSugar open doors for a "blessed" type system? Or rather, would type annotations likely become a JSSugar feature? |
07:13 | <justingrant> | Someone is attributuing @justingrant's comments on JS0 to me in the notes |
07:13 | <Justin Ridgewell> | Maybe because I forgot to add myself (JGT) to the attendees list in the notes? I'll fix that now. Want me to fix up the notes too? |
07:14 | <jkup> | Also curious if sugar files would get their own file extension? |
07:14 | <jkup> | Like how would I know an npm package is sugar or is able to be run directly? |
07:14 | <Justin Ridgewell> | Does JSSugar open doors for a "blessed" type system? Or rather, would type annotations likely become a JSSugar feature? |
07:15 | <Ashley Claymore> | index.js🍭 |
07:15 | <jkup> | ok well i was worried but now i'm excited |
07:15 | <Ashley Claymore> | something something package.json |
07:15 | <shu> | Does JSSugar open doors for a "blessed" type system? Or rather, would type annotations likely become a JSSugar feature? |
07:15 | <jkup> | {"sugar": "yesplease"} |
07:16 | <shu> | good luck designing, getting consensus, and getting people to adopt given TS :) |
07:16 | <ljharb> | yes they would need one, theyre a different parse goal. |
07:16 | <Rob Palmer> | (replying to Justin) I'm not sure that's true. Of the two motivations for Type Annotations, it doesn't really change the need for coordination. |
07:16 | <Ashley Claymore> | which file systems allow emoji in file names? |
07:16 | <Ashley Claymore> | DOS? |
07:16 | <Michael Ficarra> | which file systems allow emoji in file names? |
07:17 | <Michael Ficarra> | DOS? |
07:18 | <littledan> | Rbuckton: Were those stats for current decorators or a previous version? |
07:18 | <Ashley Claymore> | I meant FATTTTT :(((( |
07:18 | <rbuckton> | comparing current to experimental |
07:19 | <rbuckton> | https://github.com/microsoft/TypeScript/issues/55688 |
07:19 | <jkup> | I think I agree with ljharb that it should get an extension... but then I go back to my other question. I'm not sure how to tell people "This is sugar" or "This is JS0". |
07:20 | <Michael Ficarra> | I meant FATTTTT :(((( |
07:20 | <jkup> | Unless we just really try to push for "Only publish JS0" |
07:20 | <ljharb> | the file extension tells them, just like .js and .mjs do (should) now |
07:20 | <ljharb> | but yeah "only publish js0" is what everyone would do |
07:20 | <Ashley Claymore> | we should have a new file extension for each spec version |
07:21 | <Ashley Claymore> | as each is a different parse goal |
07:21 | <Ashley Claymore> | index.es2021 |
07:21 | <Ashley Claymore> | when I refactor my code and it no longer has newer syntax I rename it to index.es2017 |
07:22 | <jkup> | just picturing your PR reviews |
07:22 | <Michael Ficarra> |
|
07:24 | <jkup> | I can see healthy discussions where engines ask "Can this go in JSSugar?" and then tooling authors come back and say "This would result in way too much bundle bloat" |
07:25 | <yulia> | restricting things to ast transform would reduce complexity. right now you have free reign in what you can do, and that can introduce new bytecode operations etc. if its an AST transform, it is quite literally sugar as it can be rewritten |
07:26 | <ljharb> | would that as a constraint remove the need for jssugar? |
07:27 | <yulia> | So again, mozilla isn't strictly supporting JSSugar as the solution here, we are co-signers of the problem |
07:27 | <yulia> | but if something is a pure ast transform than that only touches the tokenizer and the parser. it is simpler than a full engine implementation |
07:27 | <shu> | i'm hearing the tooling authors here loudly say "it's also bad for us" |
07:28 | <shu> | i want to reiterate the implication from that isn't "engines need to do it" |
07:28 | <shu> | the implication from that is we are designing features wrong (for performance) |
07:28 | <yulia> | I don't want to say yes (to not derail the conversation, as we still have more to figure out here), but certain proposals currently in the pipeline that are not AST transforms (introducing custom behavior) would be significantly simpler if they were; for example explicit resource management |
07:31 | <Aki> | rbuckton: do y'all collect analytics on targets? |
07:31 | <rbuckton> | I'd have to get back to you on that |
07:33 | <littledan> | Have we nailed down the details for which features have which cost? Seems like we should study this more and see what is possible to change, though the response to Shu’s tdz effort was disappointing |
07:33 | <Rob Palmer> | Side note: Do we know which old features are slow? I only know of the TDZ issue. We run most of our production code using very modern untranspiled ES2023/ES2024. Performance has not been problematic, and is obviously is much faster than if we downlevelled private field usage or async usage. |
07:33 | <shu> | classes and TDZ are the most prominent ones |
07:34 | <littledan> | classes and TDZ are the most prominent ones |
07:34 | <Rob Palmer> | Profiling classes is my hobby. I have not seen any lingering issues. |
07:34 | <littledan> | Profiling classes is my hobby. I have not seen any lingering issues. |
07:34 | <shu> | How much slower are classes these days, after those optimizations you mentioned? |
07:34 | <littledan> | gotta ask a more specific question |
07:35 | <Marja Hölttä> | when i was looking into it, i noticed that one thing classes can't do is omitting super ctors. some tools, when they notice the super ctor doesn't do anything interesting, just omit it when doing old-style classes. or they inline the super ctor workload into the subclass ctor and then omit it. |
07:36 | <Marja Hölttä> | i optimized it a bit in v8, omitting trivial ctors, but it's still not as good as the oldschool version iirc. |
07:36 | <Ashley Claymore> | So potentially it's for deeper class hierarchies where the issues become more measurable? |
07:37 | <rbuckton> | In principle, implementers could also implement AST transforms in the runtime. |
07:37 | <Marja Hölttä> | before i optimized it, the problem was pretty visible even for shallow class hiearchies (since 1 call is so much more than 0 calls) |
07:38 | <Ashley Claymore> |
I assume these are very close in performance these days? Assuming |
07:39 | <Ashley Claymore> |
Good point!! |
07:40 | <yulia> | yeah this is a side bar that we've been discussing. But if it expands to a massive subtree that would potentially be a problem. We should go through the full exercise of JSSugar first before we start talking about this part |
07:40 | <shu> | perhaps i was being too coy |
07:40 | <hax (HE Shi-Jun)> |
function OldSkol() { return {field: 1} } ? (I'm not sure) |
07:40 | <shu> | i was referring to TS, littledan |
07:41 | <yulia> | I mean, this is also about how we are defining syntax right now |
07:42 | <Marja Hölttä> | i don't have the current numbers but i can look into it |
07:43 | <Marja Hölttä> | probably that case should be on par |
07:43 | <Marja Hölttä> | at least it would be less surprising |
07:44 | <Marja Hölttä> | another class topic: private fields vs just normal fields |
07:44 | <Marja Hölttä> | idk the exact overhead but i assume it's non-zero |
07:44 | <Ashley Claymore> | Maybe the
|
07:45 | <rbuckton> | If a goal of JSSugar is for runtimes to look at desugared syntax to determine whether it is something to optimize, is there a reason runtimes aren't already doing this? |
07:45 | <Ashley Claymore> | I think that used to be faster, in the past |
07:45 | <shu> | wait, where was that a goal |
07:45 | <shu> | (and we are already doing this, we try to see patterns that common frameworks and other popular libs use) |
07:45 | <rbuckton> | Maybe not a goal, but you just made that statement two minutes ago |
07:45 | <shu> | i don't remember making that formulation |
07:46 | <shu> | but in any case, we do do this |
07:46 | <yulia> | we are doing this by default for all features, so anything that compiles down to current JS is being targeted |
07:46 | <yulia> | because again, JS0 = current js |
07:50 | <keith_miller> | I recall one of places where classes were slow for no apparent benefit was empty constructors invoke the iterator protocol on arguments to forward them so you can't elide the call without a lot of optimizations. But maybe I'm misremembering that? |
07:50 | <Justin Ridgewell> | We fixed that |
07:51 | <shu> | i think we managed to fix that for default constructor |
07:51 | <shu> | the point marja was talking about is the this TDZ basically |
07:51 | <shu> | super() must be there |
07:51 | <shu> | this is not true for ES5-style classes, so Closure can just straight up elide it |
07:51 | <keith_miller> | Ah right ok |
07:52 | <Andrew Paprocki> | Side note: Do we know which old features are slow? I only know of the TDZ issue. We run most of our production code using very modern untranspiled ES2023/ES2024. Performance has not been problematic, and is obviously is much faster than if we downlevelled private field usage or async usage. |
07:52 | <shu> | we didn't fix that if you typed super(...arguments) in your constructor though |
07:53 | <rbuckton> | no this before super() is important to maintain expectations about superclass state. The fact you can run any statements before super() is perhaps a failing of the class syntax. |
07:53 | <shu> | right |
07:53 | <shu> | and we've chatted about this before, but we should have designed it to be more static so the elision optiimzation can still apply |
07:53 | <shu> | while maintaining that guardrail |
07:53 | <shu> | not the dynamic thing we have for ES6 classes |
07:54 | <Andrew Paprocki> | and we've chatted about this before, but we should have designed it to be more static so the elision optiimzation can still apply |
07:54 | <shu> | no, the super() can't be elided thing is actually directly shown by a transpiler optimization that can no longer apply to ES6 classes that used to apply to ES5 classes |
07:55 | <rbuckton> | The fact you can forget to invoke the superclass constructor in an ES5-style class is a huge footgun, even if it is more performant. |
07:55 | <keith_miller> | !super() :P |
07:56 | <rbuckton> | no, the constructor() { super(); ... } , not in the possibility that the runtime might be able to optimize away a super() as the first statement? |
07:57 | <rbuckton> | IMO, we should have had something like constructor() : super() { } akin to C++ or C# |
07:57 | <rbuckton> | Where the absence of : super() implies you're invoking the superclass constructor with no arguments. |
08:01 | <rbuckton> | early prototypes of TypeScript experimented with a class syntax like class C(a, b) { } prior to the actual class syntax being standardized, which combined the constructor with the class name. C# actually has that now too. |
08:02 | <nicolo-ribaudo> | Omitting I'd be curious to see though if a Babel-transpiled subclass constructor is indeed faster than the same code running natively. |
08:02 | <nicolo-ribaudo> | Not comparing with "how would people write the class if it was ES5" |
08:02 | <nicolo-ribaudo> | But with what Babel actually emits |
08:02 | <rbuckton> | In C# you can now write
|
08:04 | <rbuckton> | which is akin to writing
|
08:04 | <nicolo-ribaudo> |
|
08:05 | <rbuckton> | We could always introduce slight alternatives to the class syntax that would make super() invocation implied, such as class Sub(a, b) extends Super() {} |
08:13 | <rbuckton> | (I'm not advocating for that specific syntax, just that its conceivable that we could do something of that nature) |
08:23 | <rbuckton> | when i was looking into it, i noticed that one thing classes can't do is omitting super ctors. some tools, when they notice the super ctor doesn't do anything interesting, just omit it when doing old-style classes. or they inline the super ctor workload into the subclass ctor and then omit it. Object.setPrototypeOf . IMO, one of many problems with class design is that it was allowed to be too dynamic. |
08:43 | <hax (HE Shi-Jun)> | early prototypes of TypeScript experimented with a class syntax like |
08:44 | <nicolo-ribaudo> | Could structs just be "class V2"? Is there any good reason to use classes if we get structs? (assuming that they'll support private state) |
08:47 | <hax (HE Shi-Jun)> | Yeah, it seems current struct proposal is very like class V2 (though shared struct look like a very different thing) |
08:54 | <shu> | Could structs just be "class V2"? Is there any good reason to use classes if we get structs? (assuming that they'll support private state) struct ? or the messaging? |
08:54 | <shu> | i feel like the only compelling reason to use classes is expandos? |
08:55 | <shu> | mixins maybe |
08:58 | <nicolo-ribaudo> | what's the concrete thing you're thinking of? a different keyword than |
08:58 | <nicolo-ribaudo> | And like, lint rules saying "use a struct here" |
08:59 | <nicolo-ribaudo> | Similarly to how the ecosystem migrated (at least, for hand-authored code) from var to let |
09:29 | <littledan> | We could always introduce slight alternatives to the this : should references to an and b be spelled as this.a or just a ? If bare, does it follow lexical scoping semantics or this semantics? |
09:30 | <littledan> | It would certainly bare an interesting analogy to Swift, where structs are preferred over classes (but the semantics are completely different!) |
09:31 | <littledan> | This is difficult to square with |
11:33 | <Marja Hölttä (not here, use marja@google.com)> | rbuckton: the "superclass" can also change in ES5; the tools which were inlining the ctors were also assuming that the superclass won't change, because the program they're optimizing is well-behaved like that |
11:34 | <Marja Hölttä (not here, use marja@google.com)> | (they also straight up didn't inline in the ES6 version which is their problem, not our problem) |
11:37 | <Marja Hölttä (not here, use marja@google.com)> | but definitely, one problem was that the tools were making these assumptions and optimizing based on that, but as an engine we need to be prepared for everything being maximally dynamic, and weird things happening |
11:37 | <littledan> | IMO, we should have had something like |
11:40 | <littledan> | idk the exact overhead but i assume it's non-zero |
11:42 | <littledan> | i was referring to TS, littledan |
11:45 | <littledan> | restricting things to ast transform would reduce complexity. right now you have free reign in what you can do, and that can introduce new bytecode operations etc. if its an AST transform, it is quite literally sugar as it can be rewritten |
11:47 | <littledan> | good luck designing, getting consensus, and getting people to adopt given TS :) |
11:49 | <littledan> | it's baking time with the world |
11:53 | <littledan> | can you elaborate? not familiar with the wasm usecase so well, so i don't know how import.defer solves this better than import source + import() |
11:55 | <littledan> | Why would we expect the cost to be different in JSSugar vs this expansion? |
11:57 | <littledan> | But the custom code for extractors is much more direct than that of destructuring iterators |
11:58 | <littledan> | Splitting the proposal in two and shipping the browser part means we make less progress on the “let it bake before shipping” front. |
11:59 | <littledan> | Yes I like your 14 day goal, let’s see if we can change policy here. |
12:01 | <littledan> | So, how should we understand how bad this is? Is the length of the bytecode sufficient reason that we shouldn’t add such a feature to JSSugar even? |
12:27 | <yulia> | Ah got it |
12:28 | <yulia> | Ok so that is more of a use case I can understand |
12:29 | <yulia> | Let’s maybe talk about it next week, I need to better understand which options we would shut out if we do not do import.defer now |
13:31 | <littledan> | Overall I won’t be heartbroken if we shut out that possibility. There are lots of ways that the functionality could be recovered. But it is a coherent use case. |
17:50 | <Mathieu Hofman> | I'm worried that shutting off import.defer does not allow us to re-introduce it later unless we do resolve what deferred exactly implies, which caused this problem in the first place. I was honestly surprised that import defer had lazy eval on any ns property get, even if that property isn't a known export. I had assumed since the beginning the lazy eval was only triggered on access of known exports. I understand that the latter requires fetching and parsing exports of the module, but I always assumed that what the goal of this proposal, and it didn't intend to support deferred parsing as well. |
18:11 | <Ashley Claymore> | We could do `import.defer` later but it would have to either be a 3rd type of namespace different from the one returned by the static import. Or it would resolve to a wrapper object around the namespace. Or maybe there would be some other API all together. So door wouldn't be completely closed |
23:10 | <shu> | i expect this to work exactly the same way as it does today (i.e. tools releasing support for stage 3 features earlier than browsers), and then we see uptake (or not). the biggest difference i heard and agree with is if transpilation is expected to be permanent, then people might not adopt it for reasons like "slow". for those kind of features, which i suspect is rarer, indeed the feedback loop with performance (now tool codegen performance) is very similar to that of browsers. but i don't really quite get why that's such a zinger. i mean, yeah, it's a maintenance cost! that's why browsers don't wanna do it, for the reason of great cost to the users if the tools, for those features, decide they also don't want to shoulder the cost, then as i keep repeating, it does not follow from that that browsers continue to shoulder the cost. it follows from that that we aren't designing features right, or it's a feature that we shouldn't have |
23:12 | <shu> | but my thesis is that the cost to tools has a smaller blast radius, and is lower than in browsers |
23:12 | <shu> | the counterargument i heard to that was "tools are volunteer projects" |
23:13 | <shu> | i wish they were better funded too and it's a structural issue the ecosystem needs to solve with incentives, not TC39, but it also doesn't follow from that fact that browsers need to do it |
23:25 | <Anthony Bullard> | Maybe tools should start compiling to optimized byte code /s |
23:25 | <Jack Works> | Is it a real production or just toy project? it's real. some library requires async initialization. if you import (or require) it synchronously, you'll need to await init() to make it work (no TLA because of cjs). adding unthenable to all module namespaces will break this, but I don't think those packages are widely adopted via native esmodule |
23:40 | <ptomato> | i wish they were better funded too and it's a structural issue the ecosystem needs to solve with incentives, not TC39, but it also doesn't follow from that fact that browsers need to do it |
23:50 | rkirsling | imagines a game-theoretic presentation on the power structures of the web, and the subsequent social media implosion |