01:28 | <rkirsling> | hmm, I will likely be absent during the R&T timeblock; here's hoping discussion about toString doesn't get too heated |
01:33 | <rkirsling> | (or maybe we're beyond that now?) |
01:41 | <rkirsling> | also, anytime folks are looking for a JSC logo for slides: we do have a mascot called Squirrelfish đ https://webkit.org/wp-content/themes/webkit/images/squirrelfish-lives.svg |
08:36 | <Rob Palmer> | good morning, all |
08:37 | <Rob Palmer> | Thanks to Luca we've made some minor schedule adjustments to better accommodate folks' time constraints |
08:44 | <Rob Palmer> | This means we have Record & Tuple in the first morning session today, and have pushed out Intl.DurationFormat & LibJS to tomorrow. This makes way for Guy's topics (Import Reflection, Defer Eval) at the end of today. |
08:47 | <Alex Vincent> | Rob Palmer: I've come to realize my time constraint no longer holds. I'm still in the overflow section, but if a slot opens up, please ignore my posted constraint. |
08:48 | <Rob Palmer> | Thanks for the update. We will strive to bring overflow items in, as and when extra time frees up. |
08:52 | <Rob Palmer> | The Google Meet room is up. Please join us. We will begin in 7 minutes. |
08:52 | <bakkot> | Rob Palmer and other chairs: for my item (Set methods) I want to have the option of using the full 45 minute time box if it's needed, but I'm hoping that it ends up being uncontroversial, in which case it might be as short as 10 minutes |
09:02 | <Rob Palmer> | Thanks bakkot I have tagged it as such. |
09:04 | <Michael Ficarra> | oooohhh I like this history slide a lot |
09:04 | <Michael Ficarra> | definitely going to steal that for my proposal slides from now on |
09:05 | <Ashley Claymore> | oooohhh I like this history slide a lot |
09:05 | <Michael Ficarra> | if you can fit it all on one slide, I'll be impressed |
09:06 | <littledan> | It would be surprising if Node and Deno really continue to not support this when Chrome does |
09:11 | <Rob Palmer> | Hey all, as Michael says, please ensure your attendance is logged in the Notes doc. |
09:11 | <Rob Palmer> | (I deleted the URL because we link everything from the main Reflector post) |
09:11 | <Rob Palmer> | (I deleted Michael Ficarra's comment accidentally) |
09:14 | <Luca Casonato> | It would be surprising if Node and Deno really continue to not support this when Chrome does |
09:15 | <Michael Ficarra> | Rob Palmer: that was Saboff, not me |
09:15 | <ryzokuken> | (I deleted Michael Ficarra's comment accidentally) |
09:16 | <Michael Ficarra> | oohhh I see |
09:16 | <Michael Ficarra> | too early |
09:24 | <bakkot> | for the notes, who is speaking other than frank? |
09:24 | <Ashley Claymore> | MAH |
09:27 | <ryzokuken> | given how many ongoing API proposals could benefit from R&T, shouldn't we be really prioritizing it? |
09:28 | <ryzokuken> | like... ideally every single Intl constructor should take a record options bag |
09:33 | <HE Shi-Jun> | The problem is how long we need to wait for r&t đ |
09:33 | <bakkot> | I don't think we should start making APIs return records and tuples even when their result is immutable, as convenient as it is |
09:33 | <bakkot> | everything else is already objects |
09:34 | <HE Shi-Jun> | So we add r&t but our APIs do not use it, only userland use it? |
09:34 | <shu> | i'm not even convinced that the different identity thing is that big a problem |
09:34 | <shu> | caching is good for this, function is good for this |
09:34 | <bakkot> |
yeah basically |
10:05 | <bakkot> | wait temporal has non-symmetric equality |
10:05 | <bakkot> | I had not realized that |
10:06 | <bakkot> | seems... not great? |
10:07 | <shu> | really? |
10:07 | <shu> | how can it not be symmetric...? |
10:07 | <bakkot> | that was the claim made in this presentation |
10:07 | <bakkot> | not literal === equality but equality methods |
10:08 | <Kris Kowal> | Or as etymologists would call it, anametric equality. |
10:09 | <Alex Vincent> | page 16 of the notes for the transcript where this was mentioned |
10:13 | <yulia> | could we take a short break before getting into the queue Rob Palmer ryzokuken |
10:14 | <Rob Palmer> | yes, we'll do a 10 min intermission as soon as Ashley finishes the presentation part |
10:15 | <Michael Ficarra> | "ecosystem challenges" and "subtlety" are way too hand-wavey for me to understand what is meant |
10:15 | <Michael Ficarra> | like what is the concrete thing that those objections refer to? |
10:16 | <shu> | i have thoughts but my brain |
10:16 | <shu> | so slow |
10:16 | <shu> | does not bode well for tomorrow |
10:30 | <ryzokuken> | not literal |
10:30 | <ryzokuken> | it's the compare methods |
10:30 | <ryzokuken> | basically, since compare accepts plain objects, any superset temporal instances could work as long as they're the argument |
10:31 | <ryzokuken> | but if the receiver is the superset, it won't work |
10:31 | <ryzokuken> | (because it will lack certain properties) |
10:31 | <ryzokuken> | actually, nvm me, the compare methods are static |
10:32 | <ryzokuken> | so basically as long as the arguments are of types which are supersets of the type whose compare function is called, it will work |
10:35 | <littledan> | Note, in Romance languages, discuss means argue against, so I think Patrick meant we donât argue against the goal of immutability |
10:37 | <jasew> | nicolo-ribaudo: we struggle to hear yulia on this side of the room |
10:41 | <rbuckton> | I've long been in favor of the introduction of user-defined value types, and it was one of my goals for structs |
10:42 | <rbuckton> | IIRC, equality has always been a top-level goal? |
10:44 | <ryzokuken> | another quick reminder, I've settled on a better workflow to admit people into the call ASAP but please feel free to ping me here if you're waiting to be allowed in since Meet doesn't notify me about people waiting to be admitted. |
10:44 | <nicolo-ribaudo> | IIRC, equality has always been a top-level goal? |
10:44 | <rbuckton> | I've long been in favor of the introduction of user-defined value types, and it was one of my goals for structs #[] and #{} as essentially being to value types the equivalent of [] and {} to reference types, though with the added property of immutability. |
10:45 | <rbuckton> | If struct had come before R&T, I would have pushed more for R&T to be designed in terms of structs. |
10:47 | <bakkot> | fwiw I think there's probably a way to get maps and sets which support multiple keys without going full user-defined equality |
10:47 | <rbuckton> | What I wanted was struct + value types + operator overloading, with flexibility in struct to support mutability/immutability and shareability/transferability/copiability. |
10:47 | <bakkot> | there was even a proposal for that |
10:47 | <Ashley Claymore> | rekey + compositekey |
10:48 | <bakkot> | and we might want that even in a world with R&T given that sometimes you want to key off of objects |
10:48 | <shu> | i don't see a realistic path in doing value types with operator overloading |
10:48 | <bakkot> | though I guess symbols as weakmap keys make that less necessary |
10:48 | <shu> | (for performance) |
10:50 | <rbuckton> | I've been considering proposing customizable equality/hashing for Map/Set and built-in support for hash code/identity hash acquisition for several years now. |
10:50 | <rbuckton> | I'm less interested in multi-key maps, and more interested in creating a Map<URL, ...> or Map<Point, ...> , etc. |
10:51 | <yulia> | I think when we drop equality, the argument for value types is weaker |
10:51 | <Alex Vincent> | I am very interested in multi-key maps... |
10:51 | <nicolo-ribaudo> | I think when we drop equality, the argument for value types is weaker |
10:52 | <yulia> | there is also the realms behavior that benefits, but that can be solved in a way similar to shared structs |
10:52 | <HE Shi-Jun> | I don't understand op overloading argument, I remember op overloading proposal do not allow overload === ? |
10:52 | <rbuckton> | I am very interested in multi-key maps... |
10:52 | <pipobscure> | Without === there is little value add; as in just use immutable.js and be done with it. |
10:52 | <yulia> | Operator overloading here is not user defined |
10:53 | <littledan> | I think when we drop equality, the argument for value types is weaker |
10:53 | <Andreu Botella> | That's not really operator overloading then, right? It's just (in theory, regardless of implementation) value types with a === that makes sense for the type |
10:54 | <HE Shi-Jun> | Operator overloading here is not user defined |
10:55 | <littledan> | Without === there is little value add; as in just use immutable.js and be done with it. |
10:55 | <nicolo-ribaudo> | but === already be overloaded by different primitive types and objects? |
10:57 | <bakkot> | i still think we should explore making Array.prototype and Object.prototype reject numeric properties |
10:57 | <HE Shi-Jun> | I guess it depends on how you see R&T. If you say "R&T are like objects", then giving them a different equality feels different from how other primitives have their own equality |
10:57 | <nicolo-ribaudo> | Implementation complexity |
10:58 | <HE Shi-Jun> | so I don't fully understand that, i just feel R&T is just another primitive and their equal operation. |
10:59 | <nicolo-ribaudo> | shu: What does AI mean? I assume you are not proposing we should let artificial intelligence design the proposal |
11:00 | <shu> | sorry, "Action Item" |
11:00 | <HE Shi-Jun> | Anyway, we have many use cases of deep equality, so without that we just throw the heavy tasks to developers. |
11:07 | <ryzokuken> | I wonder if we'd benefit from some design principles, perhaps as invariants. |
11:07 | <ryzokuken> | Something like https://www.w3.org/TR/html-design-principles/#priority-of-constituencies |
11:07 | <ryzokuken> | it's unclear what the priority is here |
11:08 | <Alex Vincent> | rbuckton: ok - I wasn't offering a critique, just a statement of my interest in multi-key maps. đ |
11:08 | <HE Shi-Jun> | The real problem is who can represent developers. |
11:08 | <ryzokuken> | that's a problem indeed |
11:08 | <Rob Palmer> | we resume at the top of the hour 1pm local time, which is in 52mins |
11:08 | <ryzokuken> | but even in the presence of a representative, do we care? |
11:09 | <rbuckton> | littledan: I've been thinking about the "dynamic comparison in Map/Set" thing for awhile, and started working on a draft of a proposal awhile ago. |
11:09 | <nicolo-ribaudo> | The real problem is who can represent developers. |
11:09 | <rbuckton> | littledan: I've been thinking about the "dynamic comparison in Map/Set" thing for awhile, and started working on a draft of a proposal awhile ago. |
11:10 | <HE Shi-Jun> | We have many delegates that are JavaScript developers and not just standard/engine engineers |
11:10 | <waldemar> | I don't quite understand what alternative Yulia has in mind, and I'd like to know what it is. |
11:12 | <rbuckton> | Plus something like Equaler would have value in other APIs like .includes and .groupByToMap |
11:27 | <littledan> | I don't quite understand what alternative Yulia has in mind, and I'd like to know what it is. |
11:27 | <littledan> | https://gist.github.com/rbuckton/f8c2ac278b796324a06410e59c56eb10 (4 years old at this point) |
11:29 | <rbuckton> | Thanks for sharing this! |
11:55 | <yulia> | I was cryptic in my "i don't have much time" -- I'm not dying but ill be taking a break in march. We have some great folks from mozilla taking over though |
11:56 | <yulia> | I don't quite understand what alternative Yulia has in mind, and I'd like to know what it is. |
11:58 | <littledan> | I don't have 100% a full solution, I would like to see an investigation of building this on top of shared structs or a clear problem statement. so far it is usually a compound description of the constraints that lead us to a primitive, but many of them are issues i see more broadly in the language and i think would be beneficial if expanded |
11:58 | <littledan> | The presentation had a slide shown twice with three high-level goals, and went into detail about how they are related |
11:59 | <Rob Palmer> | We are restarting plenary in 1 minute. |
11:59 | <shu> | Ashley Claymore shared with me an sketch of building on top of shared structs, could you also share it with yulia if you didn't already? |
12:00 | <littledan> | Fwiw here is another gist around an alternative, trying to draw out how there really is a spectrum of options https://gist.github.com/littledan/4b9c797f3e70d3531fcf32decc6e9754 |
12:00 | <littledan> | Fwiw here is another gist around an alternative, trying to draw out how there really is a spectrum of options https://gist.github.com/littledan/4b9c797f3e70d3531fcf32decc6e9754 |
12:01 | <yulia> | I think i outlined a couple of things that might work? and also the conditions that would resolve our concerns. I am not sure what you are asking |
12:01 | <littledan> | (There arenât all that many observable properties that you derive from trying to align with shared structs. Seems like typeof, ===, not sure what else) |
12:01 | <yulia> | its another thing if you don't like the solution, I still consider them valid and the implementer concerns are significant. I wouldn't bring this up otherwise |
12:01 | <Rob Palmer> | Thanks to Ashley and Linus and Andreu for note taking! |
12:02 | <littledan> | I think i outlined a couple of things that might work? and also the conditions that would resolve our concerns. I am not sure what you are asking |
12:03 | <yulia> | right and what I said was that the goals that are being addressed are broader issues within the language. they are not limited to just value types |
12:04 | <littledan> | its another thing if you don't like the solution, I still consider them valid and the implementer concerns are significant. I wouldn't bring this up otherwise |
12:05 | <yulia> | yes, thank you for doing that, and i was sort of referencing it because I know this isn't the ideal version of the proposal as you see it. I just think it should be seriously considered |
12:05 | <yulia> | for now, id like to focus on the module layer zero proposal and we can come back to this, but i think we are pretty much on the same page in terms of where things are right now |
12:05 | <littledan> | Maybe next time we discuss R&T we should go over various options in more detail to discuss pros and cons |
12:06 | <yulia> | In part the goal today was to also bring the concerns we have already discussed among champions and implementers to the broader committee, so we are sort of going over ground a second time -- what I am saying now is not substantially different from our prior meetings |
12:06 | <yulia> | just to clarify, in case it seemed like i was asking for something new |
12:07 | <littledan> | In part the goal today was to also bring the concerns we have already discussed among champions and implementers to the broader committee, so we are sort of going over ground a second time -- what I am saying now is not substantially different from our prior meetings |
12:19 | <yulia> | what does "kicker" mean here? |
12:21 | <Mathieu Hofman> | though I guess symbols as weakmap keys make that less necessary |
12:22 | <nicolo-ribaudo> | what does "kicker" mean here? |
12:23 | <yulia> | thanks |
12:23 | <Mathieu Hofman> | I'm not saying I have no interest, but overriding equality/hash for Map/Set is a much higher priority to me. |
12:25 | <eemeli> | As discussed earlier today re
|
12:26 | <Michael Ficarra> | module source is no more of a new form of eval than importing a data URI which you can do today |
12:26 | <nicolo-ribaudo> |
new Module(src).source === src |
12:28 | <ljharb> | Kris Kowal: re the queue, can you help me understand the use cases for having ModuleSource instead of just passing a string to Module? |
12:28 | <Luca Casonato> | shu: Yes, the import hook is shallow |
12:28 | <rbuckton> | Equality semantics aren't necessarily controlled by the target key, but by the provided Equaler . The gist from 4 years ago is a little weaker in that regard, and so is the @esfx/equatable implementation I mentioned earlier. "rekey" assumes you can convert the key into something with an equivalent identity but that can significantly increase the complexity of user code (i.e., needing to introduce a WeakMap/FinalizationRegistry and roll your own identity generation). Equality and hashing is often easier and generally only involves math and a built-in mechanism to acquire an identity hash for objects. |
12:28 | <shu> | Luca Casonato: okay, just to make sure i understand |
12:29 | <rbuckton> | The Equaler approach also mirrors what many implementations are already doing internally. |
12:29 | <shu> | Luca Casonato: to have it be deep, the importhook itself needs to return Module instances that are themselves passed the import hook |
12:29 | <Luca Casonato> | yes |
12:30 | <Michael Ficarra> | bakkot: it's not a new kind of eval, import is the evaluator here |
12:31 | <bakkot> | it's a new kind of eval, you can't use dynamic eval to evaluate an arbitrary string |
12:31 | <nicolo-ribaudo> | Can we try giving 1 minute each for the replies to this topic? |
12:32 | <Michael Ficarra> | bakkot: data URIs |
12:32 | <Luca Casonato> | and blob urls |
12:32 | <bakkot> | those aren't in 262 and have different CSP rules than eval does |
12:33 | <rbuckton> | it's a new kind of eval, you can't use dynamic eval to evaluate an arbitrary string |
12:33 | <bakkot> | and also just because it's possible to use something obscure to accomplish a thing does not mean that we should be providing a first class way of doing it |
12:36 | <ljharb> | imo Module is the same as Function and friends |
12:36 | <Luca Casonato> | bakkot: Are you opposed to dynamic instantiation of module instances in general, or only from arbitrary text? |
12:36 | <ljharb> | it's a constructor to create invokeable code you can pass around. so far, all of those take a string of source |
12:36 | <bakkot> | Luca Casonato: I don't know what "dynamic instantiation" means if not "from arbitrary text" |
12:36 | <bakkot> | but it's the "arbitrary text" I have a problem with, yes |
12:36 | <ljharb> | nobody objected to AsyncFunction etc taking a string, why would Module not? |
12:37 | <bakkot> | Function already existed, AsyncFunction is not that different from it |
12:37 | <Luca Casonato> | import reflection: import module foo from "./foo.js"; await import(foo) |
12:37 | <bakkot> | Module is quite different |
12:37 | <bakkot> | Luca Casonato: totally fine with that |
12:37 | <ljharb> | as dan said on the queue, i can eval(`module { ${source} }`) anyways, how is that different from passing source in directly? |
12:38 | <bakkot> | everyone knows eval is evil |
12:38 | <bakkot> | "I can already do this by using eval " is not a reason to add a feature |
12:38 | <littledan> | as dan said on the queue, i can |
12:38 | <littledan> | Not just through CSP but by deleting the property |
12:38 | <ljharb> | oh sure in this case i meant "via ModuleSource" |
12:39 | <ljharb> | (i don't think it's clear that deniability is a sufficient motivation to create an entire class, but that's a separate discussion) |
12:39 | <littledan> | I share bakkotâs concern generically and was persuaded by the eval injection risk |
12:40 | <Luca Casonato> | bakkot: are you ok with:
|
12:40 | <rbuckton> | Though you will now also need to deny ModuleSource , since await import(new Module(new ModuleSource(code))) is just indirect eval. |
12:40 | <bakkot> | Luca Casonato: assuming foo.source is opaque, yes, I think so |
12:41 | <Luca Casonato> | Luca Casonato: assuming foo.source is a ModuleSource instance. There is no access to the module source text. |
12:42 | <bakkot> | though, I should say, I also don't understand the need for that |
12:42 | <littledan> | though, I should say, I also don't understand the need for that |
12:43 | <bakkot> | yeah, the testing case is interesting, but not compelling to me on its own |
12:43 | <bakkot> | I am very reluctant to add features which are only motivated by testing |
12:44 | <ljharb> | what about feature-detection? like "is TLA supported" |
12:44 | <yulia> | im sort of swayed by hot reloading as a use case, in particular having no-reload updates |
12:44 | <rbuckton> | I find the testing case compelling, but there are potential issues there as well. If you can't remove modules from the module cache, re-importing the same module with different dependencies in a test runner will just continuously grow the module cache until you OOM. |
12:44 | <yulia> | so, similar to erlang behavior for swapping out running code is something i sometimes wistfully think about. |
12:44 | <Luca Casonato> | what about feature-detection? like "is TLA supported" new ModuleSource would synchronously throw on syntax errors |
12:44 | <eemeli> | I get the sense that this first proposal is including ModuleSource in order to use it esp. for the introspection stuff that's coming in a later proposal. Could we not have a first proposal that has the source as a string and leaves out module.source , and then a follow-on proposal that modifies this proposal before it reaches stage-4 with the ModuleSource features that are in it now? |
12:44 | <Mathieu Hofman> | Right but engines can guarantee the stability of this, where delegating to the program, I don't see how it can |
12:45 | <ljharb> | right, but how could i detect it if i can't make a module from a string |
12:45 | <rbuckton> | Right but engines can guarantee the stability of this, where delegating to the program, I don't see how it can |
12:45 | <Luca Casonato> | right, but how could i detect it if i can't make a module from a string |
12:45 | <yulia> | cc bakkot in case this is possibly interesting |
12:45 | <bakkot> | what about feature-detection? like "is TLA supported" |
12:46 | <shu> | Kris Kowal: thanks the developer - production split is a helpful framing |
12:46 | <ljharb> | eg i want to know if it's worth trying to import a module that i know requires TLA support, and i support envs that lack it, and i don't want to even bother making the network request if it lacks it |
12:46 | <nicolo-ribaudo> | I had in on the queue but didn't get to it, but ModuleSource is to JavaScript what WebAssembly.Module is to WASM. A |
12:47 | <shu> | let me think on that, but sounds like a starting point to how to think about getting ahead of performance footguns and how to message it |
12:47 | <nicolo-ribaudo> | Because WebAssembly.Module is the representation of the wasm source, and it is stateless |
12:47 | <bakkot> | ljharb well, nothing is going to have ModuleSource but not TLA, so presumably you're imagining some other syntax? |
12:48 | <rbuckton> | eg i want to know if it's worth trying to import a module that i know requires TLA support, and i support envs that lack it, and i don't want to even bother making the network request if it lacks it |
12:48 | <Luca Casonato> | It is the compiled module source, that you can also use to get the list of imported specifiers, and list of exported binding identifiers. ModuleSource could provide the same for JS modules. Ie See also https://github.com/tc39/proposal-compartments/blob/master/1-static-analysis.md |
12:49 | <ljharb> | Would you not generally know this up front, given that its usually unsafe to eval code you don't control anyways? |
12:49 | <ljharb> | ljharb well, nothing is going to have ModuleSource but not TLA, so presumably you're imagining some other syntax? |
12:50 | <ljharb> | (altho ModuleSource can probably be polyfilled since every engine has a way to create ESM from a string, despite it not being in 262) |
12:50 | <Luca Casonato> | (altho ModuleSource can probably be polyfilled since every engine has a way to create ESM from a string, despite it not being in 262) |
12:51 | <ljharb> | oh true, no, only async |
12:51 | <nicolo-ribaudo> | do browsers have a synchronous way to do this? I thought not ModuleSource global with ModuleSource +Babel , generating an object that toString s to a data url? |
12:51 | <rbuckton> | i'd know that the code i'm importing has TLA, of course - but i don't know what the env supports |
12:51 | <ljharb> | rbuckton: exactly. how can i feature-test the env without the ability to make a module from a string? |
12:52 | <rbuckton> | package.json: { "engines": { "node": "^19" } } ? |
12:52 | <ljharb> | that covers node, but not browsers or node-like things |
12:52 | <nicolo-ribaudo> | That's very specific to a single env |
12:52 | <nicolo-ribaudo> | Not even to an env, but to package managers |
12:52 | <ljharb> | and there could also be a fallback, so i wouldn't need to artificially restrict compat |
12:53 | <linusg> | bakkot: "D denting" -> "dedenting" replacement would be nice |
12:53 | <bakkot> | done |
12:54 | <rbuckton> | True, but you're not just sending code to a random environment. I assume there's some setup/handshake between you and the remote. That's when I'd perform feature testing or inform the client what the remote supports. |
12:55 | <rbuckton> | And even if there isn't, if you have ensured the minimum level of support for sending a module over the wire, you can send one that performs the necessary feature tests in advance (i.e., send a module { some new syntax } over the wire during handshake and see if that fails) |
12:55 | <Mathieu Hofman> | I assumed implementations would care as it would allow user code to execute in the middle of internal Map/Set implementations. This is also a problem for the Map user if the equality somehow further delegates to the objects themselves. |
12:58 | <rbuckton> | I assumed implementations would care as it would allow user code to execute in the middle of internal Map/Set implementations. This is also a problem for the Map user if the equality somehow further delegates to the objects themselves. === semantics. The question would be whether implementers would find the necessary changes to handle runtime comparisons would be a less complex alternative. |
12:59 | <rbuckton> | I agree it would add complexity, and the justification for that added complexity would be to avoid worse complexity elsewhere. |
12:59 | <ljharb> | yes i agree, but i'm saying that you can not perform that feature testing in the first place without this capability |
12:59 | <ljharb> | at any time |
13:00 | <Kris Kowal> | (@bakkot Regarding new paths to eval, to restate @littledan from the queue, eval('module {}') is equivalent but worse, because injection.) |
13:00 | <bakkot> | Kris Kowal right but people know not to use eval |
13:00 | <bakkot> | we shouldn't be encouraging them to do equivalent things |
13:02 | <rbuckton> | yes i agree, but i'm saying that you can not perform that feature testing in the first place without this capability module {} , then you can. You don't need ModuleSource(text) or source-text access to define those feature tests. To be clear, I'm not opposed to ModuleSource(text) , I just don't find this to be a compelling example. |
13:04 | <rbuckton> | In fact, in a discussion with my team it was asked why JS should even have
Though I fully see the CSP concerns as being a major reason for a syntactic alternative. |
13:08 | <Kris Kowal> | we shouldn't be encouraging them to do equivalent things |
13:14 | <ljharb> | hm, could you do isSubsetOf with a WeakSet that has a size own data property set to Infinity ? |
13:26 | <Mathieu Hofman> | Regarding the feature detection, I fail to see how this is a problem specific to the modules proposals, or that the module proposals should solve. This is a broader ecosystem issue. Every new syntax we add has the same problem, and it's impossible to for a publisher to feature test what syntax the target environment might support. This is the case for servers sending modules to web clients, but also for library authors not knowing anything about the environment of the consumers. IMO, this is not something the language can solve, but that needs some kind of holistic approach. One thing I've been pondering is whether authors could somehow document which syntax features their code is using, and have better ways to know which syntax is supported by target environments, so that tooling (servers, transpilers, etc.) could do impedance matching. |
13:28 | <Rob Palmer> | We resume 14:40 (11mins time) |
13:28 | <rbuckton> | Hopefully back in 10 min, dogs need a walk. |
13:28 | <Ashley Claymore> | đ So excited this got stage 3. Lovely proposal |
13:30 | <ljharb> | the difference is that modules, like functions, are first-class values that have stored code that can be executed |
13:31 | <Justin Ridgewell> | Rob Palmer: If possible, I'd love to come back to String.dedent later in the meeting. |
13:34 | <Michael Ficarra> | Justin Ridgewell: any reason why the caching issue can't be worked out on the issue tracker or in an incubator call? does it still need the whole committee's attention? |
13:35 | <Justin Ridgewell> | Because I'd like to get Stage 3 |
13:35 | <Michael Ficarra> | oh, has the naming issue been worked out already? |
13:36 | <Justin Ridgewell> | If we can agree on the caching behavior in issue tracker, I'd like to finalize it and ask for advancement. |
13:36 | <Justin Ridgewell> | Naming issue? |
13:36 | <bakkot> |
yes, and more generally you can make fake wrappers which will let you pretend to be a set for a lot of cases. like, to union with array: |
13:38 | <Michael Ficarra> | Justin Ridgewell: oops, I was mixing dedent and groupBy together, sorry |
13:38 | <Michael Ficarra> | wow it's amazing how dumb I am when tired |
13:39 | <Michael Ficarra> | can't wait to give the iterator helpers presentation on day 3 right after waking up :-) |
13:39 | <Justin Ridgewell> | Lol, my ability to explain talk during the presentation isn't great either. Too sleepy |
13:40 | <shu> | i'm no longer sleepy |
13:40 | <shu> | i'm at the my head feels detached state |
13:41 | <Kris Kowal> | same + toddler woke up, ready for another energy-filled day |
13:44 | <Michael Ficarra> | that was fast :-) |
13:54 | <shu> | not as fast as the inner loop of an optimized IsWellFormed optimization |
13:54 | <Michael Ficarra> | shu: you better hope so |
13:55 | <Michael Ficarra> | I want constant time, make it happen |
13:55 | <rbuckton> | I'm finding the fact module importing a ModuleSource and not a Module slightly confusing from the perspective that the keyword isn't quite aligned to the type. |
13:56 | <apaprocki> | I want constant time, make it happen |
13:56 | <Michael Ficarra> | apaprocki: not a joke, we should be able to make it constant time (amortized) |
13:56 | <Robert Pamely> | I'm finding the fact |
13:56 | <Christian Ulbrich> | FWIW, TS also used a similar syntax for type imports :import type {...} |
13:56 | <ljharb> | I'm finding the fact reflect: 'module' |
13:57 | <Kris Kowal> | I'm finding the fact import moduleSource from './example' with { reflect: true } to mirror the proposed dynamic import. This is consistent with a need to confine dynamic import and washes back from that. |
13:57 | <Mathieu Hofman> | exactly, this is already a problem for Function and eval , so why would Module be subject to different requirements |
13:58 | <ljharb> | that seems like it would allow with to be expanded in unforseeable ways in the future, which sounds like a downside to me |
13:58 | <ljharb> | i agree it should have the same requirements as Function - which includes that it takes a string of source code |
13:58 | <rbuckton> | I am encouraging a return to the consideration of ModuleSource->Module and Module->somethingelse would be clearer. Especially since the ModuleSource equivalent in WASM is WebAssembly.Module . |
13:58 | <Kris Kowal> | Iâd previously encouraged import module to mirror import.module for static vs dynamic variants, but I have retracted that. |
13:59 | <Kris Kowal> | Iâd be excited to entertain ideas for somethingelse. |
13:59 | <Kris Kowal> | I have none. |
13:59 | <Mathieu Hofman> | I thought we had settled that a level of indirection through ModuleSource was not a meaningful difference. |
13:59 | <bakkot> | it is surprising to me that import module does not actually evaluate the module, so I am also supportive of import moduleSource or something |
13:59 | <Kris Kowal> | Though, itâs a constrained problem⌠module {} instanceof Module makes much sense. |
13:59 | <bakkot> | like I think of the regular import statement as importing a module |
14:00 | <yulia> | my preference would be something like with |
14:00 | <bakkot> | so "import module" is confusing |
14:00 | <Kris Kowal> | I agree. |
14:00 | <Kris Kowal> | And suggest that import moduleSource from 'example' with { reflect: true } should address that concern. |
14:01 | <Kris Kowal> | like I think of the regular |
14:01 | <Christian Ulbrich> | I tend to also agree, because there is a certain overlap in naming; import is about importing modules... |
14:01 | <yulia> | I feel like that also works well with dynamic import |
14:01 | <bakkot> | Thatâs very reasonable, though it doesnât provide any reflection of that module. import * as form does, arguably |
14:01 | <bakkot> | but yes |
14:02 | <Kris Kowal> | Right, I agree and also suggest const moduleSource = await import('example', { reflect: true}) to pair. |
14:02 | <ljharb> | i really don't like the "with" object, or any object form. are there long term, concrete, viable plans to add something else to the object? |
14:02 | <Kris Kowal> | Note (module {}).source instanceof ModuleSource intentionally reads correctly. |
14:03 | <Kris Kowal> | i really don't like the "with" object, or any object form. are there long term, concrete, viable plans to add something else to the object? with { phase: 'linked' } would be a reasonable extension. |
14:03 | <yulia> | with { lazy: true } would also be a path |
14:03 | <yulia> | rather than adding arbitrary new syntax |
14:04 | <ljharb> | i'd love to understand more about how those proposals would work |
14:04 | <Kris Kowal> | with also pairs well with dynamic import options bag, as opposed to variadic args. |
14:04 | <ljharb> | sure, but dynamic import can accept a similar-but-different form in its options bag |
14:04 | <Kris Kowal> | Yulia will be talking about lazy in this meeting. |
14:04 | <ljharb> | import module and { module: true } is perfectly sensible |
14:05 | <ljharb> | if i'm awake for that, that's great, but timezones make that hard |
14:08 | <Michael Ficarra> | okay I think I finally understand why this doesn't solve deferred evaluation: the deferred eval use case still wants to load the whole module graph eagerly, right? just not start evaluating? |
14:08 | <Kris Kowal> | This is a strawman: As for phase: 'linked' , the goal state of import is implicitly is executed whereas with import module (by whatever syntax) has a goal state of shallowly loaded. phase would provide an avenue for targetting an intermediate phase, like linked , which would ensure the transitive dependencies have loaded (or loading this module will fail). This is useful for communicating to bundlers and runtimes different performance profiles for application startup, like code splitting. |
14:08 | <Kris Kowal> | okay I think I finally understand why this doesn't solve deferred evaluation: the deferred eval use case still wants to load the whole module graph eagerly, right? just not start evaluating? |
14:08 | <yulia> | okay I think I finally understand why this doesn't solve deferred evaluation: the deferred eval use case still wants to load the whole module graph eagerly, right? just not start evaluating? |
14:09 | <Michael Ficarra> | thanks đ |
14:12 | <nicolo-ribaudo> | Maybe ModuleInstance &ModuleSource , and the syntax could be import instance or import source |
14:12 | <Christian Ulbrich> | yulia: Exactly. I also see this confusion. |
14:12 | <yulia> | import source may work if we go in that direction, and it may be the closest to what is happening now |
14:12 | <yulia> | instance is also an overloaded term as developers may think that this gets around module singleton-ness |
14:12 | <Robert Pamely> | isn't import instance just import ? |
14:13 | <yulia> | ^ also that confusion is likely |
14:13 | <nicolo-ribaudo> | import instance would give you a ModuleInstance object |
14:13 | <eemeli> | I think I like import source . |
14:15 | <ljharb> | import is like "import instance and extract bindings", maybe? |
14:16 | <yulia> | import is import and execute a module -- instance, in this case, means something different and can still be executed |
14:16 | <yulia> | thats why you can await import it |
14:16 | <yulia> | its more like module record maybe is what i shoud say? |
14:17 | <nicolo-ribaudo> | Yes an instance is exactly a module record, just exposed to JS as an object |
14:17 | <Rob Palmer> | Has this topic been discussed with bundlers on the TC39 Tools call? |
14:17 | <eemeli> | I don't see why we'd need more than two statements here; something like import + import source would also allow for an instance to be constructed from the latter. |
14:19 | <shu> | nicolo-ribaudo: wait, doesn't omitting the handler get you what's equivalent to the host? |
14:20 | <Kris Kowal> | nicolo-ribaudo: wait, doesn't omitting the handler get you what's equivalent to the host? |
14:20 | <Kris Kowal> | In this sense, import reflection simply defers the phases past load. |
14:20 | <nicolo-ribaudo> | Yes but Module instances don't have the [[HostDefined]] slot provided by the host |
14:20 | <shu> | which Module instances? |
14:21 | <nicolo-ribaudo> | Created by new Module |
14:21 | <shu> | gotcha, but import module returning module instances can have [[HostDefined]] |
14:21 | <Luca Casonato> | import reflect foo from "./foo.js"; foo instanceof Module; // true |
14:21 | <nicolo-ribaudo> | ModuleSource lacks the referrer URL, which is stored in the [[HostDefined]] slot of Module Records |
14:21 | <ljharb> | chairs, the queue isn't advanced properly |
14:21 | <nicolo-ribaudo> | [[HostDefined]] belongs to Module and not ModuleSource , because it contains data specific to that instantiation |
14:22 | <nicolo-ribaudo> | So if import *keyword* returns a Module object, it has all the data necessary to resolve the dependencies when later imported. If it returns a ModuleSource , new Module(thatThing) doesn't have the necessary data |
14:23 | <shu> | Kris Kowal: why isn't it the case that a new Module that have the host default handler get the [[HostDefined]] slot? |
14:23 | <nicolo-ribaudo> | i.e. the base URL, + maybe what HTML calls "fetch options" |
14:23 | <nicolo-ribaudo> | Kris Kowal: why isn't it the case that a |
14:23 | <ljharb> | so is the queue now for the previous topic? |
14:23 | <Kris Kowal> | Nicolò of course is the authority on the proposed spec text, but the intent is that the Module carries host-defined import behavior and ModuleSource carries host-defined origin information and those are separate concerns. The latter would prevent import in a no-unsafe-eval for a ModuleSource constructed from text. The former defines link behavior. |
14:23 | <shu> | oh sorry, i thought you wrote that spec |
14:23 | <shu> | hm i see |
14:24 | <shu> | okay that seems like a good argument for returning Module instance |
14:24 | <nicolo-ribaudo> | Caridy wrote it, I then PRed to rebase it on top of the refactor changing much of the loading logic |
14:24 | <shu> | but i think my brainpower has degraded from small child to golden retriever |
14:24 | <shu> | is this the last item |
14:24 | <ryzokuken> | we might bring something forward |
14:25 | <Rob Palmer> | something delicious and entertaining |
14:26 | <Alex Vincent> | I admit to being ready with my presentation if called upon. |
14:27 | <nicolo-ribaudo> | is this the last item |
14:31 | <littledan> | Nicolò of course is the authority on the proposed spec text, but the intent is that the |
14:31 | <littledan> | I think this is what Guy was imagining, and that it would live in WebAssembly.Module |
14:32 | <littledan> | (We may still want to propagate some of that information there) |
14:32 | <nicolo-ribaudo> | I with we had "TC39 meeting: modules edition" :P |
14:33 | <Kris Kowal> | Like Shark Week |
14:44 | <rkirsling> | live every week like modules week |
14:48 | <ryzokuken> | if we have a few more days this intense, I'll need a glucose drip |
14:48 | <bakkot> | are any of the other engines using bleeding-edge C++? |
14:48 | <bakkot> | I haven't been paying attention to the C++ world much in the last... uh, decade or so, I guess |
14:49 | <yulia> | i think we technically have c++20? |
14:49 | <yulia> | whether we use it fully or not is another question |
14:49 | <apaprocki> | mfbt has a lot of newish stuff used by sm |
14:54 | <rkirsling> | I'm not certain if "full C++20" is a reasonable state at the moment? but I think WK is "17 with a small selection of 20 things" |
14:56 | <shu> | i don't even know how to read bleeding edge C++ |
14:56 | <apaprocki> | there's so many useful things in 20 |
14:57 | <apaprocki> | we add lots of the useful library bits in our stl so we get them even in +03 |
14:57 | <shu> | "signed integers are 2's complement" |
14:57 | <shu> | for real |
14:57 | <apaprocki> | ostringstream::view() ftw |
15:11 | <shu> | wait what's the timebox for this |
15:11 | <shu> | does today go past 7? |
15:12 | <Rob Palmer> | the meeting ended 12 mins ago - apologies for the overrun |
15:12 | <ljharb> | snek: can you add libjs to esvu? |
15:13 | <snek> | ljharb: didn't I already do that? |
15:13 | <Christian Ulbrich> | linus said so :) |
15:13 | <ljharb> | oh hm, maybe i just need to update esvu |
15:13 | <ljharb> | npx esvu --engines doesn't list it for me |
15:13 | <snek> | https://github.com/devsnek/esvu/blob/master/src/engines/libjs.js |
15:14 | <ljharb> | how do i list all the available engines? |
15:15 | <littledan> | That was a very satisfying closing topic |
15:15 | <littledan> | So exciting |
15:15 | <snek> | what was the closing topic? |
15:15 | <snek> | I missed the whole meeting đ |
15:15 | <apaprocki> | libjs |
15:15 | <snek> | oh nice yeah |
15:15 | <Ashley Claymore> | 100% - LibJS found spec typos in the change-array-by-copy proposal. Very thankful for the issues they raised |
15:16 | <snek> | now if you had implemented change-array-by-copy in engine262... :P |
15:17 | <ljharb> | hmm, Error: LibJS does not have binary builds for darwin-x64 - can i not install it on a mac? |
15:17 | <snek> | I think it's Linux x64 only |
15:17 | <snek> | they'd need to expand their CI |
15:17 | <Christian Ulbrich> | Use a x86 shell... |
15:18 | <ljharb> | oof |
15:18 | <ljharb> | linusg: any chance of making a binary for mac? :-) |
15:20 | <linusg> | I think the main problem with that is that the build is done when test262 runs, which we have a dedicated (Ubuntu) CI runner for - maybe it can cross compile for macOS though, I'll ask around :) |
15:25 | <snek> | GitHub actions has mac instances |
19:24 | <Ashley Claymore> | now if you had implemented change-array-by-copy in engine262... :P |