02:18 | <devsnek> | bakkot i think u got a good solution to my question |
02:18 | <devsnek> | zip shortest + make everything except the first one infinite |
02:44 | <bakkot> | zip-longest is actually the interesting one; my thing does not give you that unless you know up front which the longest one is |
02:57 | <bakkot> | shortest I can come up with in ten minutes is
which... I guess it's straightforward enough, but I get why python decided that was worth putting in the standard library |
15:00 | <devsnek> | itertools docs has examples for how to implement the functions https://docs.python.org/3/library/itertools.html#itertools.zip_longest |
15:45 | <bakkot> | yeah but their implementation is an explicit loop, which is gross |
17:23 | <jschoi> | Has anyone thought about proposing a logical-xor operator ^^ to parallel bitwise xor ^ ? |
17:25 | <jschoi> | It was asked for and talked about on the TypeScript side, where it was closed with “making new binary operators is TC39's job, not ours”. https://github.com/microsoft/TypeScript/issues/587 |
17:26 | <bakkot> | jschoi: what's wrong with !== ? |
17:27 | <bakkot> | obviously it doesn't do the type coercion for you but I would be very reluctant to introduce a new operator which is only necessary when you don't know the types of your variables |
17:27 | <jschoi> | Yep, that was brought up in the TypeScript issue too. My answer is: nothing! I’m not seriously considering it, but I am wondering if it was considered, especially given that the ^ punctuator might be used for other purposes in the future. |
17:28 | <bakkot> | I don't recall seeing a discussion; you could check the mailing list archives at esdiscuss.org/, but I'd be surprised if there was any serious proposal put forward |
17:29 | <jschoi> | Yeah, I couldn’t find anything on ESDiscuss. But it’s good to know that the temperature for a binary ^^ in TC39 is cold. The pipe operator might use ^ , after all, which would forever preclude a binary ^^ . Thank you! |
17:57 | <devsnek> | bakkot: it doesn't seem to me like the new tail call wording behaves well with the "caller realm" for eval |
17:57 | <devsnek> | with the old wording the stack was popped, now it is not. which realm should it point to? |
18:01 | <bakkot> | devsnek: eval isn't a tail call anyway; I don't understand the question |
18:01 | <devsnek> | wdym it isn't a tail call |
18:01 | <bakkot> | https://tc39.es/ecma262/#sec-function-calls-runtime-semantics-evaluation |
18:02 | <bakkot> | a direct eval doesn't go through the normal call semantics |
18:02 | <bakkot> | it has its own branch, which doesn't include the tail call stuff |
18:02 | <devsnek> | you can do return (0, eval)() though |
18:03 | <bakkot> | oh, for indirect eval, sure |
18:04 | <devsnek> | so its like 2nd to top or 3rd to top depending on if there's a tail call now |
18:04 | <bakkot> | no, it's still the second to top |
18:04 | <bakkot> | the realm is no longer the realm of the caller of the function containing the tail call |
18:04 | <bakkot> | that was the point of the PR |
18:04 | <devsnek> | ? |
18:04 | <bakkot> | the realm used for g in function f(){ g() } is the same as the realm for g in function f(){ return g() } |
18:05 | <bakkot> | that was the point of the PR |
18:05 | <devsnek> | i'm not following |
18:07 | <bakkot> | prior to #2495, when you had a g which could observe its callers realm, e.g. if g is a revoked proxy for a callable,it would observe the realm of the caller of f in function f(){ return g() } , and now it observes the realm of f itself, just as for function f(){ g() } |
18:07 | <devsnek> | no i mean, if that's the case, isn't the assertion incorrect |
18:07 | <devsnek> | since you are continuing to use information from it |
18:08 | <bakkot> | eh, depends on what you consider "resources" |
18:08 | <bakkot> | we have consensus for allowing cross-realm tail calls to consume resources anyway, we just never merged that change in to the spec (and I don't plan to) |
18:10 | <devsnek> | it just weirds me out |
18:11 | <devsnek> | and if we explicitly differentiate between implementation activations of functions and the execution context stack, why do we also have to duplicate the context in asyncfunctionstart |
18:12 | <devsnek> | i feel like i'm missing a connection here or there is a mistake |
18:13 | <bakkot> |
I don't know what this means. the spec does not use the phrase "implementation activations of functions" |
18:13 | <devsnek> | For example, a tail position call should only grow an implementation's activation record stack by the amount that the size of the target function's activation record exceeds the size of the calling function's activation record. If the target function's activation record is smaller, then the total size of the stack should decrease. |
18:14 | <bakkot> | that's in a non-normative note, which is talking about implementation strategies |
18:14 | <bakkot> | there's no corresponding notion in the normative prose |
18:15 | <devsnek> | i think the normative text was written with that model in mind |
18:16 | <devsnek> | and it makes it weird |
18:16 | <bakkot> | it was written with that model in mind, but it was extremely confused, because it was conflating that with transfers of control |
18:16 | <bakkot> | now there is no such conflation; it is much better |
18:19 | <bakkot> | re:
it's so that when the topmost context suspends (that is, the body of the function does |
18:20 | <bakkot> | if we didn't push a new context the await would suspend the execution context which has EvaluateAsyncFunctionBody itself, which is no good |
18:22 | <devsnek> | yeah i know the reasoning there (we had to revert my pr remember?), my point was there seems to be disagreement about what thing is doing the evaluation of code. is the execution context metadata for the evaluation or does it represent the evaluation itself |
18:28 | <bakkot> | from the spec's point of view, code is just another kind of data which gets passed around. the execution context stack represents some metadata which is tracked during evaluation - e.g. [[Realm]] - as well as representing nonlocal transfers of control within the spec [but n.b. this is within the spec's abstract machine, not within ecmascript code]: an execution context can be suspended-and-popped, which transfers control back to the step subsequent to the one which pushed it, and for execution contexts which have steps after the suspend-and-pop, at some future point it can be pushed-and-resumed and control will resume at the step subsequent to the suspend-and-pop. |
18:29 | <bakkot> | I'm not sure if this answers "what thing is doing the evaluation of code", though. not sure if by "code" you mean ES code or the spec steps. |
18:35 | <bakkot> | ("execution contexts which have steps after the suspend-and-pop" is synonymous with "execution contexts which are created for the evaluation of generators/async functions/async generators/TLA modules", i.e., contexts which can use Yield or Await) |
18:35 | <bakkot> | sometimes algorithms which do suspend-and-pop use Return to transfer control back to the previous execution context, which is very strange; see https://github.com/tc39/ecma262/issues/2400 for discussion/a possible fix |