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"