-
Notifications
You must be signed in to change notification settings - Fork 6
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
Comments
I'm confused about that as a motivation, since linters handle that. What's wrong with shadowing? |
I don't know, what's it seems like avoid shadowing is one of the main reason of introducing a new namespace. |
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. |
Decorators as second class values was soundly rejected by the committee, as i understand it. I don’t think it’s a good approach. |
@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. |
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. |
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 // 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. |
@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. |
@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. |
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. |
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 Both numeric suffix or extensions could be used to for units, a common case is CSS units, which also have many short names, like 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. |
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. |
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. |
@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. 😅 |
If the only motivation for isolated namespace is to prevent shadowing, I think we can make shadowing extensions becomes an early error.
The text was updated successfully, but these errors were encountered: