01:49 | <jackworks> | Is it okay to add additional internal slots after the object created? |
01:58 | <shu> | no, don't do that |
01:59 | <shu> | unless you really can't express it any other way, then maybe we can see if an exception makes sense, but per https://tc39.es/ecma262/#sec-object-internal-methods-and-internal-slots: |
01:59 | <shu> | Unless explicitly specified otherwise, internal slots are allocated as part of the process of creating an object and may not be dynamically added to an object. |
17:18 | <devsnek> | shu: isn't this jobcallback stuff all happening inside of the steps for running a job |
17:18 | <devsnek> | why can't this be part of a host's implementation defined preparation/cleanup steps |
17:19 | <shu> | devsnek: it probably should be happening in the steps for running a job, per my last comment, but there still needs to be an extra hook to capture the incumbent to pass back |
17:20 | <devsnek> | ah i didn't see that, glad we came up with similar conclusions :D |
17:20 | <shu> | devsnek: i was trying to mirror the webidl semantics, but i don't think webidl conflates job and a callback function |
17:20 | <shu> | err, i do think, rather |
17:21 | <shu> | so webidl always associates the incumbent per function object, which is what my current PR does. but that seems to be extra expressivity that's not needed |
17:22 | <shu> | since we don't have any API that for example takes multiple callbacks at different points in time, possibly with different incumbents, then posts a single job that calls them |
17:23 | <devsnek> | makes sense |
17:23 | <devsnek> | this reminds me that i need to review your other job pr |
18:52 | <shu> | devsnek: interestingly, domenic's batching case suggests a per-function approach is perhaps desirable |
18:52 | <devsnek> | what uses batching |
18:53 | <shu> | devsnek: since you were thinking per-job, do you have concerns with the extra expressivity? |
18:53 | <shu> | i don't think anything does currently |
18:54 | <shu> | though, if the extra machinery isn't too much complexity, i don't see why we wouldn't want the extra expressivity |
18:54 | <devsnek> | this whole thing feels weird |
18:54 | <devsnek> | sort of like an implementation detail leak about the job |
18:55 | <shu> | i don't share that view, JS is embedded |
18:55 | <devsnek> | i guess the generalization is "whenever a job calls a function"? |
18:56 | <shu> | stuff in jobs already cross that boundary |
18:56 | <shu> | yes |
18:56 | <shu> | the generalization is "job callbacks" |
18:56 | <shu> | those need additional state in some embedders |
18:57 | <devsnek> | `HostCall(job record, f, thisvalue, args)` |
18:57 | <devsnek> | and put some HostDefined on job records |
18:57 | <shu> | yes, something like that |
18:57 | <shu> | though not sure if it needs the job record passed back in |
18:57 | <devsnek> | sure, jobrecord.[[HostDefined]] or whatever |
19:22 | <bradleymeck> | ljharb: if you have better names than emplace I really have no strong desires as a base except that the name shouldn't reflect an operation it might not do |
19:23 | <ljharb> | i'll definitely think about an alternative |
19:24 | <ljharb> | i realize it's not quite as reasonable to object to a name without providing at least one alternative :-) |
19:24 | <ljharb> | bradleymeck: was "one callback, but with arguments that tells you if it's an update or an insert" also blocked? |
19:24 | <bradleymeck> | yes |
19:24 | <ljharb> | what was the reasoning? |
19:25 | <bradleymeck> | it devolves to just being a ternary with and update and insert function generally |
19:25 | <bradleymeck> | no real reason to force it to be a single function at that point |
19:25 | <ljharb> | i'd say the reason is "because some folks objected to passing two callbacks" |
19:26 | <bradleymeck> | function handler(isUpdate, existingIfIsAnUpdate) { return isUpdate ? update(existingIfIsAnUpdate) : defaultValue() } |
19:26 | <bradleymeck> | ljharb: i don't see any major problem with an options bag |
19:27 | <bradleymeck> | in a comment we even had someone show an example of a reciever storing data |
19:27 | <bradleymeck> | handler receiver |
19:27 | <ljharb> | oof |
19:27 | <bradleymeck> | i can understand the complaint about not including naming in the function params, and that double purposing the handler is weird |
19:27 | <ljharb> | fwiw, the mess that is "a proxy handler" would make me fight pretty hard to eagerly extract the functions from the object |
19:28 | <bradleymeck> | ljharb: implementations strongly disagree XD |
19:28 | <ljharb> | on which part |
19:28 | <ljharb> | (also i don't think the callbacks should be called with a receiver at all) |
19:28 | <bradleymeck> | ljharb: collection normalization wanted to do that, but impl feedback was that it *must* match proxy handler behavior to ease impl and be more consistent |
19:28 | <ljharb> | it's conceptually an options bag, not a handler object |
19:28 | <ljharb> | um |
19:29 | <bradleymeck> | ljharb: regardless impls do not agree and I had to change a previous proposal because of it |
19:29 | <ljharb> | that would be inconsistent with the way options bags are used everywhere else in the ecosystem |
19:29 | <ljharb> | can you remind me who had that objection? |
19:29 | bradleymeck | digs about |
19:29 | <ljharb> | because the way proxy handlers work is bizarre and confusing and unique |
19:29 | <shu> | you could dig through the notes too :P |
19:30 | <bradleymeck> | https://github.com/tc39/proposal-collection-normalization/issues/15#issuecomment-515337415 is in there |
19:30 | <bradleymeck> | notes would be around that timeframe |
19:30 | <ljharb> | totally fair, if it's in the notes i'll look |
19:31 | <ljharb> | if it's just that one github comment tho i'd want to explore it more. in the case of collection normalization, that involves the internal hooks of maps and sets; for upsert i just don't buy a perf argument |
19:32 | <ljharb> | also, the precedent we now have is that `resolve` is looked up on `Promise` eagerly |
19:32 | <bradleymeck> | ljharb: it was in committee don't remember if it was in the presentation or hallway |
19:32 | <bradleymeck> | ljharb: upsert is not just perf |
19:33 | <ljharb> | yeah i'm not finding anything in the notes |
19:33 | <bradleymeck> | upsert is mostly about fixing the (now fixed) bugs we had to deal with when making a complex multi-level cache for work |
19:33 | <bradleymeck> | it took years to completely find them all |
19:33 | <bradleymeck> | and most had to deal w/ all the variation of .has/.get/.set workflows to try to insert or update a value |
19:33 | <ljharb> | what i mean is, i don't understand how the "similarity to proxy handlers" argument applies when that's the only place in the language we dynamically look up values on an object later, and when in all the Promise combinators, we look up the functions eagerly, on purpose |
19:34 | <ljharb> | and that Promise change was made *because* of implementor perf arguments |
19:34 | <bradleymeck> | ljharb: talk to implementors? |
19:34 | <ljharb> | happy to but it's not in the notes, so that one github comment's all i've got |
19:35 | <ljharb> | (or rather i can't find it in the notes) |
19:35 | <bradleymeck> | ljharb: just ping rbuckton and maya directly? |
19:35 | <bradleymeck> | they would know the source of the underlying reasoning perhaps more than I |
19:36 | <bradleymeck> | i'm just reacting |
19:36 | <ljharb> | ping rbuckton :-) any context here? i'll ping maya later |
20:02 | <bradleymeck> | ljharb: since these are not persistent and are always looked up since the handler is immediately called does it even have meaning to eagerly read the values? |
20:03 | <bradleymeck> | we don't keep a ref to the options bag after the return value |
20:03 | <ljharb> | it determines observability |
20:04 | <ljharb> | ie if it’s a getter, then i could determine if the map’s `has` had been checked first or not |
20:04 | <ljharb> | oh also that raises another question; are these looking up `.has` and `.get` and `.set`, or are they using the internal operations? |
20:16 | <bradleymeck> | ljharb: no .has delegation |
20:16 | <bradleymeck> | absolutely not |
20:17 | <ljharb> | great |
20:17 | <ljharb> | no get or set either, i hope? |
20:17 | <bradleymeck> | correct |
20:17 | <bradleymeck> | reentrancy concern nailed that |
20:17 | <ljharb> | yay ty |
20:17 | <bradleymeck> | otherwise we did have subclassing concerns if we didn't delegate |
20:17 | <bradleymeck> | but with reentrancy delegating would be really awkward |
20:17 | <bradleymeck> | also other langs don't do that |
20:18 | <ljharb> | right; i’m personally already convinced that the normalization approach is the only viable path for JS to making subclassing easier without polluting methods with reentrancy and observable lookups |
20:33 | <devsnek> | how long until we define that ~empty~ can coerce into a list |
20:34 | <bakkot_> | never 😠 |
20:36 | <shu> | it should coerce into a singleton list with `"Empty"` |
20:47 | <rkirsling> | shu: which is == 0 I presume |
20:48 | <shu> | i like that, yes |
20:49 | <rkirsling> | 😂 |
20:49 | <ljharb> | presumably also, ~empty~ is neither truthy nor falsy |
20:49 | <ljharb> | `!~empty~` produces `document.all` |
20:50 | <ljharb> | and `+~empty~` ofc produces `NaN` |
20:50 | <shu> | no, those are terrible ideas |
20:51 | <bradleymeck> | maybe we need a new... `void` value to represent a reified empty |
20:53 | <ljharb> | and `anything in void` would ofc be false |
21:20 | <bradleymeck> | void in void |
21:26 | <ljharb> | touché |
21:32 | <devsnek> | v8 has exactly what we need "the hole" |