> [Reflect] 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.

It either isn’t a breaking change, or can’t break much. It cannot be both.

> Not a breaking change because this constructor did not exist before.

Are you entirely sure? There’s no code anywhere which doesn’t have an object 
called Symbol invoked with `new Symbol()`? The moment you add a global 
anything, you break someone’s code somewhere.

> 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.

I fail to see where you see guidelines specced out in the specifications of 
metaproperties or superproperties. “Most people” end up just stuck with these 
because they are either unaware that these changes are coming or are not active 
enough to voice their concerns.

> 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.

The thing is, I clearly provide arguments in favour of my opinion. Let me just 
summarise them for you.

We now have:

- keywords that are just keywords, really (typeof, case, break, etc.)

- keywords that are just keywords, but don’t even exist in a language. They are 
reserved for future use in various contexts: always reserved, only in strict 
mode, only in module code etc. (enum, public, private, await etc.). May never 
be used and may possibly be removed, as some keywords have been (int, byte, 
char etc.)

- literals that are basically keywords (null, true, false)

- non-keywords that are for all intents and purposes keywords (eval, arguments)

- keywords that look like objects (because they have additional properties) 
which are not objects (new with new.target)

- keywords that look like functions (because they are invoked like functions 
and return values like functions) which are not functions (import and import())

- keywords that look like objects *and* functions but are neither (import and 
import() and import.meta)

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. It gets transformed into a separate, 
made-just-for-import CallExpression and then it gets an `import.meta` on top of 
that (as a hardcoded “metaproperty”).

All of the above are basic facts about the language as it exists now. How can 
adding “properties” to semantically fundamentally different things elegant? Or 
increasing the number of extremely context-dependent things? Or overriding 
existing keywords with new and exceedingly confusing behaviours?

> > 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

and a System spec and an Introspect spec, and ... That is why all these random 
additions to vastly different things in the language look like ad-hoc 
shortsighted solutions with no respect for the language or its evolution. “We 
need a thing, we have nowhere to put this thing, let’s add this thing to a 
keyword, because new.target (bad design) has opened a door for us”.

> 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`.

Riiiight. Because import.meta is not a magically-populated not-quite-global 
variable. Oh. Wait. That’s *exactly* what it is.

Even though it’s worse. import is a 
not-really-a-function-not-really-an-object-not-really-a-static-not-really-a-dynamic-keyword
 which is clearly far worse than a properly defined API.

On Sat, 05 Aug 2017 at 22:37 Logan Smyth

<
mailto:Logan Smyth <loganfsm...@gmail.com>
> wrote:

a, pre, code, a:link, body { word-wrap: break-word !important; }

`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

<
mailto:dmit...@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-reflectionhttps://tc39.github.io/ecma262/#sec-proxy-objectshttps://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
mailto:dmit...@dmitriid.com
<
mailto:dmit...@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

<
mailto:matthew+robb+%3cmatthewwr...@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

<
mailto:dmit...@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

<
mailto:dmit...@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

<
mailto:dmit...@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
mailto:es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
_______________________________________________
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to