Attendees
- Godfrey Chan (GC)
- Yehuda Katz (YK)
- Ricardo Mendes (locks)
- Scott Newcomer
- Rob Jackson (RJ)
- Chris Krycho (CK)
Notetaker
Chris Krycho (CK)
Agenda
Topic 1: Strict mode spec open questions
(GC, 15min) <template> Open Questions
- YK: progress on
eq etc. with SN needs to know what we say about strict mode
- GC: RFC said those should work without importing
- RJ: keywords don’t need import, per original RFC
- GC: yes, though some came along later
- YK: “corollary is in the spec but axiom isn’t”: didn’t say how to determine what a keyword is/n’t
- GC: non-written-down broad consensus
- YK: control flow one category, things like
eq another
- CK: was there a distinction between “keyword” vs. “prelude”?
- YK: no well-specified notion of even what a prelude is either
- RJ: prelude isn’t a thing that hasn’t been discussed publicly
- GC: other than appearing (without definition) in the RFC; it’s implicit imports… but only present for templates, what would it mean given imports (global?)
- YK: implementation technique would answer some questions but not good enough description
- GC: specified we should be able to override built-ins by importing
- prevents breaking existing code
- avoids making introduction of new keywords being a breaking change
- YK: lots of RFCs already assume this, but needs to be explicit: imports can always shadow built-ins/prelude/keywords
- GC: yeah, informs what “prelude” can/not mean—e.g. inserting around template doesn’t work cleanly b/c of interaction w/shadowing
- GC: don’t want to restrict components to be PascalCase-restricted anymore
- because
import { table } from './table'; should work, even if it’s a lint error
- YK: JS scope should be equivalent to hbs scope once scopes are merged
- GC: typos in tag position won’t error, e.g.
<tale /> instead of <table />, because of how HTML works
- RJ: what should we lint?
- GC: we should lint that component names should be
PascalCase, b/c it helps avoid this
- GC: typos in curly position should error, but who/how? ESLint and TS? Or add tooling/template level?
- YK: in JS you get a reference error if you say
foo if it isn’t a global
- RJ: yeah, happens at parse time, but we want it to be a build error not a runtime error
- GC: possibly we want to emit and existing tools which would catch it if we emit into JS, and Babel can be emitted in general
- RJ: if we statically know it’s a bug, we should error at build time
- GC: would be caught by red line in editor, would error on closure if it made it to the editor
- YK: agree would be caught in editor, would be happy to produce error in console,
- GC: was saying a different thing—wouldn’t make it to Glimmer VM rendering, would error early b/c of scope
- RJ: the thing is, the code w/error is code foreign to you which you didn’t write, harder to debug
- GC: it’s complicated by the next thing
- GC: should the HBS equivalent of
atob() work?
- YK:
window.div would then “work” and it would be a linting error
- YK: fine to say strict template scope has to actually be in scope
- GC: fine to say rule for angle bracket position
- YK: goal was to avoid variable namespacing per syntactic position
- GC: contextual keyword etc. style behavior
- GC: would work iff you type
window.atob instead
- GC: but w/o method syntax could be a problem
- GC: could entertain possibility that we always emit closure for how you typed it and it would always “work” even for prev. scenario
- YK: more generally, local variable shadowing rule seems incompatible w/global variables are in scope rule
- RJ: say more?
- YK: shadowing rule says
import eq should shadow keywords, need a well-defined hierarchy of locals → keywords → globals
- GC: could say window is special
- RJ:
globalThis etc.
- RJ: could also just not support window directly, reference it by doing
foo = window, etc.
- YK: similar to saying “eval is not allowed” (already true but not said!); scope visible to Handlebars template is local scope—no global scopes
- RJ: that means we can give nice build errors
- GC: can make indirect eval work
- RJ: what is indirect eval
- GC: means when you write
eval() you have access to current scope, but if you write e = window.eval() doesn’t get access to it
- YK: point is
eval() breaks all other analysis, aliased doesn’t
- GC: issue is not about eval specifically but the fact that functions work
- GC/YK back-and-forth about eval
- YK: main take is any feature that creates dynamic environment/scope change, that is not visible to templates (mostly means
window but also with and eval)
- notably private vars are described as lexical local variables
- GC: don’t incredibly care about
window.atob() so if agreed on other constraints, fine about it
- RJ: can we summarize that consensus? (CK: 😂)
- YK:
- local variables shadow keywords
- JavaScript static lexical scope (not
with/globalThis/eval) and HBS scope have same semantics
- Syntactically valid HTML tags are interpreted as HTML tags if name is not in scope
- GC: need to specify this
- YK: what HTML says the rule is, but excluding capital first letter
- YK: point is it’s not a fallback to a prelude which happens to contain
div
- GC: sounds like “component that looks like a tag is a bad idea but should be linted”
- YK: applies existing linting rule to context
- The first stage of template compilation needs to be able to ask dynamically whether a given free variable is in scope from the embedding scope; in strict mode, all remaining free variables have to be keywords after second stage; if any remain after that, it’s a syntax error.
- RJ: colloquially, compiler will ask if thing exists in embedding scope and after that it will “do what it does”—keyword or error or whatever, but that happens w/in the compiler
- YK: first stage of compiler is meant to be purely syntactic and agnostic to details which could change in edition/Ember/etc.
- keywords are layered on top of syntax
- while “is this a free variable?” is agnostic to the language embedding
- is important that no future version of Ember would change what a “free variable” means
- this is what undergirds the shadowing rules described above
- YK: sufficient to run w/on
eq etc.
- GC: existing implementations in
ember-template-imports doesn’t do this exactly
- YK: need a home for these kinds of specs