What do you think about a C# 6 like nameof() expression for

Jordan Harband ljharb at gmail.com
Mon Jun 17 05:34:34 UTC 2019


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 <coagmano at 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 <guest271314 at 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 <coagmano at 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 <guest271314 at 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 <isiahmeadows at 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
> contact at isiahmeadows.com
> www.isiahmeadows.com
>
> On Sun, Jun 16, 2019 at 12:00 AM guest271314 <guest271314 at 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.Buckton at 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 at 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.Buckton at 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 <guest271314 at gmail.com>
> >> Sent: Saturday, June 15, 2019 3:57 PM
> >> To: Ron Buckton <Ron.Buckton at microsoft.com>
> >> Cc: es-discuss at 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.Buckton at microsoft.com>
> wrote:
> >>
> >> Sorry, I meant to say “not entirely correct”.
> >>
> >> From: Ron Buckton
> >> Sent: Saturday, June 15, 2019 3:03 PM
> >> To: guest271314 <guest271314 at gmail.com>
> >> Cc: es-discuss at 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 at mozilla.org
> > https://mail.mozilla.org/listinfo/es-discuss
>
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
> _______________________________________________
> 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/20190616/5e6bf8ed/attachment-0001.html>


More information about the es-discuss mailing list