Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make shadowing an early error but not a new namespace #4

Open
Jack-Works opened this issue Nov 19, 2020 · 14 comments
Open

Make shadowing an early error but not a new namespace #4

Jack-Works opened this issue Nov 19, 2020 · 14 comments

Comments

@Jack-Works
Copy link
Member

If the only motivation for isolated namespace is to prevent shadowing, I think we can make shadowing extensions becomes an early error.

@ljharb
Copy link
Member

ljharb commented Nov 19, 2020

I'm confused about that as a motivation, since linters handle that. What's wrong with shadowing?

@Jack-Works
Copy link
Member Author

I don't know, what's it seems like avoid shadowing is one of the main reason of introducing a new namespace.
@hax can you explain?

@hax
Copy link
Member

hax commented Nov 20, 2020

Yeah, I understand this is a uncommon design in our language. The other case is numeric literal suffixes and a potential case is decorators. I'd like to write a separate document to discuss the problem in a much general way.

@ljharb
Copy link
Member

ljharb commented Nov 21, 2020

Decorators as second class values was soundly rejected by the committee, as i understand it. I don’t think it’s a good approach.

@hax
Copy link
Member

hax commented Dec 3, 2020

@ljharb I agree second-class values is not a good idea for JS, but the cases I'm discussing is not second-class values, they are still first-class values, but could be declared/imported into a parallel lexical scope.

@ljharb
Copy link
Member

ljharb commented Dec 3, 2020

Let me rephrase: a parallel scope was also part of the rejected static decorators proposal, and i also don’t think that’s a good approach.

@Jack-Works
Copy link
Member Author

Jack-Works commented Dec 3, 2020

IIRC @hax has explained his reason to me in person.

The main reason is, these kinds of values (extension methods, numerical literals, decorators, ...) are very specialized uses. This means developers only want to use the value in this way (as a decorator, not a normal function). Any other references to these specialized values are highly likely to be a mistake.

But I have a question to @hax. What if I want to "compose" two extensions? (Use them as values, not in the extension space). Let's say, for example, use :: as the assumed grammar.

// extension.js
export function B() { ... }
export function A() { ... }
// use.js
import ::{ A, B } from './extension'
// This make A and B imported in the extension namespace
import { composeExtensions } from 'my-awesome-utils'

const C = composeExtensions(A, B)
// Oops, ReferenceError. I can't compose them
// cause they're in the extension namespace.
// lets-try-again.js
import { A, B } from './extension'
// In normal namespace
import { composeExtensions } from 'my-awesome-utils'

const C = composeExtensions(A, B)
// OK

"test"::C() // Oops, ReferenceError, C is not in the extension scope.
// finally.js
import { A, B } from './extension'
// In normal namespace
import { composeExtensions } from 'my-awesome-utils'

const C = composeExtensions(A, B)
const ::C = C
// Re-introduce a value to another namespace?
// Looks strange

"test"::C() // No error.

@ljharb
Copy link
Member

ljharb commented Dec 3, 2020

@Jack-Works I’m confused, i only brought up decorators as an example of second-class values and parallel scopes being subpar.

I’m not sure how your example relates to extensions.

@Jack-Works
Copy link
Member Author

@ljharb Hax's reason is applied across proposals (extension methods, numerical literals, decorators, ...). If my example confuses you, let me change my example to extension flavor. You can see how they're very identical in some way.

@ljharb
Copy link
Member

ljharb commented Dec 3, 2020

Decorators, just like template tag literals, will just be functions. If you want a function to only be run as a decorator or as a template tag, you’d have to manually write code to ensure that - just like you’d have to to prevent your function from being used as a decorator or a template tag.

I don’t want to be forced to create a variable - in a magic second scope or not - just to be able to safely extract and borrow a prototype method.

@hax
Copy link
Member

hax commented Dec 11, 2020

I understand JS traditionally leave all such responsibility to developers, unfortunately some features would become very impractical if the common cases would take some short and common names.

The best example is numeric suffix. A use case of it is polyfill of 1n 1d, which will take the common one char name like n or d, and suffer shadow issue seriously. This is why numeric suffix proposal have to choose second scope.

Both numeric suffix or extensions could be used to for units, a common case is CSS units, which also have many short names, like px, pc, s, deg, Q, etc. (And note we always need special treatment for in unit).

Decorators may be minor, so by itself may be ok to not use parallel scope. But generally speaking, they are similar. If numeric suffix and extensions use parallel scope, we could reconsider decorators to make the pattern consistent across features and make the mental model simpler.

@ljharb
Copy link
Member

ljharb commented Dec 11, 2020

It's not just a tradition; it's an intentional design choice. That a second scope would address it doesn't mean that's a viable solution, for this or any other proposal.

@hax
Copy link
Member

hax commented Dec 11, 2020

What if I want to "compose" two extensions?

This is a high-level usage which mostly only used by advanced users, and u could always do composing in a separate module. And actually u should, because it's just composing and have no relationship to extensions.

Note the difference with fp style which composing is relative common, in extensions(OO) style, normally extensions are defined in libraries or separate module.

This is also common practice in decorators --- decorators are declared in separate modules.

@hax
Copy link
Member

hax commented Dec 11, 2020

It's not just a tradition; it's an intentional design choice.

@ljharb There are many "intentional" design in the past and cause ux problems --- as JS was intentionally designed only for small scripts. I think we already fixed (or tried to fix) some past "intentional" design in every new versions intentionally. So this could be the new one. 😅

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants