Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are nested/unnested packages in Scala 2.8?

Tags:

In Scala 2.7, I could write:

package com.acme.bar

class Bar

.

package com.acme.foo

class Foo {
  new bar.Bar
}

This doesn't compile in Scala 2.8 -- however this does:

package com.acme 
package bar

class Bar

.

package com.acme
package foo

class Foo {
  new bar.Bar
}
  1. What was the motivation for this?
  2. What is the precise meaning, with regards to scope and visibility?
  3. When should I use one form over the other?
like image 774
retronym Avatar asked May 13 '10 20:05

retronym


People also ask

What are different packages in Scala?

Package in Scala is a mechanism to encapsulate a group of classes, sub packages, traits and package objects. It basically provides namespace to put our code in a different files and directories. Packages is a easy way to maintain our code which prevents naming conflicts of members of different packages.

Can we have nested packages?

Since all packages are global in scope, nesting of packages is not supported. However, you can have two packages, one called A and another called A::B , to give an illusion of nesting.


2 Answers

There were several long discussions on the mailing lists about this. See this thread for the problem and this thread for the solution.

As to meaning, only the

package A
package B

form will open a scope for A, which makes members of A visible without prefix. You'd typically use this form if your project consists of several subpackages which refer to each other. On the other hand, you'd use the form

package A.B.C

If you want to integrate C into the package hierarchy and do not intend to access other members of A or B directly. A typical case is

package net.myorg.myproject

Here, you do not want to be vulnerable to the possibility than somebody else has defined a net.java package that would shadow the root level java. In Scala 2.7 you'd prevent that by using _root_ imports. But that's ugly, and to be safe you'd have to do this almost everywhere. So the present solution is much better, IMO.

like image 194
Martin Odersky Avatar answered Sep 21 '22 15:09

Martin Odersky


Thanks for the answers so far! Let me add two small points, and we're done!

Visibility

The difference between nested and unnested packages only applies to scoping. Visibility is always based on nested packages.

package A

private[A] trait Secret

This works:

package A
package B

trait AB extends Secret

So does this:

package A.B

trait AB extends A.Secret

In both cases, the structure is interpreted as:

package A {
  trait Secret
  package B {
     //...
  }
}

Scoping

Compare this with scoping, in which you could imagine this interpretation for unnested packages:

package A {
  private [A] trait Secret
}

package `A.B` {
   trait AB extends A.Secret

}

Mix and Match

You can arbitrarily mix and match nested and unnested package:

package com.acme.project
package util.shazam
package blerg
like image 26
retronym Avatar answered Sep 20 '22 15:09

retronym