|
View:
New views
20 Messages
—
Rating Filter:
Alert me
|
| < Prev | 1 - 2 - 3 | Next > |
|
|
Nested package scopes vs. Imports (Was: Revisiting absolute/relative paths)On Thu, Jul 16, 2009 at 3:09 PM, David MacIver<david.maciver@...> wrote:
> 2009/7/16 Kevin Wright <kev.lee.wright@...>: >> for a given import: >> import foo.bar.baz >> >> I propose that foo and foo.bar not be considered for subsequent relative >> imports >> Neither package has been explicitly imported, and both were simply mentioned >> "in passing" as part of the fully-qualified path to the import of >> foo.bar.baz >> >> I'm happy of course to see further debate on this proposal and how it could >> be considered as adding a pile of special cases or breaking consistency. > > You're right, of course. This doesn't add a pile of special cases or > break consistency because it's exactly how things already behave. > Importing foo.bar.baz doesn't import foo or bar. This exchange goes a long way in illustrating the confusion here ... I think that most people coming to Scala from Java look at, package a.b.c import a.b.d.Foo // OK import b.Bar // OK too! Huh? How is b in scope and assume that it's the import which is in someway responsible for their surprise. But it's not, it's the package declaration at the top of the file which is responsible. Desugaring to, package a { package b { package c { import a.b.d.Foo // OK import b.Bar // OK too ... clearly b is in scope } } } makes the behaviour crystal clear. What's also crystal clear is that this is very different from Java, and that from an Java perspective it involves a surprising capture of (typically unrelated) scopes (as you observed earlier in this thread). I'm not at all sure what the right thing to do here is. It clearly is a problem, but on the other hand it is a useful feature. I like your proposal of only capturing the enclosing scopes if the desugared syntax is use and having the more common "package a.b.c" not cause the scope capture. But does that eliminate the usefulness of package nesting so much it might as well be dropped altogether? Cheers, Miles -- Miles Sabin tel: +44 (0)7813 944 528 skype: milessabin http://www.chuusai.com/ http://twitter.com/milessabin |
|
|
Re: Nested package scopes vs. Imports (Was: Revisiting absolute/relative paths)As we're moving to a new thread, I'll repost my last entry from there :)
It looks to me like package names typically have two parts with different semantic meanings. - First, there is an static part. Usually the reversed domain name of the project website, such as org.hibernate or net.liftweb - Second is a dynamic part, which refers to packages within a single project or group of closely related projects. It is only within this dynamic part that relative imports make sense. Given this understanding, the difference in purpose between parts of the package name can then be made explicit: package `net.liftweb` or package `org.hibernate`.engine.query.sql The content within the backticks is considered as an atomic identifier in its own right, and cannot be further subdivided for the purpose of relative imports. After the backticks, anything goes, it's business as usual... On Thu, Jul 16, 2009 at 3:35 PM, Miles Sabin <miles@...> wrote: On Thu, Jul 16, 2009 at 3:09 PM, David MacIver<david.maciver@...> wrote: |
|
|
Re: Nested package scopes vs. Imports (Was: Revisiting absolute/relative paths)Of course, I'm happy to substitute the backtick for any other character that's more accessible on a swiss keyboard.
Perhaps braces could be repurposed? package {org.hibernate}.engine.query.sql On Thu, Jul 16, 2009 at 3:45 PM, Kevin Wright <kev.lee.wright@...> wrote: As we're moving to a new thread, I'll repost my last entry from there :) |
|
|
Re: Nested package scopes vs. Imports (Was: Revisiting absolute/relative paths)I quite like both Miles' and Kevin's proposals. I am not at all keen
to fiddle with scope resolution rules -- they are complicated enough as it is (easier than Java's but still quite complicated). But the idea of fiddling with visible package nesting has potential, IMO. Of the two proposals Miles' is the cleanest and most consistent, but not backwards compatible. Kevin's proposal is backwards compatible by requiring new syntax for disabling nesting. But it slightly misuses the backtick ident rule. I.e. what if I want a package (i.e. directory) with name `my.package`. Then Kevin's rule would give me something else. Yet another variation would be to adopt miles proposal with the twist that package foo.bar.baz; ... means package foo { package bar { package baz { ... }}} instead of package foo.bar.baz { ... }| That way, one can still disable package nesting by using braced package clauses like the one above, yet the large majority for programs that use a Java style package clause would work as before. I don't particularly like this twist, and prefer Miles proposal, really, except for backwards compatibility. Note that with any of the proposals one can always back get relative imports by importing the package that's at the root of the relative imports. For instance, the following would work OK package `scala.tools.nsc` import scala._ import collection.immutable.Vector Cheers -- Martin On Thu, Jul 16, 2009 at 4:45 PM, Kevin Wright<kev.lee.wright@...> wrote: > As we're moving to a new thread, I'll repost my last entry from there :) > > > It looks to me like package names typically have two parts with different > semantic meanings. > - First, there is an static part. Usually the reversed domain name of the > project website, such as org.hibernate or net.liftweb > - Second is a dynamic part, which refers to packages within a single project > or group of closely related projects. > > It is only within this dynamic part that relative imports make sense. > > Given this understanding, the difference in purpose between parts of the > package name can then be made explicit: > package `net.liftweb` > or > package `org.hibernate`.engine.query.sql > > The content within the backticks is considered as an atomic identifier in > its own right, and cannot be further subdivided for the purpose of relative > imports. After the backticks, anything goes, it's business as usual... > > > On Thu, Jul 16, 2009 at 3:35 PM, Miles Sabin <miles@...> wrote: >> >> On Thu, Jul 16, 2009 at 3:09 PM, David MacIver<david.maciver@...> >> wrote: >> > 2009/7/16 Kevin Wright <kev.lee.wright@...>: >> >> for a given import: >> >> import foo.bar.baz >> >> >> >> I propose that foo and foo.bar not be considered for subsequent >> >> relative >> >> imports >> >> Neither package has been explicitly imported, and both were simply >> >> mentioned >> >> "in passing" as part of the fully-qualified path to the import of >> >> foo.bar.baz >> >> >> >> I'm happy of course to see further debate on this proposal and how it >> >> could >> >> be considered as adding a pile of special cases or breaking >> >> consistency. >> > >> > You're right, of course. This doesn't add a pile of special cases or >> > break consistency because it's exactly how things already behave. >> > Importing foo.bar.baz doesn't import foo or bar. >> >> This exchange goes a long way in illustrating the confusion here ... >> >> I think that most people coming to Scala from Java look at, >> >> package a.b.c >> >> import a.b.d.Foo // OK >> import b.Bar // OK too! Huh? How is b in scope >> >> and assume that it's the import which is in someway responsible for >> their surprise. >> >> But it's not, it's the package declaration at the top of the file >> which is responsible. Desugaring to, >> >> package a { >> package b { >> package c { >> >> import a.b.d.Foo // OK >> import b.Bar // OK too ... clearly b is in scope >> } >> } >> } >> >> makes the behaviour crystal clear. >> >> What's also crystal clear is that this is very different from Java, >> and that from an Java perspective it involves a surprising capture of >> (typically unrelated) scopes (as you observed earlier in this thread). >> >> I'm not at all sure what the right thing to do here is. It clearly is >> a problem, but on the other hand it is a useful feature. >> >> I like your proposal of only capturing the enclosing scopes if the >> desugared syntax is use and having the more common "package a.b.c" not >> cause the scope capture. But does that eliminate the usefulness of >> package nesting so much it might as well be dropped altogether? >> >> Cheers, >> >> >> Miles >> >> -- >> Miles Sabin >> tel: +44 (0)7813 944 528 >> skype: milessabin >> http://www.chuusai.com/ >> http://twitter.com/milessabin > > |
|
|
Re: Nested package scopes vs. Imports (Was: Revisiting absolute/relative paths)2009/7/16 Miles Sabin <miles@...>:
> On Thu, Jul 16, 2009 at 3:09 PM, David MacIver<david.maciver@...> wrote: >> 2009/7/16 Kevin Wright <kev.lee.wright@...>: >>> for a given import: >>> import foo.bar.baz >>> >>> I propose that foo and foo.bar not be considered for subsequent relative >>> imports >>> Neither package has been explicitly imported, and both were simply mentioned >>> "in passing" as part of the fully-qualified path to the import of >>> foo.bar.baz >>> >>> I'm happy of course to see further debate on this proposal and how it could >>> be considered as adding a pile of special cases or breaking consistency. >> >> You're right, of course. This doesn't add a pile of special cases or >> break consistency because it's exactly how things already behave. >> Importing foo.bar.baz doesn't import foo or bar. > > This exchange goes a long way in illustrating the confusion here ... > > I think that most people coming to Scala from Java look at, > > package a.b.c > > import a.b.d.Foo // OK > import b.Bar // OK too! Huh? How is b in scope > > and assume that it's the import which is in someway responsible for > their surprise. > > But it's not, it's the package declaration at the top of the file > which is responsible. Desugaring to, > > package a { > package b { > package c { > > import a.b.d.Foo // OK > import b.Bar // OK too ... clearly b is in scope > } > } > } > > makes the behaviour crystal clear. > > What's also crystal clear is that this is very different from Java, > and that from an Java perspective it involves a surprising capture of > (typically unrelated) scopes (as you observed earlier in this thread). > > I'm not at all sure what the right thing to do here is. It clearly is > a problem, but on the other hand it is a useful feature. > > I like your proposal of only capturing the enclosing scopes if the > desugared syntax is use and having the more common "package a.b.c" not > cause the scope capture. But does that eliminate the usefulness of > package nesting so much it might as well be dropped altogether? I don't think one can get rid of package nesting. My proposal was purely about whether the definitions are considered to be nested or just the result (i.e with package foo.bar, bar is still a member of foo but foo is not in scope here) If you're going to allow declarations of the form package foo{ package bar{ } } then foo's contents really have to be in scope in bar. Scala has the nice property that everything captures its defining scope, and it would be a shame to throw it away. But package foo.bar; can be regarded as having its defining scope being the top level, so not bringing the parent packages into scope there is much less problematic. |
|
|
Re: Nested package scopes vs. Imports (Was: Revisiting absolute/relative paths)On Thu, Jul 16, 2009 at 4:09 PM, martin odersky<martin.odersky@...> wrote:
> I quite like both Miles' and Kevin's proposals. Minor clarification ... that was actually David's proposal ... Cheers, Miles -- Miles Sabin tel: +44 (0)7813 944 528 skype: milessabin http://www.chuusai.com/ http://twitter.com/milessabin |
|
|
Re: Nested package scopes vs. Imports (Was: Revisiting absolute/relative paths)On Thu, Jul 16, 2009 at 5:12 PM, Miles Sabin<miles@...> wrote:
> On Thu, Jul 16, 2009 at 4:09 PM, martin odersky<martin.odersky@...> wrote: >> I quite like both Miles' and Kevin's proposals. > > Minor clarification ... that was actually David's proposal ... > Ah, thank you. It's hard to keep current with the mail volume. As another clarification I guess nobody proposes that package nesting be dropped. I.e. even if I write package foo.bar { } The package `bar` is still a member of the package `foo`. It's just that the members of `foo` would not be considered an outer scope for the stuff in the braces. Cheers -- Martin |
|
|
Re: Nested package scopes vs. Imports (Was: Revisiting absolute/relative paths)2009/7/16 martin odersky <martin.odersky@...>:
> I quite like both Miles' and Kevin's proposals. I am not at all keen > to fiddle with scope resolution rules -- they are complicated enough > as it is (easier than Java's but still quite complicated). But the > idea of fiddling with visible package nesting > has potential, IMO. Of the two proposals Miles' is the cleanest and > most consistent, but not backwards compatible. Kevin's proposal is > backwards compatible by requiring new syntax for disabling nesting. > But it slightly misuses the backtick ident rule. I.e. what if I want a > package (i.e. directory) with name > `my.package`. Then Kevin's rule would give me something else. > Yet another variation would be to adopt miles proposal with the twist that > > package foo.bar.baz; ... > > means > > package foo { package bar { package baz { ... }}} > > instead of > > package foo.bar.baz { ... }| > > That way, one can still disable package nesting by using braced > package clauses like the one above, yet the large majority for > programs that use a Java style package clause would work as before. I > don't particularly like this twist, and prefer Miles proposal, really, > except for backwards compatibility. > > Note that with any of the proposals one can always back get relative imports by > importing the package that's at the root of the relative imports. For > instance, the following would work OK As an idle observation (and not one I'll back to the death if people disagree with me), I think the backwards compatibility argument here isn't too compelling. The thing is, the cost of breaking backwards compatibility here is that you'll have to touch a lot of source files to add an import statement. This is unfortunate. But as the lift example shows, the cost of not breaking compatibility here is that the addition of something to the classpath can cause you to touch a lot of source files to qualify a large number of your imports with _root_. So breaking backwards compatibility is a one time cost that should be cheaper than the cost of something that can happen accidentally at any time without the compatibility break. Of course, I still hold that if you don't hold to Java package name conventions then this accident is vanishingly unlikely, but I seem to be outruled on whether that's an acceptable solution. |
|
|
Re: Nested package scopes vs. Imports (Was: Revisiting absolute/relative paths)On Thu, Jul 16, 2009 at 4:16 PM, martin odersky<martin.odersky@...> wrote:
> On Thu, Jul 16, 2009 at 5:12 PM, Miles Sabin<miles@...> wrote: >> On Thu, Jul 16, 2009 at 4:09 PM, martin odersky<martin.odersky@...> wrote: >>> I quite like both Miles' and Kevin's proposals. >> >> Minor clarification ... that was actually David's proposal ... >> > Ah, thank you. It's hard to keep current with the mail volume. As > another clarification I guess nobody proposes that package nesting be > dropped. I.e. even if I write > > package foo.bar { > > } > > The package `bar` is still a member of the package `foo`. It's just that > the members of `foo` would not be considered an outer scope for the > stuff in the braces. That's correct. Cheers, Miles -- Miles Sabin tel: +44 (0)7813 944 528 skype: milessabin http://www.chuusai.com/ http://twitter.com/milessabin |
|
|
Re: Nested package scopes vs. Imports (Was: Revisiting absolute/relative paths)2009/7/16 martin odersky <martin.odersky@...>:
> On Thu, Jul 16, 2009 at 5:12 PM, Miles Sabin<miles@...> wrote: >> On Thu, Jul 16, 2009 at 4:09 PM, martin odersky<martin.odersky@...> wrote: >>> I quite like both Miles' and Kevin's proposals. >> >> Minor clarification ... that was actually David's proposal ... >> > Ah, thank you. It's hard to keep current with the mail volume. As > another clarification I guess nobody proposes that package nesting be > dropped. I.e. even if I write > > package foo.bar { > > } > > The package `bar` is still a member of the package `foo`. It's just that > the members of `foo` would not be considered an outer scope for the > stuff in the braces. Very definitely. My intent was that the only difference between package foo.bar { } and package foo { package bar { } } is that the defining scope of the inner most braces of the first is the top level, while the second it's the package foo. Clearly the latter should be considered a member of foo, therefore the former should too. And even without this argument, relative imports of subpackages are way too useful to ditch. |
|
|
Re: Nested package scopes vs. Imports (Was: Revisiting absolute/relative paths)May I recall a proposal that was made some time ago by I-dont-remember-whom?
1) Make all imports absolute by default import com.example._ // means "import _root_.com.example._" 2) Relative imports would be prefixed by "_" import _.util.StringUtils While not backward compatible, this proposal has the advantage of being very friendly to Java developers (no surprises) and clarifies the intended scope of the import. alex |
|
|
Re: Nested package scopes vs. Imports (Was: Revisiting absolute/relative paths)It looks as though package and object namespaces are moving towards some kind of unification anyway, that would allow us to drop the java-style package naming that seems to cause this problem in the first place.
We could then have: package foo.bar { package baz { <relative imports from foo don't work here> } } Which seems to capture all the requirements nicely. Choose something instead of backticks to avoid breaking anything and my suggestion could also be used as an interim, side-by-side with deprecating the old style package specification. On Thu, Jul 16, 2009 at 4:18 PM, David MacIver <david.maciver@...> wrote: 2009/7/16 martin odersky <martin.odersky@...>: |
|
|
Re: Nested package scopes vs. Imports (Was: Revisiting absolute/relative paths)2009/7/16 Alex Boisvert <boisvert@...>:
> May I recall a proposal that was made some time ago by I-dont-remember-whom? I'd rather you didn't. > 1) Make all imports absolute by default > > import com.example._ // means "import _root_.com.example._" > > 2) Relative imports would be prefixed by "_" > > import _.util.StringUtils > > While not backward compatible, this proposal has the advantage of being very > friendly to Java developers (no surprises) and clarifies the intended scope > of the import. Rather than respond to this specifically, I'd like to point out something that I think a lot of people have overlooked: The problem that sparked this discussion has absolutely nothing to do with imports and can be observed without ever mentioning the word "import". The problem is purely that the "fully" qualified name java.io.File does not necessarily point to what you think it does because of the ability to shadow. There is no way to fix this without completely rewriting the rules Scala uses to refer to all identifiers. This is why we are discussing fixes to limit to possibilities for accidental shadowing instead. |
|
|
Re: Nested package scopes vs. Imports (Was: Revisiting absolute/relative paths)On Thu, Jul 16, 2009 at 5:24 PM, Alex Boisvert<boisvert@...> wrote:
> May I recall a proposal that was made some time ago by I-dont-remember-whom? > > 1) Make all imports absolute by default > > import com.example._ // means "import _root_.com.example._" > > 2) Relative imports would be prefixed by "_" > > import _.util.StringUtils > syntax of an import clause import StableId `.' (id | `_' | ImportSelectors) StableId ::= id | Path `.' id | [id '.'] `super' [ClassQualifier] `.' id The proposal means that a StableId in an import should be name-resolved differently from StableId's everywhere else. Not good. Second, that proposal would not solve direct access with fully qualified names. Third, that proposal would annoyingly complicate idioms such as: def f(env: Environment) { import env._ ... } Fourth, the proposal would misuse the underscore, which so far means "unknown quantity". For all of these reasons, this is clearly not a path I want to take. Cheers -- Martin > While not backward compatible, this proposal has the advantage of being very > friendly to Java developers (no surprises) and clarifies the intended scope > of the import. > > alex > |
|
|
Re: Nested package scopes vs. Imports (Was: Revisiting absolute/relative paths)Fair enough. Thanks both (David and Martin) for explaining why it wouldn't work so well.
alex On Thu, Jul 16, 2009 at 8:36 AM, martin odersky <martin.odersky@...> wrote:
|
|
|
Re: Nested package scopes vs. Imports (Was: Revisiting absolute/relative paths)This proposal makes a lot of sense. But it's going to add an exception
to indentation rules (whether mental or automatic in the future) because you probably don't want to change indentation of a file depending on how much nested levels of packages you have and it also means you have to change the end of a file if you change the level of nesting. I guess this is a really minor concern but it would be nice if there was a minimal syntax for this that would only affect the first lines in a file. I can't think of anything though. David MacIver wrote: > 2009/7/16 Miles Sabin <miles@...>: > >> On Thu, Jul 16, 2009 at 3:09 PM, David MacIver<david.maciver@...> wrote: >> >>> 2009/7/16 Kevin Wright <kev.lee.wright@...>: >>> >>>> for a given import: >>>> import foo.bar.baz >>>> >>>> I propose that foo and foo.bar not be considered for subsequent relative >>>> imports >>>> Neither package has been explicitly imported, and both were simply mentioned >>>> "in passing" as part of the fully-qualified path to the import of >>>> foo.bar.baz >>>> >>>> I'm happy of course to see further debate on this proposal and how it could >>>> be considered as adding a pile of special cases or breaking consistency. >>>> >>> You're right, of course. This doesn't add a pile of special cases or >>> break consistency because it's exactly how things already behave. >>> Importing foo.bar.baz doesn't import foo or bar. >>> >> This exchange goes a long way in illustrating the confusion here ... >> >> I think that most people coming to Scala from Java look at, >> >> package a.b.c >> >> import a.b.d.Foo // OK >> import b.Bar // OK too! Huh? How is b in scope >> >> and assume that it's the import which is in someway responsible for >> their surprise. >> >> But it's not, it's the package declaration at the top of the file >> which is responsible. Desugaring to, >> >> package a { >> package b { >> package c { >> >> import a.b.d.Foo // OK >> import b.Bar // OK too ... clearly b is in scope >> } >> } >> } >> >> makes the behaviour crystal clear. >> >> What's also crystal clear is that this is very different from Java, >> and that from an Java perspective it involves a surprising capture of >> (typically unrelated) scopes (as you observed earlier in this thread). >> >> I'm not at all sure what the right thing to do here is. It clearly is >> a problem, but on the other hand it is a useful feature. >> >> I like your proposal of only capturing the enclosing scopes if the >> desugared syntax is use and having the more common "package a.b.c" not >> cause the scope capture. But does that eliminate the usefulness of >> package nesting so much it might as well be dropped altogether? >> > > I don't think one can get rid of package nesting. My proposal was > purely about whether the definitions are considered to be nested or > just the result (i.e with package foo.bar, bar is still a member of > foo but foo is not in scope here) > > If you're going to allow declarations of the form > > package foo{ > package bar{ > > } > } > > then foo's contents really have to be in scope in bar. Scala has the > nice property that everything captures its defining scope, and it > would be a shame to throw it away. But package foo.bar; can be > regarded as having its defining scope being the top level, so not > bringing the parent packages into scope there is much less > problematic. > > |
|
|
Re: Nested package scopes vs. Imports (Was: Revisiting absolute/relative paths)2009/7/16 Erkki Lindpere <erkki@...>:
> This proposal makes a lot of sense. But it's going to add an exception to > indentation rules (whether mental or automatic in the future) because you > probably don't want to change indentation of a file depending on how much > nested levels of packages you have and it also means you have to change the > end of a file if you change the level of nesting. > I guess this is a really minor concern but it would be nice if there was a > minimal syntax for this that would only affect the first lines in a file. I > can't think of anything though. Something like import foo.bar._ perhaps? :-) |
|
|
|
|
|
Re: Nested package scopes vs. Imports (Was: Revisiting absolute/relative paths)That suggestion was my fault, and after learning more about the issue
I'd like to denounce it. David's solution seems much cleaner to me. Kris On Thu, Jul 16, 2009 at 9:24 AM, Alex Boisvert<boisvert@...> wrote: > May I recall a proposal that was made some time ago by I-dont-remember-whom? > > 1) Make all imports absolute by default > > import com.example._ // means "import _root_.com.example._" > > 2) Relative imports would be prefixed by "_" > > import _.util.StringUtils > > While not backward compatible, this proposal has the advantage of being very > friendly to Java developers (no surprises) and clarifies the intended scope > of the import. > > alex > |
|
|
Re: Nested package scopes vs. Imports (Was: Revisiting absolute/relative paths)2009/7/16 Erkki Lindpere <erkki@...>:
> Are we talking about > > package foo.bar > import foo._ > > as the equivalent of > package foo { > package bar { > } > } > ? Yes. > Might be good enough, although I'd prefer not to duplicate 'foo' (if it > might actually be longer). What about this (someone already propsed that I > think): > package `com.foo`.bar not thrilled with it to be honest. It's a fairly non-obvious meaning for it to have. How about the following: package foo package bar currently this is a compile error: You're not allowed more than one braceless package per file. It could instead be interpreted so that these nest, with the close braces happening right before EOF. i.e. package foo package bar class Kittens translates to package foo{ package bar{ class Kittens } } thus avoiding the braces as an incentive to nest. |
| < Prev | 1 - 2 - 3 | Next > |
| Free embeddable forum powered by Nabble | Forum Help |