again, `Object.keys({ y })[0]` will give you the string `y`, and will survive refactoring tools. you can even do `function nameof(obj) { return Object.keys(obj)[0]; }` and then `nameof({ y })`.
Obviously it's slightly less ergonomic than `nameof y` would be - but adding new syntax is very expensive, so there'd need to be overwhelming evidence that this pattern is commonly used enough, and that userland workarounds like my `nameof` function were insufficient. On Sun, Jun 16, 2019 at 10:13 PM Frederick Stark <coagm...@gmail.com> wrote: > > > your examples are all completely incorrect anyway > > "incorrect" as to precisely what? > Keep reading the email mate. > Incorrect as to your understanding of how the language works and at what > point variables are defined. > > > The user MUST _already_ know the _exact_ identifier name > It's not an issue to need to know the name of the identifier. In fact, as > you correctly pointed out, it's necessary. > If I'm understanding it correctly, the value of the proposal is to make it > easier to refactor (especially with variable renaming tools) without > leaving behind string literals that no longer match the variable name. > > I've run into this issue before, but it's been a relatively minor pain for > me personally. So I can see some use for the proposal, though I suspect it > would see most of it's use in tooling. > On the other hand, it might add unnecessary complexity to the language, > which should be avoided. > Overall I'm very mildly supportive. > > > That leaves the use case of getting ALL of the names of the identifiers > in the current scope > I have not seen anyone proposing this, so there's no reason to criticize > it yet. > > > Obligatory disclaimer: not a TC39 member, no decision making power or > influence on process > On Jun 17 2019, at 2:42 pm, guest271314 <guest271...@gmail.com> wrote: > > The user MUST _already_ know the _exact_ identifier name or an error will > be thrown for the original proposal and additional use case for ```nameof``` > > const x = nameof y; // "y" > const y = 1; > > making the need for ```nameof``` moot given that the user cannot then > rationally state that the identifier as a _string_ will somehow be > mispelled if they are able to write the _exact_ name of the identifer at > ```nameof``` 100% of the time. > > That leaves the use case of getting ALL of the names of the identifiers in > the current scope > > // NAMEOF is always dynamic list of let, const declarations in current scope > console.log(NAMEOF); // ["x", "y"]; [{name:"x", line:5}, {name:"y", line:7}] > // should resolve be in the list even if not declared using const or let? > await new Promise(resolve => setTimeout(resolve, Math.floor(Math.random() * > 1000))); > const x = nameof y > await new Promise(resolve => setTimeout(resolve, Math.floor(Math.random() * > 1000))); > const y = 1; > > > without having to already know the name of the identifiers, as is required > by the original proposal, which essentially negates itself as the string > literal ```'y'``` is briefer than ```nameof y```. > > > On Mon, Jun 17, 2019 at 4:19 AM Frederick Stark <coagm...@gmail.com> > wrote: > > guest271314, your examples are all completely incorrect anyway since all > variable declarations (including let and const) are hoisted to the top of > the scope, so when nameof y is evaluated, y is already declared in the > scope. > > The special behaviour introduced with let and const is that they set up a > "Temporal Dead Zone" where attempts to set or get their value before the > line where they are declared in code throws an exception. > Since nameof doesn't care about the value, only the name of the variable, > it would not *need* to throw an exception. > Of course, were this proposal to be taken seriously, it could be specced > either way > > > On Jun 17 2019, at 10:15 am, guest271314 <guest271...@gmail.com> wrote: > > > - If `y` is directly visible in scope and is neither a parameter or > destructured binding, `nameof y` should just evaluate to `"y"`. This > should be agnostic to whether the binding has been declared yet, so in > your example, `x` should be set to `"y"`. > > The 1st question at > https://esdiscuss.org/topic/what-do-you-think-about-a-c-6-like-nameof-expression-for#content-33 > remains: > > Without having composed or previously read the source code, at line 1 > adjacent to ```nameof``` how does the user know that there will be later > declared variable named ```y```? > > > > On Sun, Jun 16, 2019 at 7:04 AM Isiah Meadows <isiahmead...@gmail.com> > wrote: > > Here's my opinion: > > - If `y` is directly visible in scope and is neither a parameter or > destructured binding, `nameof y` should just evaluate to `"y"`. This > should be agnostic to whether the binding has been declared yet, so in > your example, `x` should be set to `"y"`. > - If `y` is entirely undeclared, it should be a runtime > `ReferenceError` in the same way it is when accessing undefined > globals. So in your second example, I'd expect it to throw before even > attempting assignment > > ----- > > Isiah Meadows > cont...@isiahmeadows.com > www.isiahmeadows.com > > On Sun, Jun 16, 2019 at 12:00 AM guest271314 <guest271...@gmail.com> > wrote: > > > > ``` > > const x = nameof y > > const y = 1; > > ``` > > > > At line 1 adjacent to ```nameof``` how does the user even know that > there is a variable that will be declared named ```y```? > > > > What is the output of ```x``` where there is no variable named ```y``` > later declared? > > > > ``` > > const x = nameof y > > const z = 1; > > ``` > > > > On Sun, Jun 16, 2019 at 12:03 AM Ron Buckton <ron.buck...@microsoft.com> > wrote: > >> > >> > What should occur where the code is > >> > >> It would be "y" in all 3 places. > >> > >> > ... is a proposal for _more_ than only getting the _name_ of an > _declared_ and _initialized_ variable? > >> > >> It is a proposal for getting the name of a _declared_ variable. Whether > it is _initialized_ does not matter. > >> > >> > Should a ```RefefenceError``` _not_ be thrown simple because > ```nameof``` is used? > >> > >> No, an error is not thrown. ECMAScript is much more nuanced. Block > scoped variables from 'let' or 'const' exist and can be *referenced* (via > closure or export, currently) anywhere within the same block scope, even > before they are initialized. Until they have been *initialized* (the line > of code contain the declaration has been reached and evaluated), they exist > in a "Temporal Dead Zone" (TDZ). Attempting to *dereference* them (i.e. > access or store a value) while in this TDZ is what results in the > ReferenceError. > >> > >> At no point does the `nameof` operator *dereference* the variable, so > no error need be thrown. > >> > >> From: guest271314 > >> Sent: Saturday, June 15, 4:29 PM > >> Subject: Re: Re: What do you think about a C# 6 like nameof() > expression for > >> To: Ron Buckton > >> Cc: es-discuss@mozilla.org > >> > >> > >> > >> > >> What should occur where the code is > >> > >> ``` > >> const x = nameof y > >> await new Promise(resolve => setTimeout(resolve, 100000)); // should x > be "y" here? > >> await new Promise(resolve => setTimeout(resolve, 200000)); // should x > be "y" here? > >> await Promise.all([new Promise(resolve => setTimeout(resolve, 300000)), > ...doStuff()]); // should x be "y" here? > >> const y = 1; > >> ``` > >> > >> ? > >> > >> The immediately invoked arrow function example (where a > ```RefeferenceError``` is thrown) appears to demonstrate that to output the > expected result of ```nameof``` within the context of the code example > >> > >> ``` > >> const x = nameof y > >> const y = 1; > >> ``` > >> > >> is a proposal for _more_ than only getting the _name_ of an _declared_ > and _initialized_ variable? > >> > >> Should a ```RefefenceError``` _not_ be thrown simple because > ```nameof``` is used? > >> > >> On Sat, Jun 15, 2019 at 11:16 PM Ron Buckton <ron.buck...@microsoft.com> > wrote: > >> > >> ``` > >> const x = nameof y > >> const y = 1; > >> ``` > >> > >> `x` would have the value “y”. It would not matter if `y` were > initialized or had yet been reached during execution. It does not deviate > from the purpose of `let` or `const`, because you are not accessing the > value of the identifier. > >> > >> Also consider that this is legal ECMAScript in a module: > >> > >> ``` > >> export { y } > >> const y = 1; > >> ``` > >> > >> The binding for `y` exists within the same block scope, it just has not > yet been initialized. Exporting it via `export { y }`, closing over it via > `() => y`, or accessing it via `nameof y` would all be the same. In all > three cases you are accessing the *binding* of `y`, not the *value* of `y`. > Even in the `() => y` case, you don’t access the *value* of `y` until you > execute the function. > >> > >> From: guest271314 <guest271...@gmail.com> > >> Sent: Saturday, June 15, 2019 3:57 PM > >> To: Ron Buckton <ron.buck...@microsoft.com> > >> Cc: es-discuss@mozilla.org > >> Subject: Re: Re: What do you think about a C# 6 like nameof() > expression for > >> > >> > Sorry, I meant to say “not entirely correct”. > >> > >> You have not yet confirmed if in fact the expected output is > referencing a variable declared using ```const``` on the current line > _before_ initialization _on the next line_. > >> > >> That example appears to deviate from the purpose and usage of > ```const```, beyond the scope of ```nameof```, and if were implemented, a > ```ReferenceError``` should _not_ be thrown when a ```const``` variable > that has yet to be initialized _on the next line_ is referred to _on the > current line_? > >> > >> Aside from that example, the code which essentially already implements > ```nameof``` should be able to be found in the code which implements > ```ReferenceError``` relevant to ```const```. > >> > >> On Sat, Jun 15, 2019 at 10:47 PM Ron Buckton <ron.buck...@microsoft.com> > wrote: > >> > >> Sorry, I meant to say “not entirely correct”. > >> > >> From: Ron Buckton > >> Sent: Saturday, June 15, 2019 3:03 PM > >> To: guest271314 <guest271...@gmail.com> > >> Cc: es-discuss@mozilla.org > >> Subject: RE: Re: What do you think about a C# 6 like nameof() > expression for > >> > >> > At that point in the example code the identifer ```y``` does not > exist. > >> > >> That is not entirely incorrect. The identifier `y` exists, but its > binding has not been initialized, otherwise you couldn’t refer to y in this > case: > >> > >> > >> > >> > > _______________________________________________ > > es-discuss mailing list > > 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 > > _______________________________________________ > es-discuss mailing list > 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