import.meta and TC39 process as a whole
Logan Smyth
loganfsmyth at gmail.com
Sat Aug 5 20:37:13 UTC 2017
`await` could be added because there is no case in existing code where
`await <expression>` would have been valid code, so it is
backward-compatible. The same applies for all of the meta-property
proposals. The same is not true for `Introspect.context.module`. It's not
just a question of it a given construct could be made to behave the way you
want, it's also a question of it it would be compatible with existing code.
> Introduced in ECMASCRIPT 2015: Reflect is a built-in object that provides
methods for interceptable JavaScript operations.
Not a breaking change because adding a new global isn't new syntax, it's
just a new variable that exists and essentially can't break much.
> Introduced in ECMASCRIPT 2015: The Symbol() function returns a value of
type symbol, has static properties that expose several members of built-in
objects, has static methods that expose the global symbol registry, and
resembles a built-in object class but is incomplete as a constructor
because it does not support the syntax "new Symbol()”.
Not a breaking change because this constructor did not exist before.
> ECMAScript 5 introduced: yield, let
Not a breaking change because those two can only occur in locations where
they can't conflict with existing ES5 code. The extremely limited cases
where `let` _could_ be in conflict are explicitly handled in the grammar to
prevent breaking changes.
> ECMASCRIPT 6 introduced: await as a reserved word in module code
Same as above.
> So, introducting new things into the language is not really such a big
problem as it’s made out to be ;)
No-one said introducing things was not possible, but we can't break
existing code.
> Don’t forget that `super` gets its own properties. Since there’s no
specification of what “metaproperties” are, they are just called
superproperties[7] in the grammar. Because reasons.
I don't think I'd call super properties metaproperties for this reason.
`super` property access is its own class-related syntax that isn't related. I
do think it sets a perfectly reasonable guideline that makes it clear most
people have no problem accessing properties off of keywords.
> The problem with “metaproperties” is that they make the language more
complex, chaotic and make it difficult to reason about the language.
This seems to be the core of your argument, but I honestly don't quite see
why it is more complex/chaotic. The biggest issue for me in this whole
thread is that it's all extremely opinion-based. What one person calls
complex another would call elegant.
What specifically is difficult to reason about that wasn't already complex?
Same for `function.arguments`. You're saying you think it's better to have
an automatically-created `arguments` variable in every single function
instead of having syntax to access it? `arguments` and `this` as two
auto-initialized bindings are some of the most confusing parts of JS.
> So there’s really *nothing* stopping you from designing a proper
System/Module/Loader/Introspect/Avocado or any subset thereof instead of
slapping “metaproperties” on everything in sight :)
I don't think anyone has claimed that `import.meta` is meant as a
replacement for these. We still need a loader spec, but having a syntactic
way to access data about the current active module is absolutely a useful
thing to have. It's no different than CommonJS's __dirname and __filename
among others. The logic for implementing a loader is separate from the
logic for defining the behavior of module execution itself.
I'd _much_ rather have a static syntactically-defined way to access that
information over a magically-populated not-quite-global variable like
`Introspect.context.sent`.
In a perfect world absolutely `module` could have been a keyword, but at
this point making that change seems like an absolute no-go because it could
easily break existing code.
> Like look. function.sent?? Really? And it’s extremely highly
context-specific: “function.sent can appear anywhere a YieldExpress would
be legal. Referencing function.sent outside of a GeneratorBody is a Syntax
Error.”
It's the exact same context-specific behavior as `yield` and they are both
tied to generator functions. How is that in any way unexpected?
On Sat, Aug 5, 2017 at 12:43 PM, Dmitrii Dimandt <dmitrii at dmitriid.com>
wrote:
> I just realised that there is also the argument that “global object cannot
> get current context” and other limitations applied to whether a theoretical
> “System/Module/Loader/Introspect” would be a global module, or object, or
> keyword, or any (potentially context-sensitive) combination of these.
>
> However, this all basically depends on what you specify in the standard,
> doesn’t it? :)
>
> - Dynamic import has a “forbidden extensions” section[1] and how it should
> work when it’s invoked as a CallExpression [2]
> - import.meta has a full section describing how the runtime should behave
> when encountering this particular property[3]
> - new global objects like Reflect, Proxy, Symbol have specifications on
> what they are and hoe they should be treated [4]
>
> A theoretical global object/keyword/identifier/special form X could be
> specified as <object/keyword/identifier/avocado>. X.someProperty: when
> encountered, let context be Ctx, let A be B, and C be B, populate with
> properties from here and there and everywhere.
>
> Or look at the AwaitExpression[5]. There are specific limits in place to
> guard where and how it’s used and when it is to be evaluated as
> AwaitExpression.
>
> So there’s really *nothing* stopping you from designing a proper
> System/Module/Loader/Introspect/Avocado or any subset thereof instead of
> slapping “metaproperties” on everything in sight :)
>
> Like look. function.sent?? Really? And it’s extremely highly
> context-specific: “function.sent can appear anywhere a YieldExpress would
> be legal. Referencing function.sent outside of a GeneratorBody is a Syntax
> Error.” [6]
>
> Look. Here’s a proposal: `Introspect.context.sent can appear anywhere a
> YieldExpress would be legal. Referencing Introspect.context.sent outside of
> a GeneratorBody is a Syntax Error.` And then you can use
> `Introspect.context.target` instead of `new.target`.
> `Introspect.context.module` instead of `import.meta`. Clean. Reasonable.
> Extensible. Future-proof.
>
> [1] https://tc39.github.io/proposal-dynamic-import/#sec-
> forbidden-extensions
> [2] https://tc39.github.io/proposal-dynamic-import/#sec-import-calls
> [3] https://tc39.github.io/proposal-import-meta/#sec-
> source-text-module-records
> [4] https://tc39.github.io/ecma262/#sec-reflection, https
> ://tc39.github.io/ecma262/#sec-proxy-objects, https://
> tc39.github.io/ecma262/#sec-symbol-objects
> [5] https://tc39.github.io/ecma262/#prod-AwaitExpression
> [6] https://github.com/allenwb/ESideas/blob/master/
> Generator%20metaproperty.md
>
>
>
> On Sat, 05 Aug 2017 at 20:40 dmitrii at dmitriid.com <dmitrii at dmitriid.com>
> wrote:
>
>> The problem with “metaproperties” is that they make the language more
>> complex, chaotic and make it difficult to reason about the language.
>>
>> See my previous post about the multitude of keyword and keyword-like
>> types that the language has. It’s so bad that even “metaproperty” concept
>> itself isn’t defined in the standard except as a hardcoded `new.target` [1]
>>
>> If you read, for example, through the import.meta draft, you see things
>> ripe for inclusion in a proper API object.
>>
>> It gets even worse. Because “metaproperties” are not just attached to
>> keywords. They are attached to keywords which have *fundamentally different
>> semantics* in the language: `new` is an operator[2], it gets `new.target`.
>> A function is a callable object [3], and it gets a `function.sent`. Import
>> is … I don’t know what import is [4]. It gets transformed into a separate,
>> made-just-for-import CallExpression[5] and then it gets an `import.meta`
>> on top of that [6] (as a hardcoded “metaproperty").
>>
>> Don’t forget that `super` gets its own properties. Since there’s no
>> specification of what “metaproperties” are, they are just called
>> superproperties[7] in the grammar. Because reasons.
>>
>> All this is chaos from the perspective of developer experience. And truly
>> looks like random ad-hoc solutions to immediate problems with no long-term
>> goals. Imagine how much better *and* future-proof it would be if all this
>> was in the form of a unified centralised API? There is a reason people
>> laugh at PHP for its API and language design.
>>
>> [1] https://www.ecma-international.org/ecma-262/#sec-meta-properties
>> [2] https://www.ecma-international.org/ecma-262/7.0/#sec-new-operator
>> [3] https://www.ecma-international.org/ecma-262/7.
>> 0/#sec-terms-and-definitions-function
>> [4] https://www.ecma-international.org/ecma-262/7.0/#sec-imports
>> [5] https://tc39.github.io/proposal-dynamic-import/#sec-
>> left-hand-side-expressions
>> [6] https://tc39.github.io/proposal-import-meta/#sec-
>> left-hand-side-expressions
>> [7] https://www.ecma-international.org/ecma-262/7.0/#sec-left-hand-side-
>> expressions
>>
>>
>> On Sat, 05 Aug 2017 at 18:59 Matthew Robb <Matthew Robb
>> <Matthew+Robb+%3Cmatthewwrobb at gmail.com%3E>> wrote:
>>
>>> I really can't find a good resource on direct vs indirect evaluation but
>>> my understanding is it's one of the main considerations for using a keyword
>>> over an identifier for contextual information. One example which is already
>>> in the language would be 'eval' which you can read a little about here:
>>> http://2ality.com/2014/01/eval.html
>>>
>>> Now you might be able to have an API that gets you the same result as
>>> the context sensitive keywords but it would be less ergonomic among other
>>> things: Reflect.getModuleMetaProperty(someModuleNs, 'propName') but
>>> this becomes much more difficult to do FROM WITHIN THE MODULE ITSELF.
>>> Anything that is, let's call it tangible, cannot receive implicit
>>> contextual information it must have something passed to it that it would
>>> use to look up said information.
>>>
>>> Sure there could be arguments made about introducing new environment
>>> type records to the top level module scope of all modules but this is
>>> potentially much more error prone and likely to lead to more and bigger
>>> questions down the road. 'module' in particular is a really bad choice imo
>>> as node/commonjs have already introduced a 'module' identifier into all of
>>> their module scopes hence `module.exports = ...`. There may be solutions to
>>> working around that in one form or another BUT the 'trend' in TC39 to use
>>> keyword meta properties for context sensitive information is to avoid
>>> solving ever edge case of conflict that would impact existing code and
>>> users. It really is a fairly ripe space for powerful and ergonomic features
>>> like `super` which feel like "magic". The same is true for import.meta but
>>> it may be harder to identify right off as the uses haven't all been fully
>>> introduced such as environment specific properties and potentialy other
>>> loader hooks.
>>>
>>> NOW as I was writing this it came to mind that we DO have a new
>>> syntactic form for private data coming in the form of private fields which
>>> use a hash prefix. It would be interesting to explore using the same syntax
>>> for module scoped private fields:
>>>
>>> ```js
>>>
>>> console.log(#dirname);
>>> ```
>>>
>>>
>>> - Matthew Robb
>>>
>>> On Sat, Aug 5, 2017 at 12:35 PM, Dmitrii Dimandt <dmitrii at dmitriid.com>
>>> wrote:
>>>
>>>> Too bad emails don’t have "thumbs up" and “+1”s :) So here’s my "+1” to
>>>> you
>>>>
>>>>
>>>>
>>>> On Sat, 05 Aug 2017 at 18:28 "T.J. Crowder" <">"T.J. Crowder" > wrote:
>>>>
>>>>> On Sat, Aug 5, 2017 at 5:05 PM, Dmitrii Dimandt
>>>>> <dmitrii at dmitriid.com> wrote:
>>>>> > So, in my opinion, the argument for not adding new global entities
>>>>> > such as System, or Module, or Loader (or heck, even all three of
>>>>> > them) being “these are not keywords, we can’t introduce them” is
>>>>> > really really weak.
>>>>>
>>>>
>>>> Is anyone making that argument? I certainly am not. Not only is it
>>>> possible to add more global entities, as you point out, it's been done
>>>> repeatedly: `Symbol`, `Reflect`, etc. They just can't be *keywords* without
>>>> breaking things. They have to be identifiers. Which means they have
>>>> bindings with values. Which means those values can be copied. Which has
>>>> implications.
>>>>
>>>> On Sat, Aug 5, 2017 at 5:08 PM, Dmitrii Dimandt
>>>> <dmitrii at dmitriid.com> wrote:
>>>> >
>>>> > That’s not what I was really aiming at :)
>>>> >
>>>> > The original concern was “to get ‘module’ : 1. It's a
>>>> > context-sensitive keyword, and code that's using it needs to
>>>> > be updated when migrated to a module. “
>>>> >
>>>> > I was just pointing out that ‘import’ is already a context-
>>>> > sensitive keyword (as are a bunch of others, like super.
>>>> > Is super a keyword BTW?)
>>>>
>>>> My point was that this would be the only case I know of where it would
>>>> be a keyword in one context but an identifier in another in the *exact same
>>>> production*. `super`, `import`, etc., are **always** keywords. You just
>>>> can't use them except in certain contexts. So I shouldn't have said
>>>> "context-sensitive keyword" so much as "keyword or identifier depending on
>>>> context." (But then...I did, earlier; I figured the shorthand was okay
>>>> after spelling it out longhand. :-) )
>>>>
>>>> But again: Maybe that's feasible. Or maybe it's not a problem passing
>>>> the value around, in which case a predefined `module` identifier only in
>>>> module code isn't a problem anyway.
>>>>
>>>> -- T.J. Crowder
>>>>
>>>>
>>
>
>
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20170805/7133f84d/attachment-0001.html>
More information about the es-discuss
mailing list