packages and objects with the same name

573 views
Skip to first unread message

Dominik

unread,
Jun 26, 2012, 8:21:52 AM6/26/12
to scala-l...@googlegroups.com
Can someone explain me the following difference?

When I define within a package a sub-package and an object with the same name, then the compiler complains:

package p {
  package base {
    class X
  }
  object base {
    class X
  }
}

Test.scala:5: error: base is already defined as package base
  object base {
         ^

However, If I define a top-level package and a top-level object with the same name, then the compiler silently accepts that.

object p {
  class X
}

package p {
  class X
}


Where is this behavior defined in the SLS?

Btw, I do not see the advantage to prohibit the definition of objects and packages with the same name as at run time classes and packages with the same name may be found on the class path anyway.

Dominik


Som Snytt

unread,
Jun 26, 2012, 3:44:34 PM6/26/12
to scala-l...@googlegroups.com
The top-level object is actually in the default package, per 9.2.

I just had a similar experience.  Running partest --pos failed on a test because neighboring test t3999b defines object `package` in the default package.  It's not an edge case, in that it's quite regular, but it's a bit confusing.

I haven't got back to look closely, but my t5120-pos.log is
error: error while loading package, class file 'M:\apm\projects\scala\test\files\pos\t3999b-pos.obj\package.class' has location not matching its contents: contains package package

Apparently partest puts files/pos on the classpath.

$ partest ./files/pos/t3999b.scala ./files/pos/t5120.scala  # OK
$ partest ./files/pos/t5120.scala   # [FAILED]

Paul Phillips

unread,
Jun 26, 2012, 8:39:21 PM6/26/12
to scala-l...@googlegroups.com
On Tue, Jun 26, 2012 at 5:21 AM, Dominik <dominik...@fhnw.ch> wrote:
Btw, I do not see the advantage to prohibit the definition of objects and packages with the same name as at run time classes and packages with the same name may be found on the class path anyway.

Classes and packages are in different namespaces.  Objects and packages are in the same namespace.  Being in the same namespace is a pretty good reason to prohibit it.  I'm not sure why classes and packages with the same name are prohibited (in fact I didn't notice they were until just now.) It doesn't complain until you put something in the package.

Dave

unread,
Jun 27, 2012, 7:25:39 AM6/27/12
to scala-language
I think it is in the SLS 9.2.

"Selections p.m from p as well as imports from p work as for objects.
However, unlike
other objects, packages may not be used as values. It is illegal to
have a package with
the same fully qualified name as a module or a class.

Top-level definitions outside a packaging are assumed to be injected
into a special
empty package. That package cannot be named and therefore cannot be
imported.
However, members of the empty package are visible to each other
without qualification."

package p {
package base {

}
object base {

}
}

Fully qualified names are both _root_.p.base so it is already
ambiguous. There is no way to do an import without ambiguity.



package base {

}
object base {

}

IIUC: Fully qualified name are also both _root_.base.
but the object base is automatically imported and in scope and the
package base not.
base nad import base._ refers to object base
If you do try to import with the fully qualified name _root_.base then
the import is ambiguous.

object base {
class X { println("class X in object base") }
}

package base {
class X { println("class X in package base") }
}

object Main extends App {
import base._ // doesn't matter
new base.X
}

C:\scala-2.10.0-M4\myexamples2>scalac namingclash.scala

C:\scala-2.10.0-M4\myexamples2>scala Main
class X in object base



object base {
class X { println("class X in object base") }
}

package base {
class X { println("class X in package base") }
}

object Main extends App {
import _root_.base._
new base.X // ambiguity
}

C:\scala-2.10.0-M4\myexamples2>scalac namingclash.scala
namingclash.scala:38: error: reference to base is ambiguous;
it is both defined in package <empty> and imported subsequently by
import _root_.base._
new base.X // ambiguity
^
one error found

Dominik

unread,
Jun 28, 2012, 7:53:48 PM6/28/12
to scala-l...@googlegroups.com
Hi Dave,
thank you very much for this explanation. Now it seems to be clear to me.

The top-level definitions are defined in an empty package _root_.<empty>,
which however can neither be named nor imported, but the members are
visible similar to an (explicit or wildcard) import declaration.

Let us look again at the example:


  object base {
    class X { println("class X in object base") }
  }

  package base {
    class X { println("class X in package base") }
  }

  object Main extends App {
    import base._
    // this imports class X from the object as object base (from package <empty>) is implicitly available here.

    new base.X   
    // this creates an instance of class X in object base.
   
    new _root_.base.X
    // this demonstrates, that the object base is not in the root package as this reference is NOT ambiguous
 
    import _root_.base._ 
    // this simply imports X (now from the package), but after that import the reference X is ambiguous.

    new base.X
    // this reference is not ambiguous, is still refers to class X in object base.
    // I do not get a compiler error here, neither with 2.9 nor with 2.10M4.

  }

- Dominik

Reply all
Reply to author
Forward
0 new messages