2019-12-03 [23:23:56.0000] I've been doing some experiments with radix trees for unicode name literals in strings [23:24:24.0000] it looks like a serialized map in memory would be around 800kb [23:25:29.0000] significantly less than the 4mb of a hashmap [23:26:43.0000] mathiasbynens: ^ [23:27:12.0000] devsnek: makes sense [23:27:36.0000] i don't remember the exact numbers you were talking about before, but does that sound more reasonable? [23:27:57.0000] i mean, less is better [23:28:05.0000] i didn't provide any specific numbers [23:28:17.0000] but imho, even that 800 kb doesn't pay for itself [23:28:55.0000] this would be a feature that minifiers "undo" anyhow [23:29:48.0000] yeah, that's not a trivial cost to users, relative to the benefit they'd get [23:29:54.0000] still want to make a babel plugin for it tho [23:29:58.0000] or, ideally, have someone else do that [23:30:09.0000] ( [23:30:23.0000] "users" meaning end users, i.e. people who open websites, not people who design them [23:30:24.0000] ) [23:30:46.0000] yeah i don't think it improves much for websites [23:31:13.0000] but it pops up enough for me that i have revisited the idea once or twice :P [23:31:20.0000] make the plugin! [23:31:28.0000] i looked at that a few months ago actually [23:31:56.0000] i couldn't figure out how to test it or develop it [23:32:10.0000] should ask in the babel slack; they were pretty responsive, last I checked [23:32:25.0000] perhaps i'll take a look later [23:32:47.0000] i think the main problem is that i wouldn't bother with it if it was a babel plugin [23:32:52.0000] since i rarely ever use build tooling at all [23:32:53.0000] adding new syntax is a bit tricky; in some cases you can just extend the parser, but usually you'd have to actually add it to the parser and then the plugin just enables or disables the option [23:32:59.0000] mm, yeah [23:35:08.0000] i bet variable length encoding the codepoints could make the blob smaller, but that would make parsing take longer [23:58:32.0000] you could just start using build tooling [00:02:54.0000] hmm using finite state trees i get the map down to 200kb [00:03:29.0000] the data isn't searchable in place though [00:03:40.0000] at least not with the lib i'm testing [00:04:06.0000] and it assumes all the values are 64 bits, instead of 32 bits [00:04:42.0000] i'd imagine specializing for the data and keys we have it could be 200kb and also support lookups in place [13:34:03.0000] Hello! Can someone add me as a delegate so I can access the queue? [13:34:19.0000] cc akirose [13:35:40.0000] https://github.com/tc39/Admin-and-Business/issues/12 😝 [13:35:42.0000] on it [13:37:29.0000] Reopened issue with proper names :) [13:37:55.0000] JemYoung: done [13:38:03.0000] Thanks! 2019-12-04 [10:50:11.0000] /me hello! I think I should be joined properly now. [10:51:06.0000] tantek: you're here in the public channel :-) ping bterlson for an invite to the private one [10:51:22.0000] /me thanks ljharb! [12:41:45.0000] Hi everyone, I am new comer from UC Browser, Alibaba. Also new to the IRC tool. [12:47:27.0000] We’re (myself, Yulia, Shelley) stuck downstairs. Could anyone find someone to help us come up? [13:03:38.0000] bnb: wrong channel, but someone's on the way [13:03:40.0000] zuojian: welcome! [13:04:02.0000] Thank you - I was told to post it in all the channels 😅 [13:04:33.0000] lol then o7 [13:05:36.0000] haxjs: are you in the call? [13:22:10.0000] I had an idea for a possible class enum block syntax. Looking for a second opinion on this approach to enumerations. https://gist.github.com/metanomial/5cda898056970287b8b85424934bbddf?ts=4 [13:23:10.0000] metanomial: i replied to your discourse with links to two enum proposals; have you reviewed those? [13:23:23.0000] I did [13:23:43.0000] and how does your proposal differ from those? [13:44:40.0000] Both of those proposals are syntactic sugar to declare objects of constants. The second proposal was a little more flexible, allow enumerators to be passed to constructor functions before definition. The idea I linked above is syntactic sugar for quickly constructing static fields/instances in a class. I have updated my gist to show static [13:44:40.0000] instances in the current class syntax. [13:46:04.0000] metanomial: ok so it seems like yours is restricted to when you want your enums to be instances of the same class, which imo doesn't match many use cases for enums [13:46:27.0000] metanomial: iow to me, it doesn't seem like "sugar for static properties that are always instances of the class" is worth syntax [13:58:34.0000] I think I agree - that takes almost exactly as many characters to do in today's syntax, with `Color.RED = new Color(0xff0000);`/etc immediately following the class definition. [13:59:13.0000] And I agree that's not what many (/most?) of the calls for "enums" are asking for. [13:59:22.0000] and with class fields you can do `static RED = new Color(0xff0000)` [14:41:16.0000] Fair points. Here is a second example showing demo usage. https://gist.github.com/metanomial/5cda898056970287b8b85424934bbddf?ts=4#file-example2-js [14:49:09.0000] metanomial: So that looks like you're implementing a lot of useful enum functionality in userland; the enum itself is providing almost no additional benefit here besides moving the instance declarations around in the file. [14:49:44.0000] If we're doing enums, a lot of this stuff should be provided automatically, imo. [14:54:49.0000] Another fair point. I'll think on it a bit. Thank you for the feedback 2019-12-05 [16:56:26.0000] is there a specification anywhere for //# sourceURL=... ? [16:56:52.0000] jwalden: source maps might be in html, but def aren't in JS [16:56:52.0000] jwalden: it's a google doc [16:57:05.0000] do you still want it? [16:57:13.0000] michaelficarra: yeah, I could use it [16:57:42.0000] jwalden: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit [16:57:44.0000] michaelficarra: it looks like Firefox just is not going to enforce *at all* //# sourceURL=... if it appears inside a function body, unless that function body is "use asm" or some other very obscure edge cases [16:57:58.0000] presumably most people just do it top-level and are fine, but [16:58:22.0000] inside eval [16:58:27.0000] jwalden: find "Linking generated code to source maps" in that doc [16:59:53.0000] devsnek: inside eval you have just a regular Script, so e.g. eval("function f() {\n//# sourceURL=https://example.com/foo.js\n}\nalert(new Error().stack);") would trigger what I'm talking about [17:00:11.0000] oh wow [17:04:06.0000] michaelficarra: what's supposed to happen if I have more than one //# sourceURL=... comment in a script? [17:04:19.0000] michaelficarra: does the last one apply, or the first one, or what? [17:04:37.0000] jwalden: I know *of* the spec, I am not an expert or the author [17:04:46.0000] bah :-) [17:05:03.0000] also, it's hard to call it a spec [17:05:19.0000] it's a loosely-written design doc [17:05:50.0000] yeah :-| [17:06:00.0000] SpiderMonkey appears to just apply the last one observed [17:09:46.0000] jwalden: if you know nick fitzgerald, you may be able to learn more [17:10:04.0000] :-) I could poke him for sure [17:11:05.0000] good luck [17:11:15.0000] this is of course not how specifications are supposed to work! [17:11:19.0000] /me cantankers [17:12:59.0000] jswalden: I've been trying to get the Sentry folks to adopt that doc and add some rigour [17:13:11.0000] they are heavy users of source maps and it would be in their interest that they work well [17:13:34.0000] CSP is an _actual_ spec and has similar problems [17:13:37.0000] if you learn of such an effort, let me know, I'm interested [17:14:11.0000] CSP doesn't count [17:14:28.0000] why not it should [17:23:00.0000] sadly, my suspicion is I ought not let myself get nerd-sniped by this, given I was looking into very different issues 2019-12-06 [13:24:12.0000] anyone know the historical reason for this? in 14.3.1 Static Semantics: Early Errors: "It is a Syntax Error if ContainsUseStrict of FunctionBody is true and IsSimpleParameterList of UniqueFormalParameters is false." (https://tc39.es/ecma262/#sec-method-definitions-static-semantics-early-errors) [13:24:12.0000] i.e. why (function() { return { method(...foo) { "use strict"; } } })() isn't valid [13:26:53.0000] rickbutton: parsing difficulties [13:27:21.0000] ah, gotcha, thx [13:27:33.0000] rickbutton: because otherwise the engine has to parse the entire arg list - which might include default args, which might themselves create functions that may or may not be in strict mode - before getting to the body's strict pragma, which then might mean it needs to interpret all that arg stuff differently [13:27:38.0000] that's my understanding, at least [13:28:08.0000] right, that makes sense [13:34:36.0000] Bakkot: btw that bug in chrome, it looks to be evaluating it without the side effect detection ebaled [13:34:39.0000] enabled* 2019-12-07 [18:38:16.0000] devsnek: huh. I wonder why [18:38:53.0000] Bakkot: weird devtools logic [18:39:06.0000] it looks like it doesn't enable it if it's just a member expression [18:39:11.0000] which is very odd [18:39:37.0000] and why I couldn't repro in my node thing 2019-12-09 [22:20:45.0000] devsnek, Bakkot: what's the Chrome DevTools bug? please file it if you haven't already, thanks [00:21:52.0000] mathiasbynens: reported already https://bugs.chromium.org/p/chromium/issues/detail?id=1031243 [00:24:40.0000] mathiasbynens: devtools seems to be doing a local parse of the input and using that to decide if it has side effects [00:25:14.0000] which seems counter intuitive to the existence of v8's side effect detection [01:34:45.0000] devsnek: agreed... we should just rely on V8 here instead of trying to "guess" with broken heuristics [01:35:34.0000] we're fixing it! thanks for pointing that out [11:37:40.0000] Can someone explain https://www.ecma-international.org/ecma-262/10.0/#sec-block-level-function-declarations-web-legacy-compatibility-semantics to me, please? In particular, I've got the following code: https://pastebin.com/Zx0VNUaj and I want to know where its behavior is specified [11:38:50.0000] it seems like it'd have to do with (3.) in that list, but it does say that "No other declaration of f that is not a var declaration occurs within the function code of g" - there is a `let bar = 3` which fails that condition [11:40:02.0000] avp the notes at the beginning of the section are just of historical interest - they're documenting cases where browsers agreed before this was specified in ES2015 [11:40:08.0000] the actual changes are in B.3.3.1 [11:40:21.0000] sidebar: you should use the living spec at https://tc39.es/ecma262/#sec-block-level-function-declarations-web-legacy-compatibility-semantics [11:41:06.0000] Bakkot: thanks, i'll try and use that section to reconcile my mental model [11:42:10.0000] B.3.3 is notoriously the most cursed section of the spec though [11:42:20.0000] so don't feel bad for being confused :p [11:43:34.0000] the basic semantics are: when you have `function f(){ x() }` within a block, and you could replace that with a `var f` without getting a syntax error, then the semantics of the function are 1) you add a `var f;` to the top of the _containing_ function, 2) you add a `let f = function(){ x() }` at the top of the containing _block_ and 2) when control reaches the actual function declaration within the block, you read from the `let f` and [11:43:35.0000] write to the `var f` [11:43:43.0000] ugh, that second 2) should be a 3) obviously [11:44:46.0000] Bakkot: that helps a lot - deciphering the intent of B.3.3.1 was daunting [11:57:20.0000] avp also you should use strict mode so this doesn't happen :P [12:01:55.0000] JSC has bugs for B.3.3 early errors that I've been too scared to fix [12:04:02.0000] everyone does [12:04:04.0000] the spec does [12:04:25.0000] https://github.com/tc39/ecma262/issues/913 etc [12:19:12.0000] it's functions all the way down [13:13:46.0000] > dysfunction all the way down [13:13:46.0000] FTFY [13:38:59.0000] Object.assign(Object.prototype,{get:()=>{}, set:(v)=>{}, value:undefined}); wrecks so much [13:39:22.0000] it kinda seems like you have to use null prototypes to guard against it [13:45:47.0000] bradleymeck: ? what key are you trying to defineProperty there? [13:49:01.0000] none, just if Object.prototype has all 3 of those keys Object.defineProperty stops working unless you use null prototypes like Object.defineProperty(obj, 'propname', {__proto__:null, value: 'value'}) [13:49:20.0000] since it sees stuff up the proto chain and says it can't be both an accessor and data prop [13:49:40.0000] was staring at my node pr and noticed we don't guard this currently [13:49:43.0000] ohhhhh wow i just realized what you mean [13:50:02.0000] i wonder if it'd be web compatible to change that somehow [13:50:29.0000] well idk but running that little script on all my open tabs killed all of them except some static sites [13:50:51.0000] likely we can't change it though [13:51:59.0000] we can't make it be own properties i'm sure, but i wonder if we could effectively make it be "Get" but stop before Object.prototype [13:52:16.0000] that seems pretty weird too [13:52:18.0000] better question [13:52:24.0000] who is doing Object.assign(Object.prototype,{get:()=>{}, set:(v)=>{}, value:undefined}) [13:52:52.0000] me, checking to see if we survive it in node (we don't) [13:53:15.0000] once you get implicit set hooks things look pretty dicey about data exfiltration across modules [13:53:32.0000] but đŸ€· this is more just locking down stuff to survive craziness [13:53:57.0000] we had a couple of people snooping internals and doing bad things in the long past and we started to move to primordials in part because of that [13:54:56.0000] i remember symbol polyfills were able to patch node [13:55:08.0000] so that util.inspect and stuff worked with them [13:55:52.0000] causing it to always error by filling out both get/set always or value is probably good enough honestly [13:56:39.0000] ideally we would use some null proto shenanigans but slowdown on benchmarks is pretty bad [13:57:47.0000] i just don't see why its worth guarding against [13:57:53.0000] bradleymeck: another alternative is that the error for "no get/set + value" could be made to only throw when get/set is not undefined, instead of just present [13:58:13.0000] bradleymeck: that way you'd always be able to locally override the shenanigans with `get: undefined, set: undefined` for data properties [13:58:25.0000] altho i guess that wouldn't protect you for accessors [13:58:46.0000] devsnek: same thing as why any other part of the runtime is worth being robust [13:59:12.0000] i don't really get the overall goal tbh [14:00:18.0000] user code shouldn't be able to break the platform? [14:00:57.0000] mostly its to get reliable behavior when things go wrong, node has access to things like shell execution and often people send authorization strings to node in various ways, you don't want people snooping on strings and you don't want shell execution to happen. it gets hard to understand what a user can accidently load (see all those malicious packages people install) and have it undermine the default platform APIs [14:01:40.0000] malicious code can just `require('inspector')` and read every value of every variable in the entire codebase [14:01:49.0000] so, make it just ignore anything strange and/or make it survive anything strange to avoid leaking data or allow accidental execution. accidental execution is hard to avoid in JS [14:02:07.0000] devsnek: not if you use a policy that doesn't allow it [14:02:17.0000] which is why we have started making efforts to use em [14:02:51.0000] assuming the code you've explicitly pulled in is malicious is like [14:03:11.0000] you've already lost [14:03:21.0000] you either need full isolation [14:03:25.0000] devsnek: we work with developers who install 3rd party code all the time. you build up layers of defenses like anything else [14:03:25.0000] or you need to trust the code somehow [14:03:43.0000] even with full isolation you can get confusion problems that make the isolated payload malicious [14:04:08.0000] seems like an inherently losing battle tbh [14:04:42.0000] devsnek: the entire concept of SES is winning that battle, isn't it? [14:04:46.0000] or attempting to [14:05:00.0000] đŸ€·đŸ» [14:05:08.0000] i think security always will be a race of sorts yea. though i don't think we are really trying to prevent everything, but instead make auditing feasible [14:05:20.0000] i think SES solves a symptom of the problem [14:05:22.0000] not the problem [14:05:48.0000] even reading code line by line myself i'm not fully confident in it not having some odd effect (i had one with a sticky regexp today!) [14:06:09.0000] bradleymeck: wait you had a real use case for the sticky flag?? [14:06:22.0000] ljharb: i saw it being used and i removed it [14:06:30.0000] cause lastIndex was being weird with .search [14:06:55.0000] anyways, i do want to use shell commands so it isn't like i can ever really trust anything [14:08:19.0000] aha [14:08:55.0000] ljharb: the idea was to match the last " in a quoted string but it wasn't working right [14:09:23.0000] misplaced sticky flags won't exfiltrate your tokens [14:10:16.0000] devsnek: no, but it did change a parser and we got bad data that bypassed some checks! [14:15:30.0000] you can always keep structured data structured... bugs exist of course but these systems aren't inherently fallible [14:20:01.0000] devsnek: not all data is provided to you in a structured format; you can't get away from parsing untrusted input sometimes [14:20:36.0000] even if it is structured it can be bad to intake naively ("__proto__" from json payloads) [14:20:54.0000] I mean the output of the parser [14:21:15.0000] it's still the output of the parser, and you can know it may be unsafe 2019-12-11 [23:52:19.0000] if we get tuples in js, advent of code will become a lot easier, because a lot of their challenges use maps of (x, y) [07:12:49.0000] devsnek: why not use literals for those? [07:13:16.0000] new Map([[x,y],[a,b]]) is often forgotten too :( [09:45:47.0000] It is pretty easy to write an n-key map class [09:57:46.0000] Bakkot: it could be easier [09:57:57.0000] sure but you do it once and then it is done [09:58:53.0000] depends on if the base class adds apis [09:59:00.0000] if it adds apis you do it again [09:59:30.0000] if it adds APIs your map will not automatically update to have those APIs, yes [09:59:39.0000] (depending on how they are implemented...) [09:59:40.0000] but no existing applications will break [09:59:48.0000] yup [10:00:25.0000] even if they are implemented through delegating to existing interfaces it might be odd [10:00:37.0000] Potentially yes [10:00:50.0000] like .has could be false but .get could return a value if we add default values that are not undefined [10:00:50.0000] also when I've done this in the past I haven't actually done `extends Map` [10:00:57.0000] interesting [10:01:14.0000] (since it doesn't really keep the interface for map) [12:22:01.0000] bradleymeck: you need identity of the x and y [12:22:22.0000] (x, y) === (x, y) [12:22:24.0000] Symbol.compositeKey would be nice~ [12:22:29.0000] yeah [12:22:38.0000] I guess there's also that frozen proposal [12:22:41.0000] that probably won't go anywhere fast though :( [12:22:48.0000] mine/compositeKey [12:22:59.0000] value types seem to have some momentum [12:25:07.0000] I just hope they allow all types inside [12:34:38.0000] i'd not be ok with that unless they change intent of the proposal a bit [12:34:47.0000] though if they do change stated intent seems doable [12:37:22.0000] it seems kinda useless if it can't hold objects tbh [12:37:50.0000] like private fields, I'd use them every once in a blue moon but not as a generalized pattern [12:39:08.0000] if serializable and stateless is the critical use case holding objects would be problematic. if immutable but allowing state is the critical use case holding refs seems fine. [12:39:35.0000] you can have them without objects inside them even if objects are allowed [12:39:54.0000] and even then, think of JSON.serialize on an object with a function property [12:40:03.0000] er [12:40:07.0000] JSON.stringify [12:40:27.0000] ? [12:42:22.0000] I don't get why one person wanting to restrict it means another person can't also use it more liberally [12:43:09.0000] depends, but if the more liberal use makes it hard to assert the more constrained use holds true in various cases thats usually a reason [12:43:41.0000] I mean it's a trade off either way [12:43:55.0000] the more constrained case literally makes it impossible for the more liberal use case [12:44:09.0000] yea, like you said its a trade off [12:46:10.0000] I feel like the obvious balance would be choosing the difficult case over the impossible case [12:46:23.0000] but people consistently go the other way so đŸ€· [12:47:31.0000] difficult enough to be impossible pretty much is just impossible [12:50:26.0000] if it's an invariant of serialisation you can throw when you hit an object [12:50:34.0000] it doesn't seem too hard imo [12:56:58.0000] devsnek: the reason to disallow objects is that many people are going to look at these things and assume they can treat all of them as immutable and be bitten when that turns out to not be the case [12:57:37.0000] I didn't have that assumption [12:57:59.0000] many other people will [12:58:53.0000] a lot of people also assume const makes the object it holds immutable [12:59:06.0000] like probably at least one a week in ##javascript [12:59:25.0000] should const have not been allowed to point to objects? [13:00:04.0000] I am not entirely clear on why const exists at all, in honesty [13:01:17.0000] variables that can't change [13:01:51.0000] that is a description of the thing, not an explanation of why it exists [13:02:00.0000] const is great, but it is definitely a confusing name [13:02:15.0000] I mean I use it as that enough to justify it as the sole reason for it's existence [13:02:22.0000] I dunno if others do [13:02:37.0000] (i like it because it conveys developer intent to not reassign a variable, which is not sufficiently conveyed by "it doesn't happen to be reassigned at the moment") [13:03:17.0000] in any case my larger point was that no matter what, there will be people who don't understand features because they assume their behaviour instead of actually learning what they do [13:03:52.0000] of course, and that's something we always have to weigh [13:04:01.0000] here I think most people will assume it is deeply immutable [13:05:18.0000] maybe we can make a poll or something [13:07:58.0000] the name itself is definitely bad, but I don't understand folks not taking the time to get used to it [13:08:37.0000] we could just remove the immutability part from them [13:08:43.0000] :P [13:10:00.0000] like, it seems that there are folks that advocate for using `let` and not `const` because `let` itself might've been a better name for what `const` does, but [13:10:49.0000] that's really upsetting to me since at the end of the day, `const`'s behavior is exactly the desirable thing, and the name can be gotten used to... [13:10:50.0000] var was already taken though [13:10:56.0000] yeah that's the thing [13:11:07.0000] I love Scala's `val` / `var` [13:11:18.0000] yeah val's not bad [13:13:24.0000] something I'm a little unclear of the timeline on is the existence of a `const` keyword in browsers [13:13:45.0000] I feel like it existed non-functionally prior to ES6? [13:14:09.0000] but maybe that's some headcanon of mine that developed due to the long implementation window of ES6 [13:14:24.0000] rkirsling: old spidermonkey had its own const and let for awhile [13:14:29.0000] that had different semantics from ES2015's [13:14:34.0000] eventually they fixed it [13:14:36.0000] that must be it [13:14:49.0000] in their "JavaScript 1.7" thing, or whichever version [13:14:56.0000] ahh [13:15:15.0000] old V8 also had it's own let and const [13:15:15.0000] with weird semantics [13:15:15.0000] they weren't allowed in strict mode [13:16:08.0000] ah right that too [13:16:21.0000] i think v8's tho were early ES6 versions [13:16:36.0000] altho maybe SM's were even earlier ones, i dunno [13:17:13.0000] I'm glad node doesn't use harmony flags anymore [13:17:15.0000] lots of breakage [14:00:04.0000] do we have a strong assertion about run to completion semantics in JS written out anywhere/what to do if a host implements a co-routine like Job Scheduler? [14:09:14.0000] e.g. if a host is allowed to have `Promise.resolve().then(()=>{...;bar();...}); foo();` execute `bar()` before `foo()` [14:10:47.0000] if that isn't explicitly forbidden than ES6 has a massive gap [14:11:11.0000] i'm pretty sure it was a quite intentional part of promises that nothing that happens in a then callback can *ever* happen synchronously [14:11:45.0000] TLA changes that slightly, in that if you `await` that promise before calling `foo()`, then bar can happen before foo [14:13:40.0000] ljharb: i'm staring at https://github.com/nodejs/node/pull/30891 [14:14:24.0000] bradleymeck: i mean, `require()` can already "sleep" if the module wants it too [14:14:27.0000] bradleymeck: via node addons [14:14:49.0000] ljharb: thats different though. that PR lets you unwind promises [14:14:55.0000] oh right true [14:14:59.0000] sleep/atomics is fine [14:15:29.0000] even execSync is probably fine since it isn't using exposed machinery even though it does nest JS [14:17:37.0000] but JS that can't share an env [14:22:49.0000] it kind of does due to the streams impl [14:22:56.0000] but not from the process [14:23:10.0000] it just inlines an event loop to resolve streams events [14:23:21.0000] which aren't under the promise-like invariants [14:24:55.0000] that isn't really exposing that stuff to userland though so đŸ€· [14:53:55.0000] bradleymeck: it could never execute the inner bit first [14:54:14.0000] the only thing possible is if foo pumped the event loop, it would happen *during* [14:54:19.0000] but never *before* [14:54:45.0000] actually [14:54:53.0000] I don't know if foo pumping the event loop is allowed [14:54:56.0000] I hope it isn't [14:55:00.0000] i'm not clear on that, if you require out of the inner loop and grab the outer promise and await it [14:55:12.0000] it looks like it would resolve [14:55:38.0000] /me thinks this is esoteric [14:56:26.0000] I think it's safe to assume nothing will ever do that [14:57:44.0000] i never thought modules would delete themselves from require.cache at one point, but they do [14:58:11.0000] i can imagine finding an easier way to do this kind of forced resolve being possible but not obvious 2019-12-12 [20:31:02.0000] ljharb: is `ChainEvaluation` supposed to link to the runtime semantic? [20:31:42.0000] devsnek: um, i'm not sure. which PR was this in and can you link me to the rendered spec? [20:31:52.0000] devsnek: linking generally is handled by ecmarkup [20:31:58.0000] https://tc39.es/ecma262/#sec-optional-chaining-evaluation [20:32:07.0000] `Return the result of performing ChainEvaluation of ...` [20:32:12.0000] ChainEvaluation there doesn't link [20:32:41.0000] i don't think any grammar things link there [20:32:48.0000] see https://tc39.es/ecma262/#sec-runtime-semantics-arrayaccumulation for example [20:33:31.0000] (by "link there", i mean, i don't think that category of thing is autolinked in general terms) [20:33:39.0000] ic [20:33:40.0000] unfortunate [20:33:49.0000] also in ChainEvaluation [20:34:05.0000] please file an ecmarkup bug if you think they should autolink tho :-) [20:34:07.0000] there are productions like `OptionalChain : OptionalChain arguments` [20:34:14.0000] and then it says "evaluate OptionalChain" [20:34:33.0000] like i know it is referring to the second one [20:34:38.0000] but it isn't immediately obvious [20:35:31.0000] an editorial PR would be helpful :-D [20:35:51.0000] not trying to pass the buck every time, just about to head out and can't track it myself rn [20:36:25.0000] np [20:40:04.0000] I think those are ecmarkup concerns [20:41:24.0000] cause in particular ChainEvaluation(...) was changed to ChainEvaluation of ... to align with current editorial practices but that incurred a loss of linkability [20:42:22.0000] er sorry the latter is separate [20:43:24.0000] that we had to fix because there's a very specific was the spec differentiates parent nonterminal Foo from child nonterminal Foo [20:44:08.0000] it is meant to be as intuitive as one could reasonably hope for but if you can think of a way to describe it in a Notations section that might be cool [20:44:51.0000] optional chaining and nullish coalescing unflagged in engine262 🎉 [20:44:52.0000] *...very specific way... [20:45:14.0000] 🎉 [20:45:17.0000] this one is my favourite though https://github.com/engine262/engine262/commit/7e7692de0050c5149f0dfd553c67bdb565b1174c [20:45:53.0000] nice [20:46:02.0000] would be nice if we had like `OptionalChain_a` and `OptionalChain_b` [20:46:39.0000] reminds me of https://trac.webkit.org/changeset/240686/webkit [20:46:57.0000] lol [20:47:41.0000] Yeah _a and _b could be reasonable [20:48:01.0000] In general, a syntax-directed operation will be defined in many clauses, so what would you auto-link to? [20:48:18.0000] the general heading [20:48:31.0000] https://tc39.es/ecma262/#sec-optional-chaining-chain-evaluation [20:48:53.0000] yes, for that case there's only one clause, but in general there might be several. [20:51:24.0000] wdym there are like six there [20:51:52.0000] "clause" = section, say [20:52:53.0000] the spec doesn't really have a word for the construct that there's six of, but I'd call them 'definitions' [20:58:45.0000] or emu-grammar+emu-alg pair, if I need to be explicit [23:05:18.0000] I think sometimes eval rules paired with parse nodes / productions are referred to as reducers (not in the spec, just seen it elsewhere) [23:14:01.0000] does anyone know what production accepts the strings '\8' and '\9' in sloppy mode? Chrome and FF both allow them (treated as identity escapes), but I’m having trouble finding an avenue that explains it. possibly this is a spec/web reality divergence, but I feel like I’m just missing something since it’s easy to get confused when looking at annex b modifications. [23:31:09.0000] Oh, they allow \8 and \9 in strict mode too o: [23:38:59.0000] here’s my notes from trying to figure this out as a gh gist to avoid making too much noise in here: https://gist.github.com/bathos/09171830ee14d3d7a0d9393eb07f64ca [06:18:21.0000] looks like test262 only has \8 in regex literals. [06:19:21.0000] but test262-parser-tests has 2 occurrences, and they're both under fail/ [07:10:30.0000] (bathos ^) [07:31:59.0000] thanks — I take it that confirms the interpretation that \8 and \9 being permitted as identity escapes in Chrome/FF is off-spec [10:59:57.0000] it's possible test262-parser-tests is wrong; I tried to be accurate with all of them but I do not have access to any way of formally verifying their correctness [11:04:03.0000] ah. well, we came to the same conclusion, anyway, which seems like a data point. [11:04:10.0000] though this came up a while ago and I think the logic in this comment is still correct: https://github.com/jquery/esprima/issues/1502#issuecomment-230672053 [11:06:47.0000] yeah, that’s pretty much 1:1 with what I wrote in the gist link when trying to find all the paths [11:13:49.0000] should probably open an ecma262 issue if there isn't one already [11:14:30.0000] I think this was lost in the move from the old bug tracker: https://web.archive.org/web/20141214073322/https://bugs.ecmascript.org/show_bug.cgi?id=1553#c2 [11:14:35.0000] also https://mail.mozilla.org/pipermail/es-discuss/2013-March/029403.html [11:15:03.0000] https://github.com/whatwg/javascript/issues/12 [11:15:07.0000] etc [11:23:21.0000] does anyone know if js shift is going to track 2019 and 2020 updates [11:32:05.0000] yes, once we have time [11:32:17.0000] assuming you mean https://shift-ast.org/index.html [11:33:04.0000] ast spec for 2019 is done; ast spec for 2020 will get made once es2020 is done [11:57:15.0000] I'm looking for parsers to vendor into engine262 [11:57:30.0000] shift looks the best so far but not updated since 2018 [11:57:41.0000] I could probably help out with updating it [12:00:23.0000] what does "vendor" mean when used as a verb? [12:00:37.0000] jmdyck: copy into my repo [12:00:49.0000] tx [12:01:29.0000] I'm really not enjoying the "extend acorn" approach I currently use [13:09:40.0000] devsnek: it should be pretty easy to update; there were very few syntax changes in 2019 [13:09:57.0000] happy to help with that if you actually want to try 2019-12-13 [10:40:38.0000] https://tc39.es/ecma262/#sec-numberbitwiseop seems a bit circular [10:40:42.0000] step 3, i mean [10:42:16.0000] & is specified in terms of Number::bitwiseAND which is specified in terms of & [10:42:59.0000] "applying the bitwise operator op" tho isn't the same as how `&` is specified, is it? [10:43:16.0000] What does that phrase mean? [10:43:49.0000] perhaps we're missing an explicit definition for it - but the intention i think is to do math [10:44:17.0000] yeah, i think that has to be the intention, [10:45:02.0000] ie if the op is &, it should do what previous editions did here: http://www.ecma-international.org/ecma-262/#sec-unsigned-right-shift-operator [10:45:13.0000] where it just says "compute rnum & 0x1F" [10:45:44.0000] so maybe that detailed info for each op that's in steps 7 and 8 of the last edition needs to be restored somehow? [10:46:31.0000] wow, here's what the previous edition says about bitwise AND: http://www.ecma-international.org/ecma-262/#sec-binary-bitwise-operators-runtime-semantics-evaluation [10:47:11.0000] right, that's probably where the bigint proposal got the prose from [10:47:13.0000] basically the same thing only instead of "op" it's called "@" [10:47:15.0000] love it [10:47:33.0000] sounds to me like not a new bug, if it's a bug :-) [10:47:46.0000] no indeed :) [10:47:54.0000] but if you want to make a PR that makes that clearer that'd be fine with me [10:48:21.0000] right shift has a clearer definition in old editions than && does [10:48:23.0000] * & [10:49:04.0000] hmm. BigInt::bitwiseAND is specified in more detail. Although ... too much detail for my brain [10:49:25.0000] I don't think I should work on this, it probably isn't bothering anyone else [10:49:40.0000] lol k [10:49:45.0000] thanks for bringing it up! [13:21:12.0000] https://tc39.es/ecma262/#sec-jobs-and-job-queues states that Jobs can be interleaved, but it does not clarify if that also includes preemption [13:21:15.0000] mmmm [13:22:19.0000] jobs must be dispatched in the correct order [13:22:37.0000] i guess it depends on your definition of "dispatched" [13:22:58.0000] yea, but in RunJobs the host can determine the order [13:23:08.0000] i don't see anything that implies a job can be paused entirely [13:23:21.0000] but that word is "interleaved"... oddly placed [13:23:52.0000] hmm [13:23:53.0000] `No other Job may be initiated until the currently running Job completes` [13:24:35.0000] that answers my question at least [13:24:39.0000] yes, "completes" i assume means all the spec work / eval runs to completion as in end of source text [13:25:50.0000] at the very least, this means the require(esm) thing is against the rules [13:26:17.0000] yea, reading the other things like await they never affect jobs, only the execution context stack [13:26:55.0000] maybe we should explicitly state preemption of the entire job is not allowed [13:27:06.0000] interleaved makes it a bit confusing [13:30:59.0000] PerformEval is a trip [13:32:29.0000] step 18 of PerformEval annoys me [13:32:31.0000] i should open a pr [13:38:45.0000] why does RunJobs offset execution cleanup [13:38:58.0000] execution contexts are cleaned up in the next iteration [13:39:25.0000] is this just for compat with InitializeHostDefinedRealm [13:40:09.0000] devsnek: isn't the Function null for `var`? [13:40:21.0000] hmm? [13:40:30.0000] > step 18 of PerformEval annoys me [13:40:40.0000] oh [13:40:53.0000] 18. Set evalContext's Function to null. [13:40:56.0000] uhhh [13:41:08.0000] for one of the two eval call types, eval's frame is missing that eval was called [13:41:24.0000] it doesn't matter that much except for when building up stack traces [13:42:39.0000] i think its for direct calls [13:43:31.0000] yeah it is [14:05:02.0000] In my limited use of `BigInt` in Chrome and Firefox, I've found myself repeatedly writing Math.abs, Math.min, and Math.max equivalents. Is there any proposal to add something like BigInt.abs, BigInt.max, etc? [14:05:30.0000] one of the things on my todo list is changing those math methods to accept bigints [14:07:46.0000] If, say, Math.max were changed to accept BigInt values, what happens if you mix Number and BigInt arguments? [14:07:55.0000] it would throw [14:08:08.0000] actually [14:08:18.0000] relational comparison works on numbers and bigints [14:08:36.0000] But what should the return type be then? [14:08:36.0000] Math.max and Math.min could work on inputs containing both [14:08:44.0000] Number|BigInt [14:09:02.0000] well really [14:09:09.0000] a union based on the types you pass in [14:09:28.0000] So `Math.max(3, 5n)` would return `5n`, but `Math.max(5, 3n)` would return `5`? [14:09:33.0000] That seems like it could cause problems [14:09:35.0000] đŸ€·đŸ» [14:09:42.0000] it doesn't exist yet [14:09:45.0000] lots of discussions to be had [14:09:51.0000] making math methods work with bigint is something on my list [14:09:51.0000] i might actually draw something up for february [14:10:12.0000] i'd be happy to work with you on that [14:10:22.0000] cool, i'll ping you in the next few weeks [14:10:25.0000] 🎉 [14:11:16.0000] I think they should throw if types are mixed; yes, relational ops work on mixed inputs, but their return type isn't numeric; all the ops with numeric return types throw on mixing partially to avoid answering this question. [14:11:36.0000] ^ that does seem to be the precedent, I agree [14:12:20.0000] i think there's a few cases where we can hit a more useful bar than that - but yes, that is the precedent [14:12:42.0000] in general, anything where you'd lose information when using a Number above MAX_SAFE_INT is something that throws - not just mixing types [14:12:57.0000] relational comparison isn't a place like that, so it doesn't throw [14:13:57.0000] Wouldn't it be less error-prone and more readable to just add `BigInt.abs`, `BigInt.max`, etc. static methods? [14:14:16.0000] maybe(tm) [14:14:22.0000] i'd rather use the existing methods [14:14:25.0000] it's cleaner imo [14:14:30.0000] there's a lot of bikeshedding to be done though [14:14:53.0000] Moving away from the static methods entirely, here is an alternative idea for BigInt absolute value: https://gist.github.com/metanomial/18695b95517d0b78bb882ffe78ce16dd?ts=4 [14:15:37.0000] if math didn't already exist i'd be all over that [14:16:30.0000] Why not just leave Math to Number types? [14:16:51.0000] metanomial: that's something we'll have to consider, but it's much nicer to have "math" methods be able to do *math* with all the number types :-) [14:16:59.0000] because math isn't about number, math is a pure thing [14:17:26.0000] well it was pure until -0 came around [14:17:56.0000] A bunch of the math stuff doesn't make sense for bigints [14:17:59.0000] cos, etc [14:18:32.0000] also true [14:18:33.0000] (or at least acos) [14:18:34.0000] Math as a general purpose set of methods would probably be more useful if there were well known symbols for describing "number" types and operator overloading [14:18:37.0000] and those would continue to throw [14:19:26.0000] the entire definition of math rn is pretty scary [14:19:32.0000] but yeah basically the options are something like 1) make some of the math methods support bigints where it's intuitive, 2) keep Math for Number, and add BigInt static methods, setting a precedent for BigDecimal as well, 3) add bigint and number prototype methods and effectively deprecate the math methods (seems weird to me), 4) do nothing [14:19:51.0000] `Each of the following Math object functions applies the ToNumber abstract operation to each of its arguments (in left-to-right order if there is more than one). If ToNumber returns an abrupt completion, that Completion Record is immediately returned.` [14:19:58.0000] fun prose [14:20:15.0000] Opt 4 is a terrible option. I'm going to be writing BigInt utilities to the end of time [14:20:27.0000] lol [14:20:33.0000] metanomial: i agree [14:20:37.0000] whatever the case [14:20:51.0000] we should definitely support clz32 [14:20:53.0000] :D [14:24:25.0000] I think 2 may be the most reasonable given the lack of "integer math" ops to this point (like Bakkot was saying) [14:24:40.0000] 1 would probably be fine with ample throw cases though. [14:25:13.0000] rkirsling: right, i think 1 or 2 are the two options to suggest, once the committee agrees on the problem :-) [14:25:13.0000] rkirsling: i have a preference for 1, because it just doesn't make any sense to me that "Math" doesn't work on bigints [14:25:29.0000] rkirsling: but maybe after i audit all the math methods and come up with a table, i'll change my mind, i dunno [14:25:41.0000] i'm also a fan of 1 [14:25:48.0000] yeah I'm not opposed [14:26:09.0000] we definitely need some solution [14:26:40.0000] and something that allows a path for bigdec would be good (whatever that means) [14:26:51.0000] Math.clz32(1f) [14:26:59.0000] or is that 1d [14:27:52.0000] wow I did not realize that already existed [14:28:05.0000] rkirsling: right, potential conflicts with BigDecimal would be unacceptable [14:32:34.0000] I feel like opt 1 could lead to obscure bugs. You could have an instance where a collection of `{Number|BigInt}` has been getting passed to Math.xyz successfully for a while, because the collection by serendipity was all of one type. But then after an unrelated code change, the collection suddenly starts holding mixed types and `Math.xyz` throws [14:32:35.0000] errors about it. [14:33:34.0000] metanomial: the collection changing type unexpectedly would break every option [14:35:44.0000] But it wouldn't *change* type. The developer could have documented that the collection was `{Number|BigInt}`, and have been unsafely passing the collection through `Math.xyz`. Then at a later time, a distance change in code causes the bug to come to a head. [14:36:07.0000] metanomial: right but that's just a bug [14:36:23.0000] metanomial: it could be documented as just Number and still suddenly start receiving a bigint [14:37:41.0000] My point is that it could become difficult to debug. `Math.xyz` would accept `{Number|BigInt}`, and the collection would be of type `{Number|BigInt}`, and yet it would be throwing an error. [14:38:20.0000] i'm confused about what this bug is [14:38:30.0000] but this doesn't sound like the fault of Math.xyz's accepted types [14:38:32.0000] given the precedent for mixing to throw, I don't think it'd be very easy to have such a collection without a lot of conscious guarding [14:38:48.0000] i'm not clear on why it's difficult to debug [14:39:24.0000] I'll write up a quick example [14:39:26.0000] you'd get an exception that you mixed a bigint and a number, and you'd trace it back to where some caller was assuming it wouldn't be mixed [14:40:54.0000] thanks! 2019-12-14 [18:22:04.0000] ljharb: My hesitancy about opt 1 was probably unfounded. I messed around with mixed-types-throws a bit, and superficially it seems like it is always easy enough to debug. [19:37:09.0000] metanomial: that's good to hear, thanks for testing it out [19:38:37.0000] That being said, I still personally favor Opt 2, just for clarity. But it's not hard to get used to Opt 1 [19:53:18.0000] `Math.symbol.`? https://gist.github.com/metanomial/76189a1d82602f6624837641e438d6be?ts=4 [20:02:05.0000] a new protocol seems pretty overkill to me [20:02:14.0000] let alone a dozen [20:02:55.0000] it's too early to focus on the solution tho, that's a stage 1 thing. this isn't any stage yet :-) [23:08:51.0000] is there any difference between `obj?.a?.b` and `(obj?.a)?.b` [23:13:52.0000] i don't think there is [23:30:36.0000] devsnek: not in that case, but `obj?.a.b` and `(obj?.a).b` are different [23:30:44.0000] yes [23:31:59.0000] i really need to stop using estree in engine262 😞 [10:16:07.0000] I often see multiple `Object.definePropert(y|ies)` in groups, and it just makes for ugly code. Would a definition operator shorthand be useful? [10:17:21.0000] `a = "foo"; // [[Set]]` [10:17:21.0000] `a := { value: "foo" }; // [[Define]]` [10:41:35.0000] convenient for some folks (self included), sure. worth the confusion for everybody else ... seems unlikely? [10:45:26.0000] It would make for much cleaner code inside of classes if you could define fields outside of the constructor. [10:50:59.0000] Is that not addressed by the instance fields proposal? [10:51:17.0000] (https://github.com/tc39/proposal-class-fields) [10:53:56.0000] (InitializeInstanceFields -> DefineField -> CreateDataPropertyOrThrow -> CreateDataProperty -> [[DefineOwnProperty]]) [10:55:00.0000] No room for setting configurability, etc there, so maybe that doesn’t help for your case. [11:07:17.0000] Class fields already use [[Define]] semantics. `:=` would just allow additional properties beyond `value` when defining fields [11:13:15.0000] https://gist.github.com/metanomial/e0c56861af0c3cfaf0268c6aa30bdb82?ts=4 [12:46:42.0000] adding that syntax was suggested as part of class fields, to make = be Set and := be Define. [12:46:47.0000] i doubt it would be possible now. 2019-12-17 [10:03:35.0000] Anyone out there have permission to add Labels to ecmarkup PRs? https://github.com/bterlson/ecmarkup/pull/165 should be labelled Bug. [10:27:05.0000] jmdyck: I can. I'm also transferring to tc39/ecmarkup soon hopefully [10:27:42.0000] will it be Someone Else's Problem then? [10:28:12.0000] Presumably ljharb's since he asked! 😂 [10:28:20.0000] :-p [10:28:28.0000] :ohyou: [10:32:02.0000] tx for the label, bterlson 2019-12-18 [07:04:12.0000] didn't object iteration order have a clarification in the past year or so? [08:49:55.0000] bradleymeck: for-in order hit stage 4 last meeting [10:05:47.0000] ljharb: perhaps that "exports" PR in node should specify OrdinaryOwnKeys ordering? [10:06:00.0000] since that doesn't seem to have changed anytime [14:10:43.0000] bradleymeck: it should specify `Reflect.ownKeys` ordering yes, not `for-in` ordering [14:11:06.0000] so own keys doesn't actually specify insertion ordering since it goes to a slot [14:11:42.0000] no? i was under the impression there were only two orderings; for-in (and things that obey it) and whatever ownKeys calls into [14:11:54.0000] but i thought both were insertion order [15:02:06.0000] ljharb: unfortunately not, Reflect.ownKeys is a runtime trap / exotic objects and Proxies (and Modules) don't guarantee insertion order [15:02:16.0000] ah that's true [15:02:23.0000] but for non-proxies and non-exotics? [15:02:31.0000] (which is what package.json would be) 2019-12-19 [16:57:41.0000] i believe that is defined, but that is what OrdinaryOwnKeys is [20:08:50.0000] gotcha [09:20:20.0000] ystartsev: [09:20:23.0000] woops [14:43:15.0000] is the spec for GetSuperBase wrong or something [14:43:59.0000] i'm so confused [14:44:41.0000] `super.x` returns a reference whose base is the prototype of whatever the superclass is [14:45:32.0000] so if you did `super.x()` [14:45:45.0000] it would call x with a this value of `Object.getPrototypeOf(superclass)` [14:45:53.0000] er [14:46:10.0000] i'm so confused lol [14:52:44.0000] oh ok this was a fun bug [14:53:23.0000] https://gc.gy/44500989.png 2019-12-20 [16:15:13.0000] it’s Object.getPrototypeOf(homeObject), rather than superClass, where homeObject is the original obj where the method was declared, regardless of current call site [16:18:58.0000] https://gist.github.com/bathos/edc8d240c4ebc94ec1909ce73f953953 [16:19:53.0000] the _this_ value is always the same as what it would have been [16:20:16.0000] the super ref base is about property lookup. the receiver is not the super ref base [16:23:05.0000] - bv / baseValue - where to start property lookup from [16:23:07.0000] - thisValue - receiver value to use when invoking [[Get]] and [[Set]] [08:44:07.0000] 👋 noob question here - what does it mean for an object to be `frozen`? I don't see a definition in the terminology doc [08:55:42.0000] mpcsh: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze [09:17:49.0000] rkirsling: thank you! [09:32:23.0000] sure! [11:41:52.0000] leobalte-: is the test262 ci supposed to list out which tests it runs? it looks like none of the engines are running any tests [11:42:26.0000] ci_test.sh i mean [11:49:51.0000] mpcsh: there's also `Object.isFrozen` [13:52:14.0000] devsnek: the report has been stale for one month as of today, I meant to ask about it [13:52:29.0000] oops I lied [13:52:36.0000] it is literally back today [13:52:49.0000] i just noticed when i had that bug with engine262 yesterday [13:52:53.0000] it didn't fail on the test262 ci [13:53:01.0000] and all the engines have been green lately [13:53:06.0000] even on prs for super experimental stuff [15:51:14.0000] ok so something pretty cool, coverage reports for engine262 help reveal what stuff is missing in test262 [15:51:48.0000] for example calling %TypedArray%.from with no arguments [15:52:04.0000] https://gc.gy/44590917.png [15:55:33.0000] awesome 2019-12-21 [16:42:08.0000] In conjunction with the proposal for a partial application syntax, has a related variation of the `switch` block been proposed? [16:42:53.0000] metanomial: do you mean https://github.com/tc39/proposal-pattern-matching ? [16:42:58.0000] metanomial: the two proposals aren't related tho [16:44:53.0000] Similar, but I was thinking for currying functions [16:46:23.0000] using switch? [16:59:36.0000] Yeah, I was thinking something like https://gist.github.com/metanomial/53873157ab73efa7bd8ffeb070c1ab54?ts=4 [16:59:59.0000] you can switch on true [17:00:14.0000] switch (true) { case name.match(/^d/): ... } [17:01:08.0000] I use this all the time, but it's verbose in a lot of situations [17:19:11.0000] Consider situations with `switch(true) { case value instanceof X: }` or `switch(true) { case Object.hasOwnProperty(target, 'foo') }`, where there is a long list of conditions. [17:19:57.0000] It would be very clean to just do `switch apply(value instanceof ?) { case X: }` and `switch apply(Object.hasOwnProperty(target, ?)) { case 'foo': }` [17:20:25.0000] I don't know if a switch block makes semantic sense here, though [17:21:46.0000] Also I don't know if the partial application syntax would extend to the `instanceof` operator [17:26:39.0000] *edit: `target.hasOwnProperty(?)` [18:19:24.0000] it’s a bit fuzzy what it would mean, given `instanceof` is an observable operation that can have side effects. do you imagine a special path where the prototype chain is only unfurled once, then membership is tested against what has been reported? or is each case a distinct application of instanceof? [18:21:17.0000] (not to mention @@hasInstance ... I’m guessing it would have to be the latter on account of that) [18:22:26.0000] given each expression would be ‘doing work’, to me it seems `if`/`else` tells a clearer story about what’s happening than switch would. [19:59:52.0000] I meant each case being a distinct evaluation of an expression, sequentially. Using the `switch` keyword would definitely lead to confusion, but I think the base pattern is still useful [20:05:14.0000] `let command; apply(command.match(?)) { case /^help\s+(\w+)/: sendHelpMessage(command[1]); }` [20:05:45.0000] I messed that up. Meant: [20:06:04.0000] `let command; apply(command = input.match(?)) { case /^help\s+(\w+)/: sendHelpMessage(command[1]); }` [15:26:23.0000] If the hashbang proposal, (private) instance fields proposal, and the smart pipeline proposal all ended up reaching stage four, would this imply ... nine different lexical goal symbols? [15:26:29.0000] InputElementDiv, InputElementHashbangOrRegExp, InputElementRegExp, InputElementRegExpOrTemplateTail, InputElementRegExpOrTemplateTailOrTopic, InputElementRegExpOrTopic, InputElementTemplateTail, InputElementTemplateTailOrTopic, InputElementTopic [15:30:25.0000] Maybe it wouldn’t. Consume-longest-possible would be enough for private ident vs topic and for hashbang vs topic I guess. [15:31:10.0000] We could somewhat reduce the complexity by having one InputElement nonterminal with parameters. [15:33:59.0000] tangential but even as it stands it's a bit odd that the paragraph says `a TemplateMiddle or a TemplateTail` three times when there's a single TemplateSubstitutionTail to subsume them [15:34:15.0000] (makes me wonder if TemplateSubstitutionTail was added later) [15:37:20.0000] My understanding was that TemplateMiddle and TemplateTail are tokens, and that TemplateSubstitutionTail isn’t, so the syntactic grammar can’t refer to it. [15:38:18.0000] (I’m not sure if this is made entirely explicit but it’s at least implied pretty strongly.) [15:38:44.0000] hmm, that would be surprising because it's only the paragraph text that's doing this [15:40:06.0000] Ah. Yeah, I don’t know for sure. But in https://tc39.es/ecma262/#sec-tokens it does say “[...] TemplateSubstitutionTail [derives] additional tokens” [15:40:57.0000] OTOH, it makes it sound like Template (NoSubstitutionTemplate and TemplateHead) is a token, and it’s really NoSubstitutionTemplate and TemplateHead which are. [15:41:05.0000] that's fair, but the other ones listed in that note are behaving as expected in https://tc39.es/ecma262/#sec-ecmascript-language-lexical-grammar [15:42:51.0000] 'cause we have InputElementTemplateTail :: TemplateSubstitutionTail, and even TemplateMiddle and TemplateTail are ultimately multitoken lexical "components" so I don't think there's any intentionality [15:43:40.0000] hm, not sure I follow. TemplateMiddle and TemplateTail are atomic from the syntactic grammar’s POV. [15:44:05.0000] The derivation of the tv and trv is part of the lexical grammar. [15:45:38.0000] (This would be more clear if references to terminals by name in the syntactic grammar weren’t styled the same as references to nonterminals.) [15:48:42.0000] it's quite possible that I'm misunderstanding that notion of atomicity but in the sentence `The InputElementRegExpOrTemplateTail goal is used in syntactic grammar contexts where a RegularExpressionLiteral, a TemplateMiddle, or a TemplateTail is permitted.` I'm not following why there'd be any issue to s/TemplateMiddle, or a TemplateTail/TemplateSubstitutionTail/ to match what the productions actually say [15:49:58.0000] by atomicity I meant they’re terminals; they are single symbols, not compused by multiple tokens/terminals. [15:50:05.0000] composed* [15:51:10.0000] but TemplateTail itself refers to TemplateCharacters which is recursive and refers to TemplateCharacter [15:51:27.0000] yes — that’s a lexical production [15:51:41.0000] the terminals of the lexical grammar are SourceCharacters [15:51:53.0000] right [15:52:02.0000] the terminals of the syntactic grammar are tokens, a subset of input elements that the lexical grammar produces [15:52:39.0000] but looking at https://tc39.es/ecma262/#sec-template-literal-lexical-components it seems impossible that TemplateSubstitutionTail can have a different status than TemplateMiddle [15:52:50.0000] The input element that the lexical grammar can produce are WhiteSpace, LineTerminator, Comment, IdentifierName, Punctuator, NumericLiteral, StringLiteral, NoSubstitutionTemplate, TemplateHead, TemplateMiddle, TemplateTail, RegularExpressionLiteral, RightBracePunctuator, and DivPunctuator. But that is largely left implicit. [15:52:56.0000] elements* [15:53:06.0000] of those, all but the first three are tokens [15:54:06.0000] but then you'd be saying that https://tc39.es/ecma262/#prod-InputElementTemplateTail is a typo for not listing TemplateMiddle and TemplateTail separately, right? [15:54:25.0000] I just want the description and the implementation to line up... [15:54:32.0000] No [15:54:38.0000] because that’s a lexical production [15:54:43.0000] two colons [15:54:54.0000] The sentence you’re looking at (‘is used in contexts where...’) is listing tokens, not lexical productions. [15:55:56.0000] It just happens that it’s never made fully explicit which lexical productions are tokens — it’s implicit in that those are the ones referenced as terminals in the syntactic grammar. [15:56:28.0000] but then RegularExpressionLiteral in the same sentence isn't a token either, right...? it's in the very same note you called out about "deriv[ing] additional tokens that are not included in the CommonToken production" [15:56:36.0000] There’s no requirement that the lexical grammar’s topmost symbol’s alternatives produce specifically a token of one type. [15:57:08.0000] Why would RegularExpressionLiteral not be a token? [15:57:52.0000] because of the note [15:57:57.0000] the token it derives which is not in CommonToken is RegularExpressionLiteral [15:58:03.0000] right [15:58:04.0000] but [15:59:38.0000] https://tc39.es/ecma262/#sec-primary-expression [15:59:53.0000] RegularExpressionLiteral is referenced here, in the syntactic grammar. That makes it a terminal. 2019-12-22 [16:00:26.0000] I would def agree that it is confusing for this to be left implicit, especially since it currently “half explains” the concept of tokens in play. [16:03:49.0000] If we go to https://tc39.es/ecma262/#prod-TemplateLiteral you’ll see NoSubstitutionTemplate, TemplateHead, TemplateMiddle, and TemplateTail are all terminals of the syntactic grammar, but not TemplateSubstitutionTail, which is just a production of the lexical grammar that acts to group two alternatives that occur together more than once. It’s ‘gone’ at this stage — the productions of the lexical grammar aren’t [16:03:49.0000] parse nodes. [16:06:24.0000] I certainly see that it isn't used there but I don't understand non-post-hoc-ly what blesses the ones that are used [16:06:55.0000] Well, how could it not be? [16:07:29.0000] Is there any way the syntactic grammar could employ TemplateSubstitutionTail as a terminal? [16:07:55.0000] it seems like the only difference between TemplateSubstitutionHead and TemplateMiddle / TemplateTail is that because the latter include raw tokens in their definition, there's no shorter way to refer to them [16:08:42.0000] er "shorter" is a terrible word [16:08:46.0000] more specific I mean [16:09:42.0000] by TemplateSubstititionHead to you mean TemplateSubstitutionTail or Template? [16:09:46.0000] do* [16:09:59.0000] oops yeah [16:10:04.0000] TemplateSubstitutionTail [16:10:25.0000] but also Template in the same way [16:11:10.0000] I may be misunderstanding the thing you see as being off-kilter [16:13:46.0000] But I could say that the ‘blessing’ stems directly from necessity — it’s not arbitrary at least as far as ‘this specific thingie has a unique identity as a terminal symbol within the syntactic grammar’. A TemplateMiddle and a TemplateTail aren’t syntactically interchangeable. [16:14:33.0000] completely don't understand how two productions in 11.8.6 can be said to have a different status from one another if both are further dependent on other productions; you seem to be suggesting a meaningful distinction between NoSubstitutionTemplate / TemplateHead / TemplateMiddle / TemplateTail which "build" something and TemplateSubstitutionTail / Template which simply list alternatives [16:15:02.0000] but I don't know how to see this distinction manifest anywhere [16:16:12.0000] right, a TemplateMiddle and a TemplateTail aren't interchangeable and so the syntactic grammar has had no reason to treat them the same for any purpose, but it seems like all you'd need is such a purpose, and voila [16:16:46.0000] I think that’s a pretty accurate description of what I’m saying, yes. What makes this confusing is that ‘lexical production’ and ‘token’ are two different things, and yet a subset of lexical productions shares names with tokens, and the distinction is not made clear. [16:18:03.0000] okay [16:18:06.0000] The distinction can only be seen implicitly by actually analyzing which productions of the lexical grammar are referenced in the syntactic grammar. This alone is sufficient to make them terminals of that grammar. [16:19:22.0000] (Like, in an abstract definitional grammar-y sense, not in spec terms specifically.) [16:19:48.0000] but there is something 'unblessed' about using TemplateSubstitutionTail in the syntactic grammar right now, even if one could come up with a sensible purpose for doing so? [16:20:31.0000] well, it would be unprecedented in this grammar to consider a single terminal to have two symbolic identities [16:21:27.0000] okay fair enough [16:24:17.0000] It’s confusing in ES because the lexical grammar is wound up with the syntactic grammar — the multiple goals are like a trick to keep pretending the lexical grammar is a ‘normal’ context-free, regular lexical grammar. [16:24:39.0000] yeah [16:24:40.0000] But if you imagine a more typical case, it’s usually possible to lex/tokenize independently from parsing. [16:25:15.0000] And each token is just ‘one symbol’ and I think that’s what’s being aimed for here. But what you’re describing seems conceptually valid to me, just not something I’ve seen before in practice I think. [16:25:15.0000] this is my first time thinking about goals at all, and evidently up 'til this point I've not really had to dwell on what makes the lexical grammar unique [16:26:20.0000] gotcha [16:26:38.0000] I am kind of obsessed with grammars/lexing/parsing so I’ve spent a lot of time on this subject within ES but I am by no means an expert so you should prob take my assessment with a few grains of salt. [16:26:54.0000] haha [16:28:35.0000] I am very much enjoying working on that domain within JSC's implementation but spec text still throws me curveballs sometimes [16:29:33.0000] (not wrt to using it for impl, wrt to understanding whether something is "written in the way that it's meant to be" like this) [16:30:16.0000] but also, having a background in linguistics, maybe it's better if I mentally rebucket the lexical grammar as "morphology that happens to be specified in a way that looks almost just like syntax" [16:30:55.0000] (lol s/wrt to/wrt/ x2) [16:31:08.0000] bathos (“If the hashbang proposal, (private) instance fields proposal, and the smart pipeline proposal all ended up reaching stage four, would this imply ... nine different lexical goal symbols?”): For what it’s worth, a hope of the smart-pipe proposal is to consolidate several other alternative proposals, like partial application and binding, each of which proposes its own additional lexical symbol(s). [16:31:28.0000] Understandably. On one hand I think the way the grammars are described in the spec is pretty elegant, on the other ... sometimes elegance isn’t the same as “optimized for accessible reading” ... it def took me a long time to figure out a lot of parts of the puzzle. I don’t know any other grammar that’s so parameterized (both explicitly and implicitly, e.g. ‘does annex b apply’, ‘is the goal symbol [16:31:28.0000] module’, etc). [16:32:16.0000] (dang, was afk for this conversation) [16:32:29.0000] jmdyck: you're not too late lol [16:34:00.0000] except now i have to go elsewhere [16:34:11.0000] anyhow, the 'interface [16:34:29.0000] 'interface' between the syntactic and lexical grammars is ... interesting [16:34:56.0000] @jschoi Cool, it would def be nice if partial application / topic were aligned. Partial application is a feature I think I would get a lot of use from personally. [16:35:32.0000] shu: come share in my grad-school flashbacks about the morphosyntactic interface rn [16:40:20.0000] It’s certainly pretty true that there are a lot of tokens in the JavaScript language now. [16:46:33.0000] @rkirsling my personal fave mindfuck in the lexical grammar is https://tc39.es/ecma262/#sec-html-like-comments. It took me two days to reverse engineer the reasoning behind why it is defined the way it is and what it is saying ... it does make sense, but it really felt like solving a puzzle. [16:47:36.0000] :ohno: [16:47:47.0000] do I dare [16:48:48.0000] haha, maybe you’ll get it faster than I did. It involves an explicit way of writing [yes LineTerminator here]. [16:51:21.0000] or in prose ‘--> begins a single line comment only if an input element preceding it was a LineTerminator or a comment including a LineTerminator or was a non-token input element which itself satisfies that same requirement’ [16:56:40.0000] I was always too afraid to know how HTML comments in JS actually worked but [16:56:45.0000] I think I'm following [16:57:34.0000] I'm amazed that don't function _as_ a multiline comment? [16:58:52.0000] And that `--> foo`, where legal, is all a comment — foo is not an identifier there! [16:59:25.0000] 😭 @ that [16:59:51.0000] I believe this dates back to oldskool practices related to putting the content of