``` const f = () => y;
let y = 1; ``` is different (dissimilar) code than the original reference example code. > I don’t disagree that there are “alternative approaches” to ‘nameof’ for many cases, but they all incur overhead. Given that a ```ReferenceError``` is thrown when attempting to reference a variable declared using ```const``` where the ```message``` property includes the name of the variable, either the specification and, or the implementers are already getting the name of the idetifier as a string and outputing the described requirement of ```nameof``` in a similar context. Thus, the code already exists. It would appear it is now a matter of locating that source code in browser implementations and abstracting the process to a ```nameof``` function or operator. Have you looked into the source code of browsers that implement ```const``` to determine the issues, if any, as to utilizing the existiing implementation(s) of ```ReferenceError``` to facilitate ```nameof``` while avoiding incurring the described "overhead" of using workarounds to achieve the same output? On Sat, Jun 15, 2019 at 10:03 PM Ron Buckton <ron.buck...@microsoft.com> wrote: > > 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: > > > > ``` > > const f = () => y; > > let y = 1; > > ``` > > > > > That fact can be utilized for an alternative approach to meet > requirement of "Case 1. Function guard.". > > > > I don’t disagree that there are “alternative approaches” to ‘nameof’ for > many cases, but they all incur overhead. > > > > At the end of the day, ‘nameof’ is a convenience feature that provides an > incremental “quality of life” improvement, much like shorthand property > assignments were a convenience feature (i.e. how hard is it to write `{ > foo: foo }`). It’s not something that would be as much of a game changer to > the language as async/await or yield were, but it would be a fairly easily > spec’d and nice-to-have capability. > > > > *From:* guest271314 <guest271...@gmail.com> > *Sent:* Saturday, June 15, 2019 2:50 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 > > > > > It doesn’t matter what the *value* of ‘y’ is, just what the lexical > name of `y` is. `nameof` wouldn’t refer to `y` as an expression, its just > pointing to the identifier. > > > > Was not referring to the _value_ of ```y```. At that point in the example > code the identifer ```y``` does not exist. That is, unless there was an > expected presumption that ```y``` was defined globally prior to the > ```const y = 1;``` declaration at the next line. Even then a variable > declared using ```const``` cannot be referenced before "lexical > declaration" or "initialization". That fact can be utilized for an > alternative approach to meet requirement of "Case 1. Function guard.". > Tested at Chromium 76 and Firefox 69. Have not used MS browser (or > browserstack) in some time. Have not tried the code at Safari either, > though the code is capable of adjustment for any JavaScript environment > which throws a ```ReferenceError``` under the same case > > > > ``` > > function func1(param1, param2, param3, userName, param4, param5) { > if (userName === undefined) { > try { > // throws ReferenceError > // Firefox 69: ReferenceError: "can't access lexical declaration > `userName' before initialization" > // Chromium 76: ReferenceError: Cannot access 'userName' before > initialization > const userName = userName; > } catch (e) { > // match identifier at Firefox, Chromium ReferenceError message > // adjust RegExp for IE/Edge, Safari, etc. > const nameof = e.message.match(/(?!`|')[^\s]+(?=')/g).pop(); > throw new Error(`"Argument cannot be null: ${nameof}"`); > } > } else { > // do stuff > console.log(userName); > } > } > > try { > func1(1, 2, 3); // throws error > } catch (e) { > console.error(e); // get name of variable identifier > } > > try { > func1(1, 2, 3, 4); // logs userName at console > } catch (e) { > console.error(e); // should not be reached > } > > ``` > > > > On Sat, Jun 15, 2019 at 9:37 PM Ron Buckton <ron.buck...@microsoft.com> > wrote: > > It doesn’t matter what the *value* of ‘y’ is, just what the lexical name > of `y` is. `nameof` wouldn’t refer to `y` as an expression, its just > pointing to the identifier. > > > > *From:* guest271314 <guest271...@gmail.com> > *Sent:* Friday, June 14, 2019 10:03 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 > > > > > I’m not sure I understand what you mean by “false-positive” in this > instance. > > > > Was referring to > > > > const x = nameof y; // "y" > > const y = 1; > > > > Where ```y``` is ```undefined``` an error is not expected to be thrown? Is > ```y``` declared globally, using ```const``` or ```let```, or not at all? > The use case described by OP > > > > function func1(param1, param2, param3, userName, param4, param5) { > > if (userName == undefined) { > > throw new ArgumentNullError(nameof userName); // `ArgumentNullError` > > is a custom error, derived from `Error`, composes error message like > > "Argument cannot be null: userName". > > } > > checks if ```userName``` was ```undefined``` before using ```nameof```. > If error checking is a substantial portion of the proposal, why should an > error (```y``` being ```undefined``` though referenced) be ignored when > referencing an undefined identifier though concentrate on coercing a name > from a different potentially undefined property? > > > > Consider this case: > ``` > const someObject = { value: 1 }; > function setValue(value /*1*/) { > if (typeof value /*2*/ !== "number") throw new TypeError(`Number > expected: ${nameof value /*3*/}`); > someObject["value" /*4*/] = value /*5*/; > } > ``` > > If you rename the parameter `value` of the function `setValue` in an > editor with a rename refactoring, you want to rename the symbols at 1, 2, > 3, and 5, but not the string at 4. > > > > Not gathering the purpose or value of ```nameof``` usage in that case. If > the value is not a "number" then why does the value or name matter? > > > > Since the primary use case appears to be an editor environment, why cannot > the editor be programmed to recognize the custom JavaScript ```nameof```` > function or operator? Then it would not matter if this board concurred with > the ```nameof``` functionality or not. Both CLI and GUI editors (and > JavaScript) are generally extensible. FWIW, some time ago incorporated > features into gedit for HTML templates; should be a similar process to > create custom scripts for the various editor environments where users rely > on such programs for code composition; now simply write the code by hand > and test in different environments, without taking the time to customize or > rely on an editor - take the time to test the code where the code will > actually be run where errors, if any, can be evaluated in the context in > which a specific output is expected. To each their own. What needs to be > implemented outside of what the users which advocate for ```nameof``` > cannot implement themselves? > > > > As mentioned earlier do not rely on "an editor with name refactoring" to > compose code. The code has to be tested (outside of the editor > environments) anyway. Test the code itself, here, not the editor. > > > > On Fri, Jun 14, 2019 at 9:49 PM Ron Buckton <ron.buck...@microsoft.com> > wrote: > > I’m not sure I understand what you mean by “false-positive” in this > instance. > > > > Consider this case: > > > > ``` > > const someObject = { value: 1 }; > > function setValue(value /*1*/) { > > if (typeof value /*2*/ !== "number") throw new TypeError(`Number > expected: ${nameof value /*3*/}`); > > someObject["value" /*4*/] = value /*5*/; > } > > ``` > > > > If you rename the parameter `value` of the function `setValue` in an > editor with a rename refactoring, you want to rename the symbols at 1, 2, > 3, and 5, but not the string at 4. > > > > Ron > > > > *From:* guest271314 <guest271...@gmail.com> > *Sent:* Friday, June 14, 2019 2:43 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 > > > > How is that behaviour related to the use cases presented by OP? Would such > behaviour not lead to false-positive relevant to the 2 use cases? > > > > On Fri, Jun 14, 2019 at 9:36 PM Ron Buckton <ron.buck...@microsoft.com> > wrote: > > > `nameof whatever` → `Object.keys({ whatever })[0]`, but I'm a bit > confused why it'd be better to type `nameof foo` in code, rather than > `'foo'` - if you change `foo` to `bar`, you have to change both of them > anyways. > > > > If you are using an editor that supports rename refactoring, its generally > easier to rename the symbol `foo` and have all references (including > `nameof foo`) be updated. You cannot safely automatically rename `'foo'` to > `'bar'` since an editor or language service cannot guarantee that by the > string `'foo'` you meant “the text of the identifier `foo`”. > > > > *From:* es-discuss <es-discuss-boun...@mozilla.org> *On Behalf Of *Jordan > Harband > *Sent:* Friday, June 14, 2019 2:29 PM > *To:* guest271314 <guest271...@gmail.com> > *Cc:* es-discuss <es-discuss@mozilla.org> > *Subject:* Re: Re: What do you think about a C# 6 like nameof() > expression for > > > > `nameof whatever` → `Object.keys({ whatever })[0]`, but I'm a bit confused > why it'd be better to type `nameof foo` in code, rather than `'foo'` - if > you change `foo` to `bar`, you have to change both of them anyways. > > > > On Fri, Jun 14, 2019 at 1:31 PM guest271314 <guest271...@gmail.com> wrote: > > Am neither for nor against the proposal. Do not entertain "like"s or > "dislike"s in any field of endeavor. Am certainly not in a position to > prohibit anything relevant JavaScript. Do what thou wilt shall be the whole > of the Law. > > Have yet to view a case where code will be "broken" by ```nameof``` not > being a JavaScript feature. "robustness", as already mentioned, is a > subjective adjective that is not capable of being objectively evaluated as > to code itself. That description is based on preference or choice. > > > > In lieu of the proposal being specificed, use the posted code example of > ```Object.keys()``` that "works". > > > > ``` > > function func1({userName = void 0} = {}) { > console.assert(userName !== undefined, [{userName}, 'property needs to > be defined']) > } > > ``` > > > > provides a direct indication that the property value is required to be > defined. Note that the example code posted thus far does not first check if > ```options``` is passed at all, for which ```nameof``` will not provide any > asssitance. > > > > Usually try to meet requirement by means already available in FOSS > browsers. Have no interest in TypeScript or using an IDE. > > > > FWIW, have no objection to the proposal. > > > > On Fri, Jun 14, 2019 at 7:53 PM Stas Berkov <stas.ber...@gmail.com> wrote: > > guest271314, what is you point against `nameof` feature? > > If you don't like it - don't use it. Why prohibit this feature for > those who find it beneficial? > > I see `nameof` beneficial in following cases > > Case 1. Function guard. > ``` > function func1(options) { > ... > if (options.userName == undefined) { > throw new ParamNullError(nameof options.userName); // > `ParamNullError` is a custom error, derived from `Error`, composes > error message like "Parameter cannot be null: userName". > // `Object.keys({options.userName})[0]` will not work here > } > } > ``` > > Case 2. Accessing property extended info > Those ES functions that accept field name as string. > e.g. > ``` > const descriptor1 = Object.getOwnPropertyDescriptor(object1, 'property1'); > ``` > vs > ``` > const descriptor1 = Object.getOwnPropertyDescriptor(object1, nameof > object1.property1); > // `Object.keys({options1.property1})[0]` will not work here > ``` > 2nd variant (proposed) has more chances not to be broken during > refactoring (robustness). > > It would make devs who use IDE more productive and make their life > easier. Why not give them such possiblity and make them happy? > > _______________________________________________ > es-discuss mailing list > es-discuss@mozilla.org > https://mail.mozilla.org/listinfo/es-discuss > <https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fmail.mozilla.org%2Flistinfo%2Fes-discuss&data=02%7C01%7CRon.Buckton%40microsoft.com%7C4036bd0c96744cab8c4208d6f1db7291%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636962322162641169&sdata=U%2B%2Fq939hNKeRQlHnXNvoEPvcoi01IR3T56Jv7eOJSlg%3D&reserved=0> >
_______________________________________________ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss