tc39 / proposal-global

ECMAScript Proposal, specs, and reference implementation for `global`
http://tc39.github.io/proposal-global/
MIT License
349 stars 18 forks source link

Please use a name without `this` in it #31

Closed rauschma closed 5 years ago

rauschma commented 5 years ago

I know it’s late, but please reconsider the name globalThis:

The name globalThis would make this more complicated again.

One possibility (but I’m OK with anything that doesn’t have this in it):

joelnet commented 5 years ago

I'm already using global in webpack. It works in node and browsers. Node's global and the browser's window are not a this. To me, this suggests a context might change, which isn't the case. I would think globalThis could be confusing.

I'm gonna vote against this.

getify commented 5 years ago

I am 100% in support of @rauschma here. Please, please reconsider.

mchandleraz commented 5 years ago

Also in complete agreement with @rauschma et al.

KoryNunn commented 5 years ago

browserify also maps window to global.

Using global would just be paving the goat-tracks that are proven to work.

EDIT: Just noticed this:

Attempts were made to ship under the name global, but it turns out that this does, in fact, break some existing websites.

And I have to say, as much as I get the "don't break things" attitude, the future is slightly more important than the past.

bmeck commented 5 years ago

Is there another name we could have proposed to investigate that doesn't cause enough breakage to be seen as a web compat problem? Several have been investigated already including global. Note that web compat problems are not purely theoretical nor absolute. JSON broke Facebook, but that website was able to update in a way that made the problem go away. Large distributed sites that cannot be feasibly updated are a different story.

rauschma commented 5 years ago

@bmeck I appreciate how difficult it is to pick a name and how important it is not to break anything! I’m fine with literally anything that doesn’t have the word this in it. My suggestion would be globalObject, but I don’t know how web-compatible that is.

smolinari commented 5 years ago

globalObject,globalObj, system, context ???

Scott

bmeck commented 5 years ago

We should avoid jests if we can here. It takes a huge amount of time to check any given thing and generally means some browser needs to actually roll it out if it seems safe enough, see what breaks and then roll it back.

feross commented 5 years ago

Has self been considered? It's already a synonym for window in the browser.

smolinari commented 5 years ago

@bmeck - Maybe some humor might make the language even more fun? 😄 It is already silly in some places. Your reasoning for not kidding around eludes my understanding. I'm certain the silly suggestions would be ignored for the spec. At any rate, I've edited my comment. Scott

ljharb commented 5 years ago

This is the option we decided to go with. The only better name imo is global, and breaking the web is unacceptable (the future of the web depends on not breaking the web).

globalThis is the global this value, which applies to sloppy mode Scripts, the Function constructor even in modules, and the upcoming Realms API - it’s not the global object, and being correct (not merely pedantic) is important.

rauschma commented 5 years ago

@feross Yes: https://github.com/tc39/proposal-global/issues/11

rauschma commented 5 years ago

@ljharb I completely understand how tricky all of this is and how important not breaking the web is!

I wouldn’t be as emotionally invested if I didn’t see almost daily people who are confused about this. And the many blog posts explaining it, many getting it wrong.

kleinfreund commented 5 years ago

From the readme's rationale (emphasis mine):

It is difficult to write portable ECMAScript code which accesses the global object.

That sounds like that's the main goal here.

ljharb commented 5 years ago

@kleinfreund that's a very good point - that sentence does imply that the name should have something to do with "global object". I'll try to update it to make that more clear.

I understand it’s confusing, but that’s what this proposal is for - the global this value. The global object is not actually directly accessible, and altho most community members (myself included) colloquially refer to it as the global object, browser representatives on TC39 flatly refused to allow it to proceed unless it explicitly did not imply that it was the global object.

rauschma commented 5 years ago

@ljharb Hmm. What is their name for what the global this points to?

ljharb commented 5 years ago

The same as in the spec, and in this proposal - the “global this value”.

Browsers have the concept of the “WindowProxy” (mentioned in the readme) that encapsulates access to the actual global object - i believe for security reasons dealing with iframes and cross-window access.

rauschma commented 5 years ago

OK, I see and accept the constraints. I’m still unhappy, because my hope (enabled by ES6!) had been that we’d be able to eventually (mostly) forget about this outside methods.

ljharb commented 5 years ago

I'm on your team here :-) I'd be delighted if the warts of the language, including sloppy mode semantics, would eventually be able to fully disappear - I think things would be much clearer for everyone, new and experienced users alike. Unfortunately, I suspect that won't be the case :-/

Thank you for the feedback - I’m not happy about the result either, but web compat has left no other palatable practical options.

KoryNunn commented 5 years ago

I would advocate doing nothing over globalThis

The global object is not actually directly accessible this is an amazing argument against caring about the fact that there is this hidden/internal global that no one consuming this API can ever use.

ljharb commented 5 years ago

Doing nothing would be worse - we desperately need a non-eval way to access the global this value, especially with CSP as a thing that exists.

If you’re content with “nothing”, I’m not sure why this identifier that you can choose not to use will matter to you - if you’ll use it, by don’t like the name, then “nothing” certainly shouldn’t be preferable.

KoryNunn commented 5 years ago

Probably getting a bit off-topic, but why would I not advocate against something that I believe would be worse than nothing?

globalObject would be better than nothing.

global would be in line with the last 10 or so years of precident.

rauschma commented 5 years ago

@KoryNunn Jordan just explained the constraints against globalObject and why having something is useful (but maybe not for you).

rauschma commented 5 years ago

@KoryNunn As for global and self, see this issue: https://github.com/tc39/proposal-global/issues/11

smolinari commented 5 years ago

And what about globalScope?

Scott

rauschma commented 5 years ago

@ljharb Got it. To clarify: Given that it’s called “global this” in the spec, the name globalThis is OK. I’d rather it were called something else in the spec (with a matching identifier).

ljharb commented 5 years ago

@smolinari it's not actually a scope (global const/lets, for example, are not properties on the global this value), and there isn't any reified "scope" concept in the spec (by design).

getify commented 5 years ago

By "global this value", are we meaning "the thing 'this' will point to in a non-strict function that has a 'this' reference"?

If so, I'd suggest that perspective on that value, used to name it, is far less relevant (and becoming less so as time goes on) compared to "the object that holds properties of all my global variables". IME the latter is far more common in terms of mentally describing what that thing is, and why we want to access it. The former is literally something most of us teach and advocate as "you should never access that if you can avoid it." I've said countless times in my courses, "if you're trying to access 'this' and it's the global object, that's usually a mistake, and that's why strict mode took that away."

So "globalThis" may be pedantically correct but it's not even remotely the common name we should be propagating for it.

As usual, @ljharb, the tone of "it's already been decided, get over it" is not helpful. You didn't consult enough of us teachers likrle @rauschma and myself to realize that TC39's perspectives here are skewed from the direction we should be going. I know that's upsetting to hear, but every time you ignore this perspective you can expect (and I assume, ultimately ignore) my pushback.

For the sake of bikeshedding, I would have preferred "globalContext" or "globalScope" or even "globalSelf" infinitely more than "globalThis". Those names all point to the identity and purpose of that object that more closely aligns with how devs interact with it, and also what many of us teachers are trying to steers devs towards.

+@littledan

ljharb commented 5 years ago

I don't think I've offered a tone or wording of "it's been decided, get over it" here, and I don't think that's being particularly charitable. Also, I don't think it's fair to assume that nobody on TC39 is a teacher - I consider myself a teacher of JavaScript, too, in some ways.

(regarding bikeshedding, "globalScope", as I've explained above, would be a very confusing name - a scope is not a noun in javascript. "globalContext" is interesting, but "context" isn't a commonly used term, so I'd find that confusing as well, and "globalSelf" would imply it's different than "non-global self", which it's not in browsers, and "self" isn't a thing at all in all JS engines)

trotyl commented 5 years ago

"the object that holds properties of all my global variables"

@getify This is wrong assumption, only top var declarations becomes properties of the global (known as legacy defect), but not top let or const declarations (which fixes the behavior):

image

image

suchipi commented 5 years ago

This is going to be one of those painful proposals that I associate with lost opportunities, isn't it? Like that issue about using # for private fields instead of private where everyone talked over each other

suchipi commented 5 years ago

I'm getting really tired of sensible language design being blocked by elitist pedantry

ljharb commented 5 years ago

@suchipi what do you think would be a sensible design here?

suchipi commented 5 years ago

I think globalObject makes sense- no one has ever been confused by window referring to a WindowProxy instead of the window object, so the distinction between the two doesn't seem useful. Also I thought the Window/WindowProxy duality wasn't part of the ECMAScript standard anyway, so it doesn't make much sense to give it affordances here.

ljharb commented 5 years ago

Given that some browsers would refuse to implement it under that name, what else would you suggest?

suchipi commented 5 years ago

Under the name globalObject? Why would they refuse it? Are there web compatibility issues with that name?

ianstormtaylor commented 5 years ago

@suchipi check out #32 if you haven't already.

ljharb commented 5 years ago

@suchipi they refused it specifically because it's not actually the global object, and they did care about the WindowProxy duality.

suchipi commented 5 years ago

Well, I think that is an example of elitist pedantry getting in the way of the needs of the average user.

What about Global?

ljharb commented 5 years ago

As I commented on #32, it was in my original list of possibilities, but the general reaction I got was that it's not a constructor and not quite the same as a namespace like Math, JSON, Reflect, etc.

At some point, I had to create a minimal list of 3-5 possibilities in order to gather web compat data, and I had to make a judgement call to prune the longer list down to that, and it didn't include Global.

suchipi commented 5 years ago

Sorry for the duplication, I'll move to #32

pleerock commented 5 years ago

If global isn't acceptable, what about globals? Not sure if it already was suggested.

ljharb commented 5 years ago

@pleerock it’s already been suggested, and it’s one of the ones i collected data on - it’s not an option, because of web compatibility.

AshleyScirra commented 5 years ago

I agree globalThis is an awkward name. Based on what @ljharb says it seems to be a case of specification terminology being moved in to the language:

The same as in the spec, and in this proposal - the “global this value”.

whereas normally I'd expect the reverse (the terminology to be determined for the language then written in to the spec).

I appreciate this has moved far along enough to shipping to be difficult to change - especially since this looks to ship in Chrome stable in 5 days... maybe that should be postponed for a little more thought?

I can see how this will quickly turn in to an epic new episode of bikeshedding, but I can't resist throwing in globalRef, which doesn't seem to have been discussed yet. It doesn't refer to "this" and doesn't imply it points to "the global object". JavaScript variables reference objects so it can be technically described as being a reference to the "global this object" (as the spec describes it), yet should be intuitive to the average developer since they can think of it as referencing what they informally think of as "the global object" (where their global variables/properties go). Hopefully it is also more straightforward to explain to beginners since it doesn't refer to "this" and is indeed a reference (but I don't teach programming).

In fact the term "the global reference" is natural enough that it was mentioned in #32, apparently in passing, without being directly suggested (emphasis added):

Global — There was discussion of this, but it was thrown out because the pascal-cased names are supposed to be reserved for constructors and for namespaces. But when you think about the 99% use case for people, the "global reference" is always for namespacing reasons, and it is often referred to as the "global namespace". So to me it seems like an extremely relevant naming choice.

So it seems to be a relatively natural term that doesn't use "this" and doesn't call it a global "object", "scope", "context" or anything else that might be misleading, since like all object variables it is indeed a reference.

As for web compatibility though, I don't know - I can only say anecdotally I've not seen it used.

fkling commented 5 years ago

I haven't been following this proposal TBH, so I might be missing something, but this confuses me:

@ljharb

globalThis is the global this value, which applies to sloppy mode Scripts, the Function constructor even in modules, and the upcoming Realms API - it’s not the global object, and being correct (not merely pedantic) is important.

Is it not the purpose of this proposal to be able to access the global object? I assume what you are referring is the following (from InitializeHostDefinedRealm):

If the host requires that the this binding in realm's global scope return an object other than the global object, let thisValue be such an object created in an implementation-defined manner. Otherwise, let thisValue be undefined, indicating that realm's global this binding should be the global object.

ATM there don't seem to be any requirements imposed by the spec onto the relationship between the global this and the global object. Is this going to change?

Because if an implementation decides to use different values for this and the global object, I don't see why I would want to access globalThis?


Another thing I want to point, even though I know that non-normative sections are not .... well ... normative, the fact that the spec contains the following statement probably isn't helping the discussion:

This global object is the value returned by the global Environment Record's GetThisBinding concrete method.

https://www.ecma-international.org/ecma-262/9.0/#sec-global-environment-records

bmeck commented 5 years ago

@fkling due to browser concerns all global property access should go through WindowProxy not the Realm's global object which is the Window, see https://github.com/tc39/ecma262/issues/1200 for an example of this being brought up.

fkling commented 5 years ago

@bmeck, I think I understand that. Global this is WindowProxy which forwards property access to global object (Window). So using globalThis in a browser context makes sense.

However, afaik, the spec currently does not require property access to be forwarded from the global this value to the global object. In an environment where this doesn't happen, globalThis doesn't seem useful and as such doesn't actually provide an environment independent way to access global variables (which is the goal of this proposal?).

Or am I missing something?

bmeck commented 5 years ago

@fkling global variables are different from global properties since they are not on the global this nor the global object actually and this is where we get more into the weeds. This proposal is about exposing the intended view of the global namespace of properties not variable inspection. I'll leave this as an example of how to see the difference in global variables vs properties:

$ node
> let a = 1
undefined
> a
1
> global.a
undefined

When we talk about non-browser environments, there are none that I know of that differentiate the global object and the global this value such that they are different.

fkling commented 5 years ago

@bmeck I guess I was referring to "global properties" then.

When we talk about non-browser environments, there are none that I know of that differentiate the global object and the global this value such that they are different.

So this proposal assumes that

even though neither is enforced in the spec? If that's the case it should at least be pointed out or it should be made clear that there are plans to amend the spec.


Either way, it seems that the argument for using the name globalThis was that the global this value and the global object are different. Yet it also seems the proposal assumes that the global this value somehow proxies the global object. This seems almost contradictory.

STRML commented 5 years ago

Naming is hard.

I would just like to voice my support for something other than globalThis, if only because its very naming carries JS design debt into the foreseeable future. Explaining what globalThis means and how it got to be is a 200+ word essay that new JS users are likely not to understand. Additionally, the very name itself is contradictory: global in this context implies a singleton, whereas this implies one of many, i.e. this scope, this object, this planet that we live on. So at face value, it seems to mean "one global singleton" which really feels messy.

I understand how it got this way but I strongly believe new language proposals should feel like they are making the language more approachable rather than less. JS got to its massive level of acceptance in large part because it was a small, approachable language.

It's obvious that the community is resisting this change. As it is not yet shipped in mainline versions nor accepted into the spec it is a perfect time to demonstrate that this body embraces the community, rather than proceeding on without them. The cost of going back to the drawing board is minimal. The cost of alienating the community is high.

@ljharb: I think this is a good opportunity for you and TC39 to consider how community feedback is solicited and handled. In particular, these comments are contradictory and make us feel shut-out:

https://github.com/tc39/proposal-global/issues/31#issuecomment-442737125

I don't think I've offered a tone or wording of "it's been decided, get over it" here,

https://github.com/tc39/proposal-global/issues/32#issuecomment-442734194

@ianstormtaylor it's a bit late for suggestions, as we've already selected the name globalThis, vetted its web compatibility, and it's already beginning to ship in browsers. In other words, the final decision has effectively been made.

Given the upcoming Realms API and especially https://github.com/tc39/proposal-realms#example-simple-realm, why not rootRealm? Realms are forward-looking. globalThis looks toward the past.