2019-07-01 [17:45:00.0000] it's fascinating that `CallExpression : CallExpression . IdentifierName` is a separate production from `MemberExpression : MemberExpression . IdentifierName` but evaluated the same (https://tc39.es/ecma262/#sec-property-accessors-runtime-semantics-evaluation) [17:45:35.0000] I would've assumed that `a().b` was a MemberExpression with a CallExpression child [18:06:59.0000] such is the way of mostly-duplicate nonterminal productions [18:07:44.0000] i believe forcing MemberExpression to be its own path is how receivers work [18:10:57.0000] I figure there's a reason but it's quite tricky to identify at a glance [22:19:42.0000] devsnek: i think someone just needs to make a PR/proposal for json modules. [23:03:58.0000] It‘s somewhat involved as a bunch is host-specific still [23:06:06.0000] annevk: how much of that isn't hoistable to 262? [23:06:13.0000] ie what are the tricky parts [23:07:48.0000] MIME type, bytes -> elements, stuff like that [23:08:16.0000] hm, ok [23:08:29.0000] so basically, figuring out where a bunch of host hooks can go? [23:09:14.0000] And keeping it readable [23:09:56.0000] gotcha [23:10:39.0000] Oh, and hosts still need to be able to add yet more types [23:10:53.0000] Seems it’d be rather messy [23:12:02.0000] types like mime types? 2019-07-04 [09:14:06.0000] Oh, https://github.com/tc39/ecma262/pull/1135 got merged! I'd forgotten how nice and precise it makes the spec. [09:14:30.0000] https://tc39.es/ecma262/#sec-mathematical-operations gives me good feelings to read because it's shows such care on the part of the spec to distinguish important, subtle things [09:14:37.0000] Looking forward to adopting this in web specs [09:46:46.0000] Yeah, we blocked formalizing all things numbers on that [12:49:03.0000] this is fancy [14:07:40.0000] caiolima: now that 1135 is merged, it'd be great if you rebased the bigint PR :-) [14:09:35.0000] ljharb: Thx for the heads up! I’ll be able to do this tomorrow or next Monday. [14:11:24.0000] awesome, thanks, lmk 2019-07-05 [14:37:41.0000] ljharb: Maybe remove "good first patch" from https://github.com/tc39/ecma262/issues/1611 (at least for now). It made sense when the change was just removing a clause. Now, it's not so simple. [14:38:47.0000] lol yeah fair 2019-07-06 [17:03:42.0000] leobalter: do you think there's any meaningful overlap between your reverse proposal and my iterator methods proposal? [17:04:07.0000] i think in theory array iterator prototype and map iterator prototype and whatnot could all have a reverse method [22:10:44.0000] devsnek: i think individual iterators would have to opt in to being reversable tho [22:11:08.0000] otherwise it'd be pretty silly to not know if your iterator will be infinite or not (and thus irreversible) [22:11:23.0000] or even just, non deterministically finite [06:53:19.0000] ljharb: I'm more talking about how that integrates with other methods and such [06:58:23.0000] for example in rust you do x.iter().rev(), not x.iter_rev() [07:19:05.0000] devsnek: yeah i think it makes more sense to have a single reverse method than to suffix everything [07:20:18.0000] array.values().reverse() vs array[reverseIterator]() [07:20:53.0000] typically symbol methods are a protocol that nicer-named methods access, no? [07:21:37.0000] perhaps [09:08:59.0000] ljharb, littledan: Hmm, 𝔽 doesn't show up in the default fonts on a Chromebook. :( [09:09:30.0000] (ℝ does, presumably because it's more commonly used as a math symbol) [09:12:10.0000] (I don't have an immediate good suggestion for alternate glyphs, except perhaps ℕ. Misleading in nature, but mnemonic in usage.) [09:13:00.0000] (Or as an amusing alternative, ℚ, because all Numbers are rationals. ^_^) [09:59:49.0000] TabAtkins: isn't 𝔽 usually used for fields anyway? [10:00:24.0000] Yes, so the current usage isn't technically accurate anyway [11:52:17.0000] There was a previous reverse iterator proposal [11:52:29.0000] https://github.com/leebyron/ecmascript-reverse-iterable [11:55:11.0000] oh that does what i said above [11:55:45.0000] People should find the meeting notes where we discussed that [11:56:05.0000] The leebyron proposal looks good to me but maybe there were reasons it didn't advance. (I suspect the biggest reason was lack of champion time.) [11:56:31.0000] oh no https://github.com/tc39/tc39-notes/blob/master/meetings/2015-03/mar-24.md#63-reverseiterable-interface [12:00:08.0000] lollll [12:10:22.0000] TabAtkins: hmm, so it seems like all the double-struck glyphs in Letterlike Symbols block are present in the more "default" fonts like Tinos, Arimo, and Noto Serif, so ℂℍℕℙℚℝℤ work fine. [12:10:40.0000] however, the rest of them are in the newer Mathematical Alphanumeric Symbols block, and are only present in Noto Sans Math, which should also be installed by default on CrOS… [12:12:49.0000] nope, apparently not [14:53:51.0000] rbuckton: what does __promisifiy__ do in ts? [15:06:03.0000] ah nevermind someone else figured out how it's used 2019-07-08 [05:51:28.0000] ljharb: I saw you've commentend on BigInt PR. Thx a lot! I'll be able get back to work on this tomorrow. [08:13:39.0000] devsnek Domenic ljharb I don't have strong preferences how we can add a reverse iterator to the spec, as long as we get something for Array, Map, and Set. Not even worried about String. I'll follow the consent sentiment from the room [08:14:50.0000] the way Lee Byron's proposal describes the iter.reverse() is "safe" but weird, I'm not sure I love it. It should definitely be coordinated with devsnek's proposal. [08:15:37.0000] obviously we need a reverse iteration syntax /s [08:16:32.0000] What I want is something straight to the point where in a list object I can `list.reverse()`. I have a preference (not a blocker) for a string named method, that may mirror a Symbol property. And I'm fully aware Array#reverse is taken, so I'm open to bikeshed names [08:16:57.0000] fwiw i haven't explored optional capabilities at all yet, so iter.reverse might not be the the best way forward, it was just off the top of my head [08:17:37.0000] it's very odd calling `[].values().reverse()` where you get two iterators and rely on both [08:18:41.0000] in rust, when you use rev, what you actually start doing is consuming the same iterator from the back instead of the front [08:18:51.0000] [].valuesRight() is ugly but follow consistency with reduceRight [08:19:01.0000] technically you could consume it from both sides at the same time, and end up in the middle [08:19:52.0000] I'd rather not have a @@reverseIterator depending on a @@iterator [08:20:15.0000] it needn’t have to [08:20:30.0000] it's weird in my mind to be a reverse iterator but not a regular iterator [08:20:31.0000] but that’d be a naive possible implementation [08:20:49.0000] naive possible yes, thats why I'm not discarding [08:20:54.0000] you could also make it required to have an iterator method, but not invoke it [08:20:57.0000] is there an example where you would want to only be iterable with a concept of reverse [08:21:03.0000] I'm playing flexible here [08:21:55.0000] devsnek: you could have an iterable for, say, data points over time, which is infinite - but your reverse iterator could start at a timestamp [08:22:02.0000] devsnek if I have a Map/Set subclass instance that enforces LIFO operations [08:22:22.0000] ok [08:23:35.0000] if we have a concept of double-ended iterators reverse can just be a general wrapper than calls nextBack instead of next [08:23:37.0000] also, the fact these two steps are only applied in specific cases, not applied to generators or any other custom iterator [08:24:24.0000] same for: `[@@asyncIterator]()[@@reverseIterator]()` [08:24:50.0000] or `[@@asyncIterator]().reverse()` where it should not even be available [08:26:16.0000] i'm trying to think of other languages that have this [08:27:01.0000] i think rust and c++ are the only languages that generalize it to a trait/template type thing [08:27:27.0000] and they both use the concept of double-ended [08:45:16.0000] i kinda like this, but perhaps its too complex? https://gc.gy/30305686.png [09:05:04.0000] I think a pro/con list for various possibilities would be a good thing to put in the proposal document [12:12:17.0000] haste [12:12:28.0000] (inb4 jorendorff can say anything posthaste) [12:12:50.0000] > BindingIdentifier: `yield` [12:12:50.0000] > * It is a Syntax Error if this production has a [Yield] parameter. [12:13:06.0000] ^ this appears in the current draft. But how is that different from [12:13:30.0000] > BindingIdentifier: [~Yield] `yield` [12:14:23.0000] That is, seems like an Early Error should be kind of a last resort. We could just enforce this in the grammar. Also, what does "this production" mean? [12:20:31.0000] `yield` in the position of a binding identifier is "this production" [12:27:52.0000] ok, well, that just seems to confirm that the meaning is basically the same as making that production conditional [12:31:14.0000] jorendorff: There is a NOTE above that early error section [12:31:24.0000] "yield and await are permitted as BindingIdentifier in the grammar, and prohibited with static semantics below, to prohibit automatic semicolon insertion in cases such as" [12:32:09.0000] WOW [12:32:11.0000] asi strikes again [12:33:35.0000] :-O [12:34:21.0000] still trying to wrap my head around how that example works though [12:34:37.0000] it's unbelievable, this is the junction of half a dozen JS quirks [12:34:43.0000] `let` is a conditional keyword [12:35:24.0000] `let;` is a legal JS statement in non-strict code; you can do `let = 12; eval("let")` and the answer is 12 [12:37:30.0000] loganfsmyth: So if ASI did happen, you would get `let; await 0;` which would actually parse [12:39:31.0000] ah right, so by making it a valid BindingIdentifier, it's not a syntax error and thus doesn't trigger ASI, ugh [12:39:40.0000] well, not exactly lol [12:39:49.0000] because `let await 0;` *is* still a syntax error [12:39:52.0000] or at least, not a grammar error [12:39:57.0000] yeah, poorly worded [12:40:04.0000] so it *does* trigger ASI [12:40:07.0000] but not until `0` [12:40:30.0000] and ASI looks at the `0`, sees that it's not immediately after a new line, and says no way [12:42:31.0000] so the way this prohibits ASI is by •exploiting details of how ASI case 1 works; and •arranging for a different token to be "the offending token" [12:42:43.0000] yupp [12:42:46.0000] good times :P [12:47:06.0000] loganfsmyth: TIL the Python parser in `python` is generated by this 406-line script https://github.com/python/cpython/blob/master/Parser/pgen/pgen.py [12:47:58.0000] oh cool [12:49:14.0000] apparently python's no-semicolons-required syntax works a *little* differently from JS's [12:51:04.0000] just a tad [12:51:39.0000] ok, i got another one [12:52:13.0000] > TemplateLiteral : NoSubstitutionTemplate [12:52:13.0000] > * It is a Syntax Error if the number of elements in the result of TemplateStrings of TemplateLiteral with argument false is greater than 2^32 - 1. [12:53:04.0000] but TemplateStrings on this is guaranteed to return a List with exactly one element TemplateLiteral:NoSubstitutionTemplate [12:53:31.0000] oops, meant to paste this link https://tc39.es/ecma262/#sec-static-semantics-templatestrings [12:57:40.0000] https://github.com/tc39/ecma262/issues/1588 [12:57:47.0000] jorendorff: ^^ [12:57:52.0000] I think? [12:58:41.0000] yup. thanks [13:49:53.0000] imagine a template literal with 2^32-1 substitutions [13:51:48.0000] devsnek: why just imagine? 😈 2019-07-09 [06:32:11.0000] A syntactic Program breaking that rule would be, I guess, at least 17,179,869,186 characters long. But a test case can be written in <100 characters I'm sure [06:33:02.0000] So ISO dates now support marking some parts of the date with X to indicate unknown things [06:33:35.0000] This is useful for folks that don't have a "complete" date for when they're born or some such [06:33:44.0000] Has this come up for Date? [06:34:05.0000] See https://github.com/whatwg/html/issues/3767 for the HTML side [06:36:43.0000] what is the result of parsing such a date supposed to be [06:38:04.0000] That's a good point, I guess it's somewhat fundamentally incompatible with ES [06:38:27.0000] A number of features in HTML would also do poorly [06:39:32.0000] maybe we can have a function to detect dates with unspecified digits [06:39:55.0000] but trying to create a date object would fail [12:22:18.0000] is it on purpose that GeneratorMethod is missing a production for private fields [12:27:40.0000] oh i guess all the methods are missing [12:27:44.0000] sigh [13:06:15.0000] annevk: it could work with Temporal, i think, for many configurations 2019-07-10 [09:37:37.0000] mathiasbynens: the spec text for Promise.any has `AggregateError` before the introduction, which seems wrong [10:10:40.0000] I thought aggregate error got removed [10:25:30.0000] definitely not 2019-07-11 [08:15:55.0000] Jeez https://bellard.org/quickjs/ is impressive [08:31:53.0000] heh [08:32:04.0000] Bellard's projects are always fun [08:32:34.0000] ..ok, yes, impressive [08:34:33.0000] I was planning to explore BigFloat at some point [08:34:43.0000] cool to see I wasn't the only one [08:43:11.0000] oh this guy made ffmpeg and qemu [09:03:20.0000] yeah, and tcc [09:03:51.0000] and some assorted fun projects, https://bellard.org/jslinux/ e.g. [09:15:10.0000] "this guy made ffmpeg" I NEED TO SHARE WORDS WITH THIS MAN [09:15:35.0000] lol [09:24:30.0000] i've been writing various bash scripts that run ffmpeg for the past several months [09:25:48.0000] and then… https://twitter.com/gesa/status/1148761150529527808 [09:26:23.0000] relatable [09:27:00.0000] a while ago i wrote a dependency resolving build system in js to avoid some mtime bug in make [09:28:16.0000] i *just* wanted a simple postprocessing script for my Plex DVR [09:28:22.0000] and then I met a yak i guess [09:29:09.0000] i feel like all the cool kids these days have plex [09:29:35.0000] "these days" i've had a plex server in my house for a decade [09:30:14.0000] oh wut https://github.com/facebook/hermes [09:30:17.0000] two js engines in one day [10:32:48.0000] wait what: https://github.com/facebook/hermes/blob/master/utils/testsuite/testsuite_blacklist.py#L1462-L1495 [10:33:33.0000] does it expect ES5 as input? [10:34:17.0000] rkirsling: react native is always transpiled [10:34:37.0000] dunno why it would be missing apis though [10:34:58.0000] right I just am surprised it doesn't say so anywhere [10:35:12.0000] actually [10:35:27.0000] right below is "PERMANANT_UNSUPPORTED_FEATURES" [10:35:36.0000] so i guess that stuff will eventually be added [10:36:04.0000] man this thing fails a lot of tests [10:38:03.0000] does facebook participate in ecma at all [10:54:03.0000] devsnek: i haven't seen anyone since 11/2018 [10:54:30.0000] hmm they do appear to be a member [10:55:03.0000] paging efaust 😭 [10:59:15.0000] yeah, wonder where Eric's been lately [12:05:51.0000] he's not on twitter so i can't hassle him 2019-07-12 [07:14:49.0000] mathiasbynens: unsure if bug from jsvu or npm but https://gc.gy/30645865.png [10:34:56.0000] leobalter: are there requirements for test262.report engines or a place to add them? all i can find so far is the issue repo [10:38:12.0000] devsnek we run the results collection privately. In general, we collect the results data using test262-harness, which is powered by eshost [10:38:42.0000] so if something supports eshost [10:38:46.0000] it can be put on test262.report? [10:38:48.0000] yes [10:39:11.0000] that's how we integrated Moddable XS [10:40:15.0000] so how come nashorn and engine262 and such aren't included [10:42:33.0000] think that "progress bar"-esque UI will need to be rethought if we add any more though [10:47:39.0000] probably [10:48:23.0000] i am kinda curious why the report stuff isn't oss [10:49:00.0000] devsnek so far, infrastructure and resources. I'd like to add all of them. I'll forward this internally and see if we can prioritize adding more engines [10:49:56.0000] my answer is wrt adding engines. The matters on being OSS is something I can't answer quickly [10:51:43.0000] thanks! it was more just curiosity than "omg why isn't test262 showing me nashorn's compliance right this minute" [11:00:28.0000] it is probably worth discussing whether there's some sort of "officialness" (probably in the sense of representation in the committee, I guess?) associated with having engines displayed there [11:00:54.0000] maybe so maybe not, just worth having a clear policy on [11:06:11.0000] rkirsling maybe the tests themselves are official, the engines are not specifically "official". We had to pick one engine to start expanding test262.report and used Moddable XS, I'd love to add more engines. [11:17:22.0000] leobalter: yeah I absolutely would like to see more of 'em on there, I just want to make sure we don't lose any ease of comparison :D 2019-07-13 [17:59:40.0000] can anyone make sense of this? https://github.com/Agoric/proposal-infix-bang [18:00:03.0000] deferred operations on objects is what i'm seeing [21:59:17.0000] it looks like a really really large proposal [21:59:34.0000] like, the first one is "promise prototype methods for deferred operations on a fulfillment value" [21:59:40.0000] and the second piece is "syntax for those methods" [22:05:42.0000] ljharb: i think fluent apis can already do the deferred operations tbh [22:05:54.0000] devsnek: what do you mean [22:05:56.0000] like `target!foo` can just be `target.foo` [22:06:03.0000] devsnek: not if `target` is a promise [22:06:07.0000] then it'd be `(await target).foo` [22:06:16.0000] or `target.then(x => x.foo)` really [22:06:26.0000] well your weird proxy thing would be part of a larger api [22:06:36.0000] like in the readme's queue message example [22:06:38.0000] i guess i'm mostly confused why we need syntax for methods nobody's using yet [22:06:45.0000] `messageThing().foo(1, 2, 3)` [22:06:49.0000] can use proxies [22:06:50.0000] it'll be an interesting topic [22:06:52.0000] and thenable [22:07:52.0000] yeah i'm interested to hear the discussion [01:42:24.0000] ljharb: yeah, the methods would need to be added and shown to be widely useful before the syntax could even be considered I’d think [01:48:03.0000] also not sure this needs new syntax at all: I am pretty sure you could just use a proxy which has traps for invocation and property access / assignment, and then use the existing syntax. something like `let remote = makeHandledPromise(); remote.foo(); remote.bar = 42; let value = await settle(remote);` [01:49:46.0000] anyway the point of the proposal, as I understand it, is that you want to have code which represents a sequence of operations on remote data without actually requiring the data to be passed from the remote system back to the system running the code at every step [06:46:09.0000] aside from the new API stuff, it's cool to imagine `fetch()!.json().something` [06:46:36.0000] oops `fetch()!.json()!.something` [06:46:47.0000] perhaps it's a bit easy to forget an exclamation mark [07:33:54.0000] Excited to see the progress on https://github.com/tc39/proposal-explicit-resource-management [07:34:34.0000] I think the infix bang idea is cool but not cool enough to carry its weight in the language. [07:34:50.0000] So many new methods which are just awkward and ugly and nobody would use given that we have await [07:35:06.0000] And the actual bang syntax is pretty error-prone and hard to read [07:35:31.0000] I'd rather explore executing code remotely using something like blöcks [07:50:16.0000] i can't believe we might actually have RAII in the language [07:51:18.0000] i'm kinda sad it's squeezed into the top of a try block [08:01:50.0000] I don't think it counts as RAII if you have to declare a specific using statement [08:01:54.0000] It's more like RAIRA [08:02:22.0000] I.e. the point of RAII is that just intializing is equivalent to resource acquisition [08:02:36.0000] Whereas this requires a specific resource acquisition statement (try, formerly using) [08:05:40.0000] "resource acquisition is resource acquisition" [08:06:16.0000] i just imagine stuff like `try (const _handleScope = v8.handleScope()) {}` [08:06:30.0000] You don't need the extra binding actually [08:06:36.0000] But yes that's the idea [08:06:50.0000] The difference is more in cases like the file handle ones [08:07:08.0000] Whereas in C++ you just initialize the file and poof, resources allocated and deallocated at end of block [08:07:24.0000] In this proposal you need to remember the try() or else you don't get auto-deallocation [08:07:50.0000] (To be clear, this proposal seems to be the best you can do in a GC'ed language.) [08:09:09.0000] could just check every lexical declaration at the end of a block :) [08:10:36.0000] I assume there's a reason that doesn't work but it's too early for me to think hard enough to figure it out [08:10:59.0000] i would assume performance [08:11:14.0000] although i guess engines like v8 already have stuff like "does this object have a toStringTag" [08:11:46.0000] Nah [08:11:50.0000] Google to the rescue https://softwareengineering.stackexchange.com/a/216032/13312 [08:12:05.0000] TLDR it needs a lot more infrastructure like copy constructors, move semantics, etc. [08:13:00.0000] oh yeah [08:13:07.0000] In a language where everything is a reference type, attaching significance to object lifetimes and making things more stack-bound starts crossing into value type territory [08:13:10.0000] hmm [08:13:16.0000] i could always do [08:13:31.0000] `let x; try (const y = whatever) { x = y }` [08:14:00.0000] or i guess just `x = whatever; try (x) {} ` [08:14:09.0000] seems to have the same issue [08:14:16.0000] but i guess its more explicit 2019-07-16 [10:50:24.0000] I randomly just discovered https://github.com/tc39/proposal-optional-chaining exists as a proposal; the overview prose says ?. can't be followed by a decimal digit -- has there been discussion anywhere/yet of this being a breaking change? consider |var increment = twoDecimalDigits?.01:.1;| for example; I couldn't see anything obvious in the repository's issues by their descriptions [10:51:16.0000] jwalden: i think that's why that restriction - because without it, it *would* be a breaking change [10:51:31.0000] ljharb: oh, the restriction means it parses the *other* way [10:51:35.0000] ljharb: okay, fine enough [10:51:48.0000] right [10:51:49.0000] I was assuming the restriction meant that wasn't permitted at all [10:51:59.0000] ah yeah that'd break the web for sure [10:52:11.0000] even if no user has ever typed it that way (which i doubt), minifiers have surely produced it that way [10:52:24.0000] troof [11:09:36.0000] jwalden: just for the record, there's an explanation at the top of the spec draft [11:09:39.0000] > For the syntax, we use the ?. token, with a lookahead at the level of the lexical grammar that allows to discriminate between a?.b (optional chaining) and a?.3:0 (conditional operator, whose meaning cannot be changed due to backward compatibility constraints). [11:09:53.0000] ah [11:12:09.0000] (though of course if the spec text itself implied something different that would be a problem :p) 2019-07-17 [09:03:02.0000] Hrm, why does Math.sqrt(-0) return -0? That's the only argument allowed to be negative, and the only return value that's negative. [09:03:19.0000] Doesn't even make sense, since -0 * -0 = +0 [09:03:39.0000] (Clearly, sqrt(-0) should be 0i.) [09:04:32.0000] (I also wish to again register a complaint with the Math functions test suite, which doesn't have any of these details tested. The spec is clear, but I didn't read into its details when I was copying over the behavior to CSS.) [09:27:08.0000] that is weird [10:50:16.0000] so in the spec, is ℝ the function (or at least applied as function) identical in meaning to ℝ as subscript? I'm looking at https://tc39.es/ecma262/#sec-tostring-applied-to-the-number-type and it talks about ℝ as subscript, but it does not seem to explain ℝ as function at all [10:51:10.0000] is it possible whoever added this was dithering between functional notation and subscript notation, settled on subscript notation ultimately, but missed fixing up a functional use or two, perhaps? [10:53:08.0000] cc ^ caiolima [10:54:31.0000] 5.2.5 (https://tc39.es/ecma262/#sec-mathematical-operations) does have [10:54:31.0000] > A conversion from a Number to a mathematical value is denoted as "the mathematical value of x", or ℝ(x). [10:55:18.0000] seems like it's basically the difference between a literal and a variable then? [10:58:40.0000] (fwiw this was a recent change in https://github.com/tc39/ecma262/pull/1135) [10:59:03.0000] jwalden: I think you mean ℝ(x), the answer is yes. [10:59:19.0000] ah [10:59:51.0000] oh, I missed that in that wall-o-text [11:01:52.0000] ljharb: BTW, not sure if I notified you last week, but I updated https://github.com/tc39/ecma262/pull/1515 since your last review. [11:02:07.0000] thanks! i'll take a look soon 2019-07-18 [09:21:30.0000] In https://tc39.es/ecma262/#sec-createintrinsics, why is thrower created before funcProto [09:21:41.0000] if it was created after, it wouldn't need the SetPrototypeOf call [09:25:40.0000] also test262 expects thrower to have [[Extensible]] = false [09:25:53.0000] but at no point is thrower.[[Extensible]] set to false as far as i can tell [09:27:12.0000] oh the intrinsic says "The value of the [[Extensible]] internal slot of a %ThrowTypeError% function is false." [09:27:23.0000] but the intrinsic is also manually created with a call to CreateBuiltinFunction [09:27:26.0000] and mutated [09:28:54.0000] devsnek: seems like a good editorial improvement :-) [09:29:04.0000] i was just making a commit now [09:34:44.0000] devsnek: I think it *used* to make sense. [09:34:54.0000] I'll see if I can find it. [09:35:28.0000] i can probably remove the entire `AddRestrictedFunctionProperties` thing too [09:37:31.0000] See https://github.com/tc39/ecma262/issues/877 and https://github.com/tc39/ecma262/pull/1148 [09:39:47.0000] hmmmmm [09:39:58.0000] well my thing is purely editorial [09:48:15.0000] ljharb: jmdyck: https://github.com/tc39/ecma262/pull/1635/ [09:48:58.0000] I'll have a look once I'm finished with last night's merges. [11:50:05.0000] `({a, b} = obj);` is a little awkward. I wonder whether do expression could help? Is `do {a, b} = obj;` valid? [11:56:19.0000] Oh, I realize it's a silly question... syntax conflict with current `do {} while` X) [11:57:04.0000] haxjs: https://github.com/tc39/proposal-do-expressions [11:59:27.0000] Thanks, devsnek. I just found my head is not clear in this moment (3AM in my timezone) and decide to go to bed now. '=D [11:59:41.0000] 👍🏻 [12:01:25.0000] Domenic: random question: in the OP of https://github.com/tc39/proposal-weakrefs/issues/17 you assert "To correctly implement this step, you need a reference to every NodeIterator object that's ever been created, so you can update it correctly ". The way I'd expect to implement this is to have the NodeIterator objects, when queried, check the document to see which nodes are still live. is there a reason that implementation doesn't work? [12:02:44.0000] (this doesn't require WeakRefs, and so seems more reasonable) [12:03:15.0000] What do you mean by "when queried"? [12:03:56.0000] oh that reminds me https://gist.github.com/devsnek/e3ee8be1fc235e2bee43b2c1cd262adf [12:04:08.0000] `.nextNode()` etc? [12:04:18.0000] this could be changed to a weakset fairly easily and used in jsdom [12:04:20.0000] or whatever other methods exist for code to look at the contents of a NodeIterator [12:04:36.0000] you have to have a reference to the node iterator first [12:04:52.0000] devsnek: ? [12:05:11.0000] I am proposing that the implementation of the nodeIterator `nextNode` method query the document to see what nodes are still live [12:05:23.0000] if no one has a reference to the nodeIterator, no one is going to call nextNode, and the point is moot [12:06:32.0000] in js though, exists and live are the same thing [12:06:41.0000] until you add weakrefs [12:07:37.0000] devsnek: I have no idea what you are trying to say [12:07:44.0000] maybe i'm misunderstanding [12:07:59.0000] the issue above gives an algorithm for "removing a node" [12:08:08.0000] what I meant by "live" in my first message was "not yet removed" [12:10:03.0000] Bakkot: I am not 100% sure if this was the reason, but I believe you cannot just figure out the next node based on the current state of the tree; you need to see all the intermediate mutations. [12:10:18.0000] So doing it lazily when queried will give wrong results. [12:10:21.0000] ah, fun [13:00:02.0000] Bakkot: Domenic: in particular there’s a reference node affected by mutations [13:01:05.0000] I guess you could use mutation observers [14:10:59.0000] would anyone happen to know of a careful derivation of the length of the longest possible string returned by NumberToString? https://tc39.es/ecma262/#sec-tostring-applied-to-the-number-type the algorithm was not written in a fashion that makes the maximum length clear [15:52:22.0000] jwalden: i don't believe there is a maximum length in the spec; it'd just be memory constraints of the host [15:52:27.0000] jwalden: same as there's no max on string length [15:53:06.0000] tfw `delete a?.b` comes for free in the spec but not the implementation [15:53:07.0000] ljharb: oh there most certainly *is* a maximum length, 64-bit floats mean at most 2**64 possible result strings so they *have* to have an upper limit [15:53:19.0000] jwalden: are bigints 64 bit tho? i thought they were unbounded [15:53:33.0000] jwalden: oh this isn't bigint tho, nvm [15:53:33.0000] ljharb: NumberToString takes in numbers, not bigints [15:59:35.0000] rkirsling: you mean babel? [16:05:51.0000] devsnek: just did a JSC impl :p [16:06:27.0000] rkirsling: why doesn't delete come for free? [16:06:29.0000] we have a hackathon going on so I was like "hmm what do I want to spend a free day on" [16:06:38.0000] doesn't `a?.b` either return undefined or a member reference [16:06:50.0000] dunno, it's possible I maybe a simple mistake, will let you know :D [16:06:55.0000] *made [16:07:09.0000] i'm looking forward to using the impl :) [16:07:41.0000] i added optional chaining to a language i'm working on a few days ago inspired by the js proposal https://github.com/devsnek/slither/commit/09746bc21e2ba0fcb8872af63f4cc62395ba8f03 [16:10:31.0000] awesome [16:11:09.0000] yeah no it looks like (at least for JSC) `delete` makes assumptions about its expression so I have to update them [16:11:41.0000] yeah i would've assumed they have all sorts of shortcuts that make life hard [16:18:18.0000] devsnek: this should give you an idea: https://github.com/WebKit/webkit/blob/master/Source/JavaScriptCore/parser/Nodes.h#L985-L1025 [16:19:16.0000] oh my [16:19:59.0000] that's rough 2019-07-19 [19:36:17.0000] https://tc39.es/ecma262/#table-unicode-script-values seems to look deformed with the `Elym` insertion [19:44:05.0000] mathiasbynens: btw for future updates of Unicode versions, you probably should update the Unicode version in https://tc39.es/ecma262/#sec-normative-references too [22:33:37.0000] TimothyGu: PR? :-p [10:31:29.0000] ljharb: is -0 => 0 in spec prose? [10:31:42.0000] or >=, always forget the order... [10:36:32.0000] I was wondering if that'd matter for https://tc39.es/ecma262/#sec-numbertorawbytes which Atomics.store() ends up invoking, but I'm guessing you get the same either way [11:14:36.0000] annevk: Since the merge of PR #1135, it appears that, in the absence of a subscript, numeric operations in spec prose are interpreted as Number operations. RelationalExpressions use Abstract Relational Comparison, which treats +0 and -0 as the same. [11:21:49.0000] annevk: No, negative zero is treated identically to positive in most contexts. [11:22:12.0000] Whoops skipped over jmdyck's response because it used big words. [11:24:45.0000] (I've been stretching my mouth to let those big words come right out.) [11:43:07.0000] jmdyck: ta 2019-07-20 [17:59:24.0000] there's no example of how to implement evaluating generic module X when you're dynamic importing [17:59:55.0000] shouldn't there be like a `HostEnsureModuleEvaluated(moduleRecord)` that the thing would call or something [18:04:02.0000] and like what do i do if i resolve to a module that is evaluating, the spec says i must return a module that is evaluated, do i wait a tick or something? [18:06:11.0000] if the module isn't cyclic, how would i even know if its been evaluated or not [18:52:29.0000] devsnek: "evaluated, i.e. whose Evaluate concrete method has already been called and returned a normal completion" [18:53:32.0000] Domenic: yes that's the line that is giving me trouble [18:53:55.0000] How your host ensures modules Evaluate() methods have been called is up to your host. [18:54:05.0000] You can see examples of how it's done in browsers by looking at the HTML spec. [18:54:13.0000] i mean for an abstract module record [18:54:17.0000] its safe to just do `Evaluate()` [18:54:24.0000] because its required to return undefined if its already evaluated [18:54:43.0000] Abstract module records Evaluate() doesn't exist [18:54:49.0000] So it is not safe to do it since it doesn't make sense [18:55:08.0000] abstract module records have Link() and Evaluate() [18:55:13.0000] They do not [18:55:17.0000] Concrete subclasses do [18:55:17.0000] test/test262/test/language/expressions/dynamic-import/assignment-expression/unary-expr.js [18:55:23.0000] oops [18:55:26.0000] ok but i mean [18:55:42.0000] the concrete implementations are required to return undefined if its already evaluated [18:56:07.0000] Sure but there will usually be a lot more involved in evaluating a module than just calling Evaluate() [18:56:12.0000] here's the logic i'm using so far https://gc.gy/31292760.png [18:56:24.0000] you'll notice that this can return modules that are `evaluating` or `linking` [18:56:35.0000] i've seen at least one example of it returning a module that is `evaluating` [18:56:38.0000] I suggest studying https://html.spec.whatwg.org/multipage/webappapis.html#hostimportmoduledynamically(referencingscriptormodule,-specifier,-promisecapability) and linked algorithms. [18:56:46.0000] They ensure the result is always evaluated [19:00:37.0000] Domenic: i am not doubting that algorithms to do this can exist [19:00:42.0000] i'm just confused why the spec doesn't provide one [19:01:00.0000] Doing so is intricately entangled in host mechanisms [19:01:55.0000] The spec's job is not to provide a host for finding/linking/evaluating modules. That requires a host. If you want engine262 to be a host, you'll need your own algorithms. The algorithms you use will not generally be useful to other hosts. [19:02:13.0000] its able to run them not-dynamically without any host algorithms [19:02:41.0000] I can't see how that's true. There's no algorithm in the spec to turn specifiers into source text strings (e.g. by reading file contents) [19:02:51.0000] no, but once you resolve the modules [19:02:58.0000] the spec has all the algorithms to run them [19:03:11.0000] for dynamic imports though, the spec is like "lol figure that out yourself" [19:03:12.0000] The situation is the same here [19:03:23.0000] Once you dynamically import the module, the spec has all the algorithms to run them [19:03:28.0000] You just need to call them [19:03:38.0000] In a way that makes sense for your host [19:04:28.0000] Note how HTML uses "run a module script" for both static and dynamic cases. [19:05:07.0000] yeah [19:05:24.0000] but html spec also disavows the top level module jobs [19:05:34.0000] Yes, those are disappearing from the spec soon [19:05:39.0000] We have consensus to remove them [19:06:43.0000] what happens if HTML has to HostImportModuleDynamically a module that is currently evaluating [19:07:06.0000] RTC guarantees this won't happen. [19:07:16.0000] rtc? [19:07:27.0000] run to completion [19:07:55.0000] in theory a sync implementation with `import(x)` from module `x` would have this problem though right? [19:08:09.0000] I don't understand the question [19:08:27.0000] like if you're in module `x` [19:08:31.0000] and `import(x)` is called [19:08:48.0000] and that synchronously performs module lookup [19:08:54.0000] it ends up with a module record that is evaluating [19:08:58.0000] what is it supposed to return [19:09:03.0000] That'd be the same as using `import 'x'` I think [19:09:09.0000] So it fails [19:09:26.0000] if i ignore the assertions about returning an evaluated record it works [19:09:42.0000] You mean if your host violates the spec? [19:09:43.0000] and `import 'x'` from `x` always works [19:09:47.0000] per spec [19:09:50.0000] I don't believe that's true... [19:09:53.0000] sure [19:09:59.0000] Oh with no bindings? [19:10:03.0000] the test suite even uses that to inspect namespaces before they're complete [19:11:28.0000] I guess `Cyclic Module Record's [[status]] is "evaluated"` is different from "abstract module record's Evaluate() has returned a normal completion" [19:14:38.0000] so perhaps this invariant is incorrect? [19:15:00.0000] What leads to that conclusion? [19:15:41.0000] because its possible to have a module that is still evaluating [19:15:50.0000] should i return an abrupt completion or something? [19:16:38.0000] It's [[status]] is "evaluating", but it meets the spec's criteria of "evaluated, i.e. whose Evaluate concrete method has already been called and returned a normal completion" [19:17:32.0000] It is perhaps confusing that the informal "evaluated" phrase is used when talking about AMRs in this way, when CMRs have a specific "evaluated" [[status]] that is more narrowly defined. We could remove the "evaluated, i.e." [19:17:48.0000] i'm pretty sure by the time Evaluate() returns everything should have [[Status]] of "evaluated" [19:18:52.0000] like the case i described is definitely within the Evaluate() call [19:18:54.0000] Didn't you give a case where that's not true? [19:19:11.0000] in my case you're still within the call stack of module.Evaluate() [19:19:19.0000] it hasn't returned yet [19:19:30.0000] You're also outside the callstack of a different module.Evaluate() [19:19:32.0000] on the same module. [19:19:53.0000] i am? [19:20:21.0000] you can't call Evaluate() on an evaluating module, the assertion will fail [19:20:29.0000] I see [19:20:34.0000] perhaps that is the issue [19:20:34.0000] Then yeah don't do sync import() [19:20:53.0000] Because doing sync import() will cause assertion failures [19:20:57.0000] Which makes sense because it's async [19:21:14.0000] (I've humored this sync import() fantasy long enough!!) [19:21:18.0000] lol [19:21:40.0000] i'm just trying to hook up HostImportModuleDynamically to HostResolveImportedModule and not do anything complex :( [19:22:42.0000] If "being async" counts as complex, I think you are kind of working against the grain of dynamic import()'s design, and thus causing yourself unanticipated complexity. [19:24:20.0000] with TLA, couldn't a module be Evaluate()ing over multiple ticks [19:24:39.0000] Yeah I wonder how that gets integrated [19:24:50.0000] Hopefully updated to "the promise is resolved" or something [20:36:43.0000] ljharb: btw my pr doesn't explicitly set the length anymore [20:37:15.0000] setting length correctly is probably a battle for another pr [20:37:26.0000] devsnek: do the alg steps mention it? [20:37:33.0000] wdym [20:38:40.0000] like below throwerSteps, there should be a note, like in Promise resolve functions [20:38:54.0000] that's only used when there is no explicit `X ( )` [20:38:58.0000] like with promise resolve functions [20:39:25.0000] is there ever one in this kind of “algorithm steps for a function” thing? [20:39:45.0000] I’m reasonably sure that it’s only done for promise functions, and they all have a note. [20:39:45.0000] wdym [20:40:13.0000] referencing the actual steps for an already created function? [21:03:04.0000] ljharb: in Promise Resolve Functions, it's not a note, it's just a very short paragraph. [21:05:57.0000] what if promises were async iterable [21:07:15.0000] (is this a new topic? because if it's the same topic, i'm not sure how it connects.) [21:11:18.0000] oh sorry its a new topic [21:12:15.0000] ljharb: In "I’m reasonably sure that it’s only done for promise functions", what do you mean by "it" ? [21:12:51.0000] does anyone know what the result of the codeblock here will be https://github.com/pemrouz/proposal-emitter#background [21:28:57.0000] jmdyck: sorry i mean, it seems that other than ThrowTypeError, the only way functions are typically created is by referring to the same section as https://tc39.es/ecma262/#sec-promise-resolve-functions [21:29:04.0000] or rather a section formatted that way [21:29:13.0000] that’s the model that promise.allsettled and matchAll etc all followed [21:29:32.0000] so maybe the real issue is that ThrowTypeError should change to match all the other places that make functions [21:36:26.0000] i'm confused [21:36:34.0000] "only way functions are created" other than calls to FunctionAllocate, you mean. [21:38:02.0000] Backing up a bit: 2 ways to create a function object: via FunctionAllocate and via CreateBuiltinFunction. [21:38:29.0000] really, via FunctionCreate [21:38:42.0000] well FunctionCreate and its brethren [21:39:07.0000] GeneratorFunctionCreate, AsyncFunctionCreate etc [21:39:11.0000] yea [21:39:25.0000] but they all go through FunctionAllocate. [21:41:43.0000] (And actually, there are 2 other ways to create a function object, both exotic: ProxyCreate and BoundFunctionCreate) [21:44:47.0000] CreateBuiltinFunction is used to create both named builtins (mostly in CreateIntrinsics step 13) and anonymous builtins (scattered throughout) [21:47:36.0000] the latter are mostly generated in arbitrary numbers by factory-like operations [21:49:20.0000] (e.g., a given realm can have an arbitrarily large set of near-identical promise resolve functions) [21:51:03.0000] and yet we have one ThrowTypeError for three different error scenarios [21:51:16.0000] but %ThrowTypeError% is different in that there's exactly one per realm. [21:53:05.0000] "TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them" [21:53:20.0000] good error messages :P [22:02:48.0000] %TypedArray% might be another one-per-realm anonymous built-in function, though it's weird. That might be all. [22:05:02.0000] afk [05:17:16.0000] Guys, function expression (!= arrow function) is a primary expression, but parentheses are necessary to directly call it? [05:33:42.0000] Are you talking about parentheses around the function expression or parentheses around the arguments? [05:34:03.0000] around the function expression. [05:36:26.0000] In my understanding, CallExpression -> MemberExpression () -> PrimaryExpression () -> Function Expression () is possible. [05:36:50.0000] But, node.js rejects it so... I'm a bit curious. [05:38:02.0000] depends on the context [05:38:16.0000] try this: 1 + function () { return 2; }() [05:38:50.0000] wow. [05:38:52.0000] =O [05:39:17.0000] Can you give some hints so that I can dig into it? =) [05:39:24.0000] That's interesting. [05:39:57.0000] to check: that expression returned 3, right? [05:40:38.0000] but if you leave off the "1+", you get a syntax error? [05:40:55.0000] Yes. I got the error. [05:42:35.0000] The parser is attempting to parse the input as a Statement, and in particular an ExpressionStatement. But there's a rule that says an ExpressionStatement can't start with the "function" keyword. [05:42:40.0000] https://tc39.es/ecma262/#prod-ExpressionStatement [05:43:45.0000] Wow. Thanks for your help. [05:43:50.0000] I really appreciate it. =) [05:44:15.0000] no problem [09:04:24.0000] jmdyck: does this look good to you? https://github.com/tc39/ecma262/pull/1635/files [09:09:50.0000] Instead of `_realmRec_.[[Intrinsics]]`, you could just have `_intrinsics_` [09:11:04.0000] oops [09:11:48.0000] And it omits setting %ThrowTypeError%'s [[Extensible]] to *false*, but then so does the current spec. [09:12:15.0000] jmdyck: if its not explicitly created, the definition is enough [09:12:30.0000] at least with the current spec [09:12:39.0000] i'd like everything to be more explicit but it seems like something for another pr [09:13:24.0000] yeah, it's currently part of the magic surrounding CreateBuiltinFunction. [09:17:11.0000] But yes, this is what I was describing in my comment (modulo getting rid of AddRestrictedFunctionProperties, which also deserves to be a separate PR). [09:18:00.0000] Now I'm just checking that it all works out the same. [09:19:51.0000] works out in engine262 [09:27:09.0000] Yup, seems equivalent to me. 2019-07-21 [18:59:51.0000] https://github.com/tc39/ecma262/pull/1640: "RLlane9 wants to merge 971 commits" [19:05:32.0000] cheeky rebase [19:09:31.0000] also a couple in test262 [15:46:13.0000] rkirsling: btw where do your optional chaining and nullish patches show up [15:52:37.0000] devsnek: on my local machine lol [15:52:47.0000] lol [15:53:02.0000] may upload this week even without asking for review yet [15:53:12.0000] once you upload though [15:53:15.0000] bugs.webkit.org? [15:53:24.0000] mhm! [15:54:06.0000] i'm really glad the world is slowly leaving bugzilla for patches [15:57:01.0000] lol. it would be nice 2019-07-22 [10:43:45.0000] fun fact: C++20 is adding cancel tokens [10:44:05.0000] I want ASCII case-insensitive string operations... but we probably shouldn't add them because they're mostly useful for polyfills...? [10:44:17.0000] Bakkot: hmm I didn't see them on any of the blog post roundups. [10:44:25.0000] they call them "stop tokens" [10:45:23.0000] "The use of the "cancel" term also has precedent in the Networking TS which defines methods such as basic_waitable_timer::cancel() and basic_socket::cancel() and makes use of std::errc::operation_canceled as an error code in response to a request to cancel the operation.However, some concerns were raised about the potential for confusion if a std::jthread::cancel() methodwere added as some may confuse this as somehow being related to the [10:45:23.0000] semantics of pthread_cancel() whichis able to cancel a thread at an arbitrary point rather than cooperatively at well-defined cancellation points." [10:45:34.0000] from http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0660r9.pdf [10:46:11.0000] Hmm yep, I just skipped my eyes over them. [10:48:13.0000] Their registration API seems to translate to JS as `new StopTokenCallback(token, callback)`. Certainly side-steps any questions around event registration systems... [10:49:16.0000] I can't figure out what `stop_possible` does. Maybe some threading thing. [11:10:18.0000] Domenic: basically just a way to tell stuff whether registering stop callbacks and/or calling stop_source is worth it [11:10:36.0000] Ah that makes sense. 2019-07-23 [07:53:27.0000] mathiasbynens: i dunno if it will fit on your slide, but engine262 also implemented Promise.allSettled :) [09:54:07.0000] @akirose: Apparently I got kicked from the delegates channel [09:54:13.0000] Can you reinvite me? [10:10:43.0000] would it be possible to use something like HackMD in the future instead of Google Docs? If the minutes are in markdown it seems a bit weird to use a platform that's extremely antagonistic to Markdown 😅 [10:11:38.0000] bnb: meant for the delegates channel perhaps? [10:11:56.0000] Wasn't sure which channel was correct <3 [10:36:59.0000] jridgewell: done! [10:53:02.0000] Brian reinvited me, but thank you too! [11:25:57.0000] ljharb: is waldemar at this meeting? [11:29:15.0000] TimothyGu: yep, i've spoken to him about the items awaiting his review [12:21:01.0000] .msg akirose 2019-07-24 [17:53:53.0000] man, implementing this syntax error is gonna be kinda grody though [18:06:20.0000] for `??`? [18:10:35.0000] yeah. kind of an assumption that all non-assigning binary ops are gonna be alike [18:11:38.0000] so one way would be to say that ?? "isn't an binary op" in that sense [18:12:13.0000] but yeah, may require some extra time to think through 🤔 [18:12:41.0000] oh fun; my parser does a recursive descent thing where each op gets its own function, so it would be trivial [18:15:18.0000] indeed [18:15:29.0000] I've got one of those too (though it's for a toy language) [18:50:37.0000] I've got one of those too [19:02:28.0000] wow this queerjs think just happened [19:02:44.0000] I didn't see anything about it until after it happened :( [19:23:40.0000] ohoho I figured it out [19:25:42.0000] the high-level lesson is "if your parser (sub-algorithm) is linear, you should probably reconceptualize your problem in a linear fashion too" [19:26:27.0000] (which sounds stupidly obvious if I do phrase it that way but the trick only works because ?? has *minimum* bin op precedence) [20:32:01.0000] does nullish coalescing have test262 tests [21:44:13.0000] devsnek: not yet [21:44:47.0000] writing up a bunch right now which we could copy over [22:30:15.0000] devsnek: https://bugs.webkit.org/show_bug.cgi?id=200072 [07:11:09.0000] rkirsling: nice [07:11:31.0000] patch looks pretty similar to this https://github.com/devsnek/slither/commit/c3799d3133fe00020b3bf6260a7b61eb84727c63 [08:26:31.0000] devsnek: indeed! very nice [14:53:20.0000] Test 123 2019-07-25 [08:32:16.0000] Guys, the expression `test.hello.foo` yields `Reference` type whose `bv` is `test.hello`, right? If we use that as a `CallExpression`, by `EvaluateCall` 1-a-i thisValue ends up being GetThisValue(test.hello), but I don't think it's right. What am I missing? [08:33:16.0000] GetThisValue(test.hello) would be test, but the actual run shows foo itself. =/ [08:33:41.0000] in `test.hello.foo` [08:33:51.0000] first a reference of test -> hello is built [08:34:10.0000] then in the `(test -> hello).foo` part [08:34:23.0000] `test->hello` is passed to GetValue() [08:34:31.0000] which grabs the result of actually performing the lookup [08:34:48.0000] so the final thing is (whatever the result of test.hello is) and foo [08:35:50.0000] So at least the `bv` is not a foo, I think? [08:36:08.0000] the base value is the result of GetValue(test.hello) [08:38:26.0000] So, the final Reference type of `test.hello.foo` is test.hello -> foo. Am I wrong? [08:38:40.0000] it's whatever `test.hello` evaluated to [08:39:19.0000] like if test.hello was 5 it would be 5 -> foo [08:44:03.0000] I got what you meant. Thanks. But, using it as a CallExpression and doing console.log(this) inside foo gives somewhat strange behavior. In `let test = { "hello": { foo() { console.log(this); } } };`, test.hello would be "hello" object there, and `EvaluateCall` should give me GetThisValue(that "hello" object), thereby test. [08:45:17.0000] Thank you for bearing with me, by the way. [08:45:21.0000] cpplearner: you should get `{ foo() {} }` as the this value [08:55:37.0000] devsnek: Thank you for the hints! I finally got it. [08:55:49.0000] =) Have a nice day. 2019-07-26 [22:18:40.0000] I like how the one thing I forgot to do in my hackathon implementation of ?. is literally the hairiest part [22:19:37.0000] i.e. not double-evaluate the LHS 2019-07-27 [10:00:45.0000] Can I make a user-defined constructor? For example, since the specification defined Array to be a constructor and a constructor shall also implement [[Call]], I can do new Array() or Array(). But, If I make a new class I can only implement `constructor`. I wonder if there's any chance to implement [[Call]] myself. [10:02:03.0000] cpplearner: using `function() {}` and `new.target`https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/new.target [10:10:58.0000] devsnek: Oh, `FunctionAllocate` takes care of [[Construct]] part, if functionKind is normal. Hmm, but implmenting both with `class` keyword is impossible, am I right? [10:11:13.0000] yeah [10:11:24.0000] Thanks for clarifying and helping me all the time! [10:11:28.0000] Have a nice day! [15:45:48.0000] damn, after a couple of days, I think I've finally worked myself into a corner [15:46:52.0000] think non-re-evaluation in `a.b?.().c` is just not compatible with an "it's just a ternary!"-style approach [15:49:03.0000] (i.e. if I'm just holding `a.b` and `a.b().c`, that call is gonna have a bad time trying to determine its this value...) [16:16:14.0000] rkirsling: i'm not following what you're saying [16:16:42.0000] devsnek: lol I was hoping you would but it's tricky to express concisely [16:17:26.0000] i think its just miscommunication [16:17:37.0000] does "its just a ternary" refer to the syntax or the behaviour [16:17:43.0000] semantics [16:17:55.0000] er like, bytecode standpoint [16:18:05.0000] so like... `(a.b ? a.b() : undefined).c` [16:18:13.0000] except that still throws [16:18:38.0000] and i forgot to compare to null/undefined [16:19:45.0000] yeah i dunno i think the feature is pretty useful [16:20:13.0000] so, for my hackathon version of this, I just have an OptionalChainNode with children `a.b` and `a.b().c`, and the bytecode generated from that node mimics a ternary, but it naively re-evaluates the base when it's not nullish [16:20:47.0000] oh i see [16:20:51.0000] (I can upload that part to WK BZ if you want to see) [16:21:06.0000] i get what you're saying now [16:21:26.0000] so then to deal with the re-eval, I thought it would suffice to pass down the register for the already-evaluated base [16:23:25.0000] and that almost works...but `a.b()` is usually a single node in itself because it not only needs to know the function to call (`a.b`) it also needs the `this` value (just `a`) [16:24:45.0000] i've gotten too used to an accumulator interpreter [16:25:50.0000] so basically `a.b?.()` is already tricky because I need to pass down the already-evaluated `this` value, but once we extend the chain, I think the entire approach is just doomed [16:26:40.0000] sounds like a fun mess [16:26:44.0000] 😄 [16:26:57.0000] yes :P [16:27:23.0000] a mess indeed, but I still do enjoy a good compiler frontend puzzle [16:28:41.0000] ...think I'm gonna upload my naive approach for posterity before I redo it, heh [16:32:19.0000] pour votre amusement: https://bugs.webkit.org/show_bug.cgi?id=200199 [16:34:11.0000] hmm yeah i had to emit a different bytecode for each of the accessor, computed, and call variants [16:35:18.0000] the proposal moved forward with parens required right [16:35:47.0000] do you mean for `??`? [16:37:04.0000] oh lol confused already [16:38:00.0000] 😂 [16:51:12.0000] me trying to figure out v8's parser https://i.redd.it/f46azqiqcg411.jpg [16:58:06.0000] wait maybe there still is a way (tm) [16:59:27.0000] if I have an OptionalCallNode that treats the call as part of the chain's base, maybe this could still be salvageable...? 2019-07-28 [17:00:08.0000] (tfw you don't know which experiment to choose next) [17:00:24.0000] this is kinda why i made engine262 [17:00:43.0000] it lets you just totally mess around [17:03:33.0000] success! https://gc.gy/31977212.png [17:04:52.0000] heheh [17:17:42.0000] ok now i've got it parsing optional chaining as normal [17:21:47.0000] rkirsling: is `this?.#test` allowed [17:47:20.0000] believe so [17:48:31.0000] i hope so, but it's worth noting that only prevents an error when `this` is nullish; it will still throw if `this` lacks the `#test` field [17:49:08.0000] yup [17:52:06.0000] i'm glad to hear this, because parsing would become a lot more complex otherwise [18:11:12.0000] property access is working but calls aren't parsing for some unknown reason ;( [18:18:09.0000] rkirsling: do you mind if I borrow the tests from your patch [18:18:17.0000] not at all [18:19:11.0000] grazie [20:11:53.0000] does `a?.b()` still perform the call if a is nullish? [20:12:10.0000] as far as i can tell that parses as a?.b and then that whole thing is a call expression [20:20:42.0000] it does not [20:20:52.0000] i.e. it's not `(a?.b)()` [20:21:07.0000] the base is just `a` [20:21:27.0000] and the whole thing is an OptionalExpression [20:22:33.0000] hmmm [20:22:43.0000] i have no idea how to approach this [20:23:16.0000] i have an ast sort of like `Call(a?.b, [])` [20:23:32.0000] it's quite tricky [20:24:14.0000] but I still feel like piping the "optionalness" through the existing AST structure is not the right way [20:24:26.0000] wdym [20:24:43.0000] like adding an "optional" prop to a member expression node? [20:25:09.0000] like I'd still rather have a parent node that let's you make the short circuit in one jump, if at all possible [20:25:52.0000] hmmmmmmm [20:26:07.0000] not a bad idea [20:26:18.0000] i just have no idea how to do this call [20:26:51.0000] instead of having `a?.b.c` be the same as `(a?.b).c` but carrying some extra data so that you know when `undefined` is an error and when it isn't [20:27:30.0000] a few hours ago I was worried that I'd have to go back to square one and try that but still hoping not [20:29:29.0000] i made the same mistake with calls in my toy language [20:30:16.0000] i guess i can read babel [20:31:44.0000] I've been avoiding doing so, hehehe [20:35:20.0000] rkirsling: when you parse a?.b() in babel, you get an OptionalCallExpression with the callee being an OptionalMemberExpression [20:35:23.0000] but here's the trick [20:35:32.0000] OptionalMemberExpression also has an optional property [20:35:41.0000] so a?.b() is OptionalMemberExpression with optional true [20:35:49.0000] a?.b.c() is OptionalMemberExpression with optional false [20:36:37.0000] wowsers [20:36:57.0000] so really two flags [20:37:03.0000] yeah I mean maybe I'm being too conservative about adding nodes right now [20:37:26.0000] short_circuits and child_of_optional_chain [22:31:42.0000] rkirsling: i figured out a way to do this that only uses a single jump label, basically add a property to member expressions and calls saying if they are short circuiting, then wrap the root in an "optional chain" node. when you visit an optional chain node, make a new jump label, push it onto an optional chain jump label stack, and then stack.top() as the target for optional chain null jumps. [22:32:22.0000] wow [22:32:37.0000] no idea how to do this in v8 [22:32:43.0000] but i got it working in slither [22:32:48.0000] cool [22:34:08.0000] so you're saying you'd just evaluate member/call exprs normally otherwise? [22:34:21.0000] that's really enticing [22:34:37.0000] yeah you don't even need to jump over individual member expressions [22:34:45.0000] the thing kicking my ass right now is just how intricate the menagerie of function call nodes is [22:35:08.0000] yeah i dunno how well the theory meshes with real-world engines [22:35:17.0000] but we can dream :) [22:35:38.0000] I'm scared to copy-paste too much because keeping it all in sync over time sounds like a maintainability nightmare [22:35:57.0000] that's basically the point i got to [22:36:22.0000] in v8 i had like three different versions of MemberExpression : MemberExpression . Identifier [22:38:29.0000] https://github.com/WebKit/webkit/blob/master/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp#L1326-L1538 [22:38:58.0000] dot-access-and-call is three nodes amounting to over 200 lines [22:39:15.0000] so many specializations :fear: [22:39:17.0000] I weep [22:41:14.0000] that's why I've been stuck in think-and-not-do mode today [22:41:43.0000] 'cause copy-pasting all of that is out of the question [22:43:53.0000] who would've thought a simple null check would be so hard :( [22:44:10.0000] srsly [22:47:05.0000] hmmmmm [22:48:17.0000] I wonder if passing the label down instead of the pre-evaluated base would do the trick [22:49:07.0000] (*instead of the register for the) [22:49:13.0000] apparently a label in v8 can only have one referencing jump [22:50:00.0000] interesting. is that a problem here though? [22:50:26.0000] well in `a?.b?.c` [22:50:41.0000] there are two jumps referencing the end null label [22:51:30.0000] I was viewing it as `(a?.b)?.c` [22:52:05.0000] i guess [22:52:06.0000] so I think you're preoptimizing there :) [22:52:33.0000] in theory its a lot simpler to just have the one label [22:53:59.0000] hmm...faster, for sure, but I hadn't thought of it as simpler [08:36:52.0000] rkirsling: here's what I came up with https://chromium-review.googlesource.com/c/v8/v8/+/1723359 [12:24:31.0000] devsnek: gasp, I gotta make haste [12:31:04.0000] rkirsling: I nerd-sniped myself and ended up staying up til 5am :P [12:31:16.0000] XD 2019-07-29 [17:29:15.0000] I was going to ask about `eval?.()` and then I remembered that `eval` is overwritable in sloppy mode [17:29:20.0000] because of course it is. [17:59:36.0000] rkirsling: i had to work around a bug where `eval?.(...args)` wasn't emitting the correct bytecode [17:59:51.0000] because you know how popular chained calls to eval with rest args are :( [18:00:25.0000] heh [18:00:52.0000] eval calls have there own node in JSC so I was thinking for a moment maybe I could just ignore the ?. in eval?.() [18:00:55.0000] but nope [18:01:10.0000] *their, sign [18:01:15.0000] *sigh [18:01:18.0000] augh typing [21:16:22.0000] man, there's gotta be a better way to say "OptionalChainable" 2019-07-30 [04:38:09.0000] oh, well then [04:38:25.0000] howdoi, ljharb, devsnek ignore that then haha [04:48:36.0000] ljharb: is aware of compare and equals MJCD :-) [04:48:56.0000] I am interested in their opinion [04:49:07.0000] but that wasn't why I was trying to assemble [04:49:30.0000] ##javascript the other day was sooo clogged with proposal talk [04:49:41.0000] now I can send them over here ^_^ [07:27:35.0000] Sigh, new Math weirdness. hypot(Infinity, NaN) returns Infinity and pow(NaN, 0) returns 1, presumably under the logic that replacing the NaN with any Number wouldn't affect the result. But max(Infinity, NaN) and min(-Infinity, NaN) both return NaN, despite the same logic applying [07:28:16.0000] (I have an issue open on CSS to see if we need to copy over the hypot/pow behavior, rather than the strict "NaN is always infectious" behavior that's currently specced.) [07:29:09.0000] I recall that min and max are specified in terms of a large list of mathematical operators without individual spec text [07:41:01.0000] Nah they have spec text. It just defined "no args, return +/- Infinity; NaN args, return NaN; otherwise call the comparison algo". [07:42:00.0000] hypot checks for infinity before checking for NaN, who knows why. [07:44:10.0000] pow defers to `**`, which says "If exponent is +0, the result is 1, even if base is NaN." [07:45:38.0000] I wonder if that behavior is dictated by IEEE-754. [08:23:44.0000] (just fyi, i was reading the spec for all of these so I could have css copy the behavior) [10:30:01.0000] devsnek: It finally clicked for me this morning that I think that solution for ?. would've been more obvious to me if I'd've done a bytecode impl of try-catch before [10:32:20.0000] rkirsling: try/catch is what got me thinking of the solution i came up with [11:48:23.0000] Does anyone remember what the argument for including uninitialized class fields was? [11:48:41.0000] It's causing people coming from TypeScript a fair bit of pain, and is a huge pain to implement [11:48:45.0000] (in parsers) [11:49:12.0000] and it seems like `x = undefined` isn't that bad of an alternative [11:49:38.0000] mostly I just don't remember why we included them, and am wondering if anyone knows offhand [12:22:41.0000] Bakkot: like `class X { x; }`? [12:23:10.0000] i mean they don't have TDZ or anything [12:23:16.0000] what's the issue people are having [12:24:47.0000] looking over the acorn plugin, it seems pretty simple [12:45:53.0000] Bakkot: what happens in that if you are in a sloppy context with a `undefined` var? [12:46:17.0000] betting it was something dealing with sloppy doing bad things [12:47:20.0000] i feel like sloppy just keeps getting more strange over time [12:48:01.0000] because divergence and different things made for strict/Module having compromises instead of initial designs for making them work in sloppy [12:51:00.0000] devsnek: yeah, like that [12:51:11.0000] see https://github.com/tc39/proposal-class-fields/issues/242 and https://github.com/babel/babel/issues/10282 [12:51:28.0000] the issue is basically that typescript and flow treat that syntax (or roughly that syntax) as being basically a comment [12:51:40.0000] oh [12:51:43.0000] bradleymeck: `x = void 0` then, I guess [12:51:48.0000] this silly thing [12:52:34.0000] Bakkot: can't they just pretend it was `= void 0` [12:52:43.0000] ofc if we'd chosen [[Set]] this wouldn't be a problem :-/ [12:52:53.0000] devsnek: I would not guarantee acorn's plugin is correct; I spent a while getting it right in babel: https://github.com/babel/babylon/pull/351 [12:52:56.0000] ljharb: yes it would? [12:53:02.0000] it has nothing to do with Define vs Set [12:53:08.0000] Bakkot: you're talking entirely about runtime semantics though [12:53:10.0000] Bakkot: with [[Set]], then `x;` is just `this.x = undefined`, no? [12:53:12.0000] devsnek: they could, sure, but that's not the semantics they actually want [12:53:23.0000] ljharb: right, which does not solve the issue these people are having [12:53:31.0000] Bakkot: hm, what issue are they having then [12:53:34.0000] they are not using accessors or nonwritable properties [12:53:43.0000] ljharb: see https://github.com/tc39/proposal-class-fields/issues/242 [12:53:53.0000] i mean i get that they want it to be a noop, but if it used [[Set]] and `= undefined` wouldn't that just work? [12:54:00.0000] no, it would not [12:54:09.0000] oh because it would override, hm [12:54:18.0000] yeah, it overrides regardless of Set vs Define [12:54:20.0000] so we'd really have to spec `x;` as a noop to fix that, which indeed would be the same with either semantics [12:54:29.0000] (Set vs Define really is not something which comes up that much in most code) [12:54:36.0000] if we're gonna change class fields [12:54:36.0000] ljharb: orrrrr we could spec `x;` as being illegal [12:54:38.0000] can we just get rid of them [12:54:42.0000] altho maybe if we used Set, then we could justify the semantics of `x;` being `if (!(x in this)) { x = undefined; }` [12:54:44.0000] devsnek: no [12:54:55.0000] we can't make `x;` illegal, its already in code [12:55:00.0000] at least my code [12:55:08.0000] and i assume i'm not the only person [12:55:09.0000] s/could/could have/, I guess [12:57:56.0000] Bakkot: thoughts on my last comment? [12:58:24.0000] (not that it will change the Set vs Define outcome anyways) [12:59:21.0000] i think class fields are the only js feature i actively dislike :( [13:01:30.0000] i feel like i missed some big stuff and decorators changed a lot while i was absent [13:01:34.0000] idk how i feel about them now [13:02:24.0000] i think a lot of people feel that way [13:02:40.0000] ljharb: that seems way too complicated [13:02:43.0000] i want decorators over "no decorators", but i reallllly do not like the current second-class magic Modules-only form :-/ [13:03:00.0000] Bakkot: the semantics for "declare the field" would be "the field exists afterwards", seems simple to me [13:04:02.0000] ljharb: except it wouldn't. imagine `Object.freeze(Object.prototype); class A { toString; constructor(callback) { this.toString = callback; } }`. with current semantics, you get the right thing; with your semantics, you would get an error. [13:04:23.0000] ljharb: and it would work if you changed the `toString;` to `toString = void 0;`, which is even more surprising. [13:04:59.0000] ok that's fair [13:05:16.0000] so then short of straight making `toString;` illegal, it seems like we're in the best place already [13:05:32.0000] and doing that is probably not even web compatible at this point [13:06:12.0000] i might just make a node addon that exposes private symbols [13:06:57.0000] ljharb: yeah; I just want to know why `toString;` is legal in the first place [13:08:32.0000] sidebar: I am not convinced that "someone somewhere has written code using this" ought to justify "we can't take it out of this stage 3 feature" [13:08:36.0000] (cc devsnek) [13:08:58.0000] the whole point of having stage 3 vs 4 is to allow changes [13:09:21.0000] fair [13:09:56.0000] if we're gonna make changes though, having to use try catch to check if an object has a private field still feels like a non-starter for the current design :( [13:10:36.0000] why? [13:10:52.0000] you have to use try catch to check if a string is valid JSON, and to check if an object is a Map, and a bunch of other places [13:10:56.0000] doesn't seem that surprising [13:11:23.0000] we really just need a way to test for private fields in terms of ergonomics [13:11:36.0000] none of those are even remotely related to checking if x has a property [13:11:38.0000] I would be on board with `#x in foo` working (without going up the prototype chain, just like `foo.#x` does not go up the prototype chain) [13:11:59.0000] devsnek: "has a property", in the context of private fields, is equivalent to "is of this kind" [13:12:07.0000] which is in fact a lot like "is a Map" [13:12:07.0000] yeah its a whole new thing [13:12:12.0000] which is why i think its a non-starter [13:12:13.0000] but oh well [13:12:16.0000] Bakkot: fwiw tho that try/catch requirement is terrible [13:12:27.0000] so yeah `#x in foo` working would be *amazing* [13:12:44.0000] but really we need a "has own" operator, that also works with private fields [13:12:52.0000] ^ [13:13:03.0000] `foo has x` or `foo has #x` or something. but we're out of keywords. [13:13:04.0000] i do like the throw though personally [13:13:13.0000] i like the throw behavior where it currently exists [13:13:18.0000] i don't like that there's no non-throwy way to check [13:13:26.0000] hm, `has` would be kinda nice, true [13:13:27.0000] ljharb: we can still add contextual keywords *shudder* [13:13:40.0000] `K own in O` [13:13:50.0000] `in foo has x` [13:14:02.0000] lol [13:14:07.0000] throwing by default feels so weirdly opinionated [13:14:08.0000] i think ASI would be a problem for leading `in`? [13:14:31.0000] `foo...has...x` [13:15:04.0000] `symbol in foo` :( [13:15:16.0000] (x\n in foo); has x [13:15:18.0000] `foo with x` [13:15:32.0000] ooo `with` returns? [13:15:33.0000] `foo super in x` [13:15:53.0000] `foo in.own x` :-p [13:16:01.0000] i've got a whole closetful of bikeshed paint here [13:16:02.0000] seems fine [13:16:13.0000] as long as grammar isn't terrible w/e [13:16:34.0000] /me . o O ( `x of foo` ) [13:24:57.0000] the saddest part of the `with` construct really is the fact that it's occupying such a useful keyword [13:25:32.0000] (although that's probably more relevant to the resource mgmt discussion but still) [13:37:33.0000] one day ASI, one day i will be freed to use keywords not from the 90s [13:39:56.0000] yolo https://www.npmjs.com/package/@snek/private [13:45:54.0000] lol [15:27:08.0000] devsnek: bug report, doesn't work in a browser [15:27:30.0000] ljharb: with the right combination of flags it might work in chrome :) [15:27:56.0000] "this website best used with chrome 74 and these seventeen flags" [15:28:21.0000] wouldn't even be the most outrageous requirement i've seen [15:29:24.0000] the projectors my school got last year require activex to send telnet commands, so you have to use internet explorer