Why packages and namespaces?
I think Brendan had a nice explanation of that some time back:
Thanks for reposting Brendan's explaination. I did look around but didn't find it.
On Jan 27, 2008 11:45 PM, liorean <liorean at gmail.com> wrote:
I think Brendan had a nice explanation of that some time back:
On 10/08/2007, Brendan Eich <brendan at mozilla.org> wrote:
There's more work to do, including rationalizing and minimizing concepts including units and packages. A couple of notes:
A package is a named pair of namespaces (public and internal), some rules for using those namespaces within the package body, and some special forms for importing names from the package's public namespace.
[snip]
Here is a concrete problem. I tried this in the reference implementation...
package org { public var ecmascript = {a: 1}; }
package org.ecmascript { public var a = 2; }
org.ecmascript.a // 2
How do I access the "org.ecmascript.a" that has value 1?
How does the programmer writing the org package know that his "a" will be clobbered by the "a" in the org.ecmascript package? Isn't the point of packages to avoid this type of problem?
Thanks, Peter
Packages, combined with 'internal', are a specialized subset of namespaces, with usage restrictions and a convenient syntax to cater for a common use case. Namespaces are more general: any declaration (local variables or any function or variable defined in a package, class, structural type or dynamic object instance) may belong to a namespace. ES4 namespaces also provide very neat integration with namespaces in E4X.
Peter
On Jan 28, 2008 12:04 AM, Peter Michaux <petermichaux at gmail.com> wrote:
Here is a concrete problem. I tried this in the reference implementation...
package org { public var ecmascript = {a: 1}; }
package org.ecmascript { public var a = 2; }
org.ecmascript.a // 2
How do I access the "org.ecmascript.a" that has value 1?
How does the programmer writing the org package know that his "a" will be clobbered by the "a" in the org.ecmascript package? Isn't the point of packages to avoid this type of problem?
Is this not considered a big problem? It seems like one to me.
Peter
On 1/30/08 9:17 AM, Peter Michaux wrote:
On Jan 28, 2008 12:04 AM, Peter Michaux <petermichaux at gmail.com> wrote:
Here is a concrete problem. I tried this in the reference implementation...
package org { public var ecmascript = {a: 1}; }
package org.ecmascript { public var a = 2; }
org.ecmascript.a // 2
How do I access the "org.ecmascript.a" that has value 1?
import org.; import org.ecmascript.; ... = org.ecmascript.a ... = a
for example. The secret is in the lookup rules for packages: longest match works. Perhaps there is a bug in the reference implementation.
How does the programmer writing the org package know that his "a" will be clobbered by the "a" in the org.ecmascript package?
He doesn't. But it's out of his hands since he can't know what code exists outside of his world that a user might intermingle with his.
Here's another example, which packages won't help with:
import org.ecmascript.a; var org = {ecmascript: 4}
... = org.ecmascript.a // error: a is undefined in 'ecmascript'
The var 'org' shadows the first identifier in package 'org.ecmascript'.
This can be worked around by narrowing the scope of the 'import' so that it shadows the var 'obj'. At least that is what I would expect. Need to check.
point of packages to avoid this type of problem?
I'd say "to help avoid", yes.
Is this not considered a big problem? It seems like one to me.
What do you suggest we do differently?
On 1/30/08 9:35 AM, Jeff Dyer wrote:
On 1/30/08 9:17 AM, Peter Michaux wrote:
On Jan 28, 2008 12:04 AM, Peter Michaux <petermichaux at gmail.com> wrote:
Here is a concrete problem. I tried this in the reference implementation...
package org { public var ecmascript = {a: 1}; }
package org.ecmascript { public var a = 2; }
org.ecmascript.a // 2
How do I access the "org.ecmascript.a" that has value 1?
import org.; import org.ecmascript.; ... = org.ecmascript.a ... = a
for example. The secret is in the lookup rules for packages: longest match works. Perhaps there is a bug in the reference implementation.
Sorry, I misread. Apparently the RI is doing the right thing in this example. The way to make the package 'org' accessible is to give it higher precedence than package 'org.ecmascript'. That should be possible by placing its import directive in a narrower scope than 'import org.ecmascript.*'. Or leaving the import of 'org.ecmascript' out of the program altogether.
Note: your program doesn't have import directives. It is a bug in the language that packages that aren't imported are considered in the name resolution process. (ticket #349 created)
On Jan 30, 2008 9:35 AM, Jeff Dyer <jodyer at adobe.com> wrote:
Here's another example, which packages won't help with:
import org.ecmascript.a; var org = {ecmascript: 4}
... = org.ecmascript.a // error: a is undefined in 'ecmascript'
[...]
What do you suggest we do differently?
The obvious thing would be to change package reference syntax, e.g., by using a symbol other than periods. But this would break backwards compatibility, so it's not an option.
In prior cases of language ambiguity, an alternate syntax was created. For example "Array(x)" was ambiguous, so "x as Array" was created as another way to cast variables. Similarly, there could be an alternate syntax for inline package references, e.g., "package(org.ecmascript).a".
This kind of seems like language bloat, though. In practice, just about everyone uses capitalized camel-humped names for classes and lower-case camel-humped names for fields and methods, so this issue doesn't come up.
On Jan 30, 2008 7:15 PM, T. Michael Keesey <keesey at gmail.com> wrote:
On Jan 30, 2008 9:35 AM, Jeff Dyer <jodyer at adobe.com> wrote:
Here's another example, which packages won't help with:
import org.ecmascript.a; var org = {ecmascript: 4}
... = org.ecmascript.a // error: a is undefined in 'ecmascript'
[...]
What do you suggest we do differently?
The obvious thing would be to change package reference syntax, e.g., by using a symbol other than periods. But this would break backwards compatibility, so it's not an option.
In prior cases of language ambiguity, an alternate syntax was created. For example "Array(x)" was ambiguous, so "x as Array" was created as another way to cast variables. Similarly, there could be an alternate syntax for inline package references, e.g., "package(org.ecmascript).a".
Or perhaps package["org.ecmascript"].a if that can be made to work syntactically.
This kind of seems like language bloat, though. In practice, just about everyone uses capitalized camel-humped names for classes and lower-case camel-humped names for fields and methods, so this issue doesn't come up.
I disagree; being able to clobber identifiers like this is just the kind of thing that is useful to malicious code, opening attack vectors on code by changing its meaning and function underfoot.
And while this particular allegation might not constitute a designed-in security hole, I still consider it bad form to devise new orthogonal ways of populating the identifier namespace, without at the same time devising matching orthogonal ways of unambiguously traversing those structures.
(The above reasoning is for the case where no imports have been made.
From my point of view, if you use import, you explicitly ask for
clobbering your namespace. Not that I'd mind solutions to ambiguity cases that creep up there either, but it ranks lower on my issue meter. :-)
I'd vote for a runtime error like:
Declaration of "var ecmascript" conflicts with existing package declaration "org.ecmascript".
This check would be made at runtime when the var declaration is ran. This behavior would then be unambiguous, and would be compatible with other programming languages.
2008/2/4, Johan Sundström <oyasumi at gmail.com>:
What it the reason for ES4 having both packages and namespaces? It seems like both can be used to protect the global namespace from clutter and otherwise avoid identifier clashes. When to use one and when to use the other?
Thank you, Peter