Nested package scopes vs. Imports (Was: Revisiting absolute/relative paths)

View: New views
20 Messages — Rating Filter:   Alert me  
< Prev | 1 - 2 - 3 | Next >

Nested package scopes vs. Imports (Was: Revisiting absolute/relative paths)

by Miles Sabin :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

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)

by Kevin Wright-4 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

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)

by Kevin Wright-4 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

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 :)


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)

by Martin Odersky :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

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)

by David MacIver :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

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)

by Miles Sabin :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

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)

by Martin Odersky :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

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)

by David MacIver :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

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)

by Miles Sabin :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

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)

by David MacIver :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

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)

by Alex Boisvert-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

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)

by Kevin Wright-4 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

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@...>:
> 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)

by David MacIver :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

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)

by Martin Odersky :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

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
>
That's what I would call fiddling with the scope rules. Here's the
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)

by Alex Boisvert-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

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:
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
>
That's what I would call fiddling with the scope rules. Here's the
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)

by Erkki Lindpere-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

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)

by David MacIver :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

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? :-)

Parent Message unknown Re: Nested package scopes vs. Imports (Was: Revisiting absolute/relative paths)

by Erkki Lindpere-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Are we talking about

package foo.bar
import foo._

as the equivalent of
package foo {
 package bar {
 }
}
?

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

David MacIver wrote:

> 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)

by nuttycom :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

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)

by David MacIver :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

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 >