This page is no longer maintained — Please continue to the home page at www.scala-lang.org

Revisiting absolute/relative paths

16 replies
Jorge Ortiz
Joined: 2008-12-16,
User offline. Last seen 29 weeks 4 days ago.
Hi all,

This came up on Twitter today, so I thought I'd re-beat a not-yet-dead horse.

Anyone with a non-trivial Scala code base and a non-trivial number of external dependencies has been bitten by Scala's relative paths.

In Lift's case, this happened when one of our dependencies (Specs) added a dependency (Textile-J) which lived in the "net.java" package. Adding this dependency meant code like the following:

  package net.liftweb
  import java.io.File

  ...

Would fail with:

  error: value io is not a member of package net.java

This was incredibly frustrating because we didn't cause the problem, there was no way to foresee it, and it affected pretty much every single Lift source file. To fix the problem, and preempt future problems of this kind, we _root_.ed every single statement which used an absolute path, including most imports. (The patches aren't pretty. Exhibit A: http://paste.pocoo.org/show/128668/, Exhibit B: http://paste.pocoo.org/show/128662/)

I made a stink about it on the mailing list at the time. The consensus was that it was a problem, and the most popular solution was to allow absolute imports of the form "import .java.io.File" (leading dot), in addition to the current form "import _root_.java.io.File". The leading dot is much more pleasing to the eye than the hideous _root_, but I think this approach is inadequate for the following reasons:

1) It only works well for import statements, but not for other statements that might require absolute paths. Consider the following code:

  val x = foo()
  .bar.baz()

Right now this parses as: val x = foo().bar.baz(). I've used this syntax extensively to break of long chains of method calls, like:

  list
    .map(...)
    .filter(...)
    .drop(...) etc

(I've used this syntax in the past. Now I prefer to wrap such statements in parentheses.)

If leading dots meant absolute paths for all statements, it would parse as: vall x = foo(); _root_.bar.baz();

This presents a dilemma between breaking non-trivial amounts of existing code and disallowing leading-dot absolute paths for non-import statements.

2) It still requires touching every source file. The above-linked patches would be slightly less hideous (with a . instead of a _root_.), but they'd be no less huge. Consistently maintaining this standard across a large codebase is painful, and the risks of ignoring rooted absolute paths are real. (As Lift saw, even a second-degree dependency can break large swaths of your code.)

Those are the reasons why I think the leading-dot proposal is inadequate. (That said, I still think it'd be an improvement over the current situation. At this point I'll take what I can get.) I'm interested in solutions that 1) work for both import and non-import statements, and 2) don't require touching every source file. I'd love to hear any proposals that address these two criteria. I'd like to outline one such proposal below.

Proposal:

All exisitng code has unchanged semantics.

For new code, suppose there is some new syntax to mark a package object as rooted. (This is NOT the proposed syntax. I deliberately don't want to propose any particular syntax.)

  ROOT package object net.liftweb { ... }

Now any code inside the "net.liftweb" package, compiled with the "net.liftweb" package object in the classpath, can only use relative paths for things also inside "net.liftweb". Stuff in, say, "net.java" would require an absolute path. Now the code:

  package net.liftweb
  import java.io.File

Does not give a compile error, because "java." refers to "_root_.java." rather than "_root_.net.java.". If there were a "java" package inside "net.liftweb" this would still be a problem, but that's within Lift's control rather than an artifact of including a dependency.

This works for both import and non-import statements, and avoids having to touch and maintain large numbers of source files. It still means Lift has to be careful about not using packages called "java", "scala", "com", "net", "org", etc., but that's much more manageable than having to _root_ every absolute path.

Thoughts?

--j
DRMacIver
Joined: 2008-09-02,
User offline. Last seen 42 years 45 weeks ago.
Re: Revisiting absolute/relative paths

2009/7/15 Jorge Ortiz :
> Hi all,
>
> This came up on Twitter today, so I thought I'd re-beat a not-yet-dead
> horse.
>
> Anyone with a non-trivial Scala code base and a non-trivial number of
> external dependencies has been bitten by Scala's relative paths.

I don't believe this claim is true. At least not for interesting
values of "bitten". I've never had to spend more than about 5 minutes
at a time fixing issues caused by this, which puts it well under my
radar for significant problems. What you're describing is nearly the
single case where problems caused by this are actually non-trivial to
work around. Everything else can be dealt with by changing an import
or two.

I'd like to propose an alternative solution for this case: Don't use
the Java reverse domain name convention for packages. It's ugly and
useless in the first place, but it's also actively harmful in Scala
because it allows other people to accidentally insert packages into
your namespace like this. Rename net.liftweb to liftweb and your
problem essentially goes away because anyone putting a package into
liftweb is really likely to mean it (and if they don't there are
probably going to be even more clashes).

Admittedly this sort of rename is quite painful for end users because
all their imports get renamed. But conveniently this doesn't actually
affect people too much if they've made sensible use of relative
imports because they only imported net.liftweb once per file. :-)
Also, package objects might allow you to work around it if you can
define package aliases in them.

Jorge Ortiz
Joined: 2008-12-16,
User offline. Last seen 29 weeks 4 days ago.
Re: Revisiting absolute/relative paths
Your alternative is compelling, but it'd be a shame to have to insist on better package names, not because they're better, but because Scala is broken.

In any case, this alternative is not an option for Lift, at least for the foreseeable (backwards-compatible) future.

Given how prevalent this package naming convention is in Java-land, I'd love to hear from other people who've had problems with relative imports. Is not using Java's package naming convention an option?

--j

On Wed, Jul 15, 2009 at 1:14 AM, David MacIver <david [dot] maciver [at] gmail [dot] com> wrote:
2009/7/15 Jorge Ortiz <jorge [dot] ortiz [at] gmail [dot] com>:
> Hi all,
>
> This came up on Twitter today, so I thought I'd re-beat a not-yet-dead
> horse.
>
> Anyone with a non-trivial Scala code base and a non-trivial number of
> external dependencies has been bitten by Scala's relative paths.

I don't believe this claim is true. At least not for interesting
values of "bitten". I've never had to spend more than about 5 minutes
at a time fixing issues caused by this, which puts it well under my
radar for significant problems. What you're describing is nearly the
single case where problems caused by this are actually non-trivial to
work around. Everything else can be dealt with by changing an import
or two.

I'd like to propose an alternative solution for this case: Don't use
the Java reverse domain name convention for packages. It's ugly and
useless in the first place, but it's also actively harmful in Scala
because it allows other people to accidentally insert packages into
your namespace like this. Rename net.liftweb to liftweb and your
problem essentially goes away because anyone putting a package into
liftweb is really likely to mean it (and if they don't there are
probably going to be even more clashes).

Admittedly this sort of rename is quite painful for end users because
all their imports get renamed. But conveniently this doesn't actually
affect people too much if they've made sensible use of relative
imports because they only imported net.liftweb once per file. :-)
Also, package objects might allow you to work around it if you can
define package aliases in them.
DRMacIver
Joined: 2008-09-02,
User offline. Last seen 42 years 45 weeks ago.
Re: Revisiting absolute/relative paths

2009/7/15 Jorge Ortiz :
> Your alternative is compelling, but it'd be a shame to have to insist on
> better package names, not because they're better, but because Scala is
> broken.

I disagree. It would be a shame to have to insist on dramatically
complicating or breaking entirely a working feature of Scala because
people are using a broken package naming convention.

People fixate on the issues with relative package imports because
they're unusual, but it's easy to forget the benefits when you're
doing so and they are many. You could retain some of them by saying in
various places "and this is how imports work in Scala UNLESS YOU'RE
IMPORTING A PACKAGE IN WHICH CASE IT DOES SOMETHING COMPLETELY
DIFFERENT", but you'd lose utility and gain surprising behaviour.

> In any case, this alternative is not an option for Lift, at least for the
> foreseeable (backwards-compatible) future.

Like I said in the comment about package objects, one may be able to
fix that problem. If you can do something like

package object net {
val liftweb = _root_.liftweb
}

then imports to liftweb remain source compatible. I don't know if this
works, but it sure would be nice if it did. :-)

> Given how prevalent this package naming convention is in Java-land, I'd love
> to hear from other people who've had problems with relative imports.

Ultimately, Scala is going to have to grow up and develop its own
conventions in places. Clearly any conventions it arrives at are going
to be heavily Java inspired, but we need to figure out the cases where
Scala needs a different convention, or where a different convention
would be beneficial. This is very distinctly one of them in my
opinion.

> Is not
> using Java's package naming convention an option?

Even if it's not an option for old code, I would very strongly
recommend it as the default for new.

milessabin
Joined: 2008-08-11,
User offline. Last seen 33 weeks 3 days ago.
Re: Revisiting absolute/relative paths

On Wed, Jul 15, 2009 at 9:44 AM, David MacIver wrote:
> I disagree. It would be a shame to have to insist on dramatically
> complicating or breaking entirely a working feature of Scala because
> people are using a broken package naming convention.

That's a very tendentious claim ;-)

In what way is the reverse domain name convention more broken than the
alternatives?

Cheers,

Miles

Ricky Clarkson
Joined: 2008-12-19,
User offline. Last seen 3 years 2 weeks ago.
Re: Revisiting absolute/relative paths

Just to record my suggestion from the discussion in #scala:

import x._ should behave as it does today, importing everything from
the nearest thing called x.
import x.y should look in the nearest x for a member called y and
import that. If it's not there, look in the next nearest x,
recursively.

Jorge said:

"It's problematic because adding classes ANYWHERE in your package
hierarchy might break some code in non-obvious ways. It's too brittle
to rely on."

I agree, but think it is much less likely to be a problem than the
current situation. Also, my suggestion does not break any existing
code and requires no changes to existing code to be useful.

2009/7/15 Jorge Ortiz :
> Hi all,
>
> This came up on Twitter today, so I thought I'd re-beat a not-yet-dead
> horse.
>
> Anyone with a non-trivial Scala code base and a non-trivial number of
> external dependencies has been bitten by Scala's relative paths.
>
> In Lift's case, this happened when one of our dependencies (Specs) added a
> dependency (Textile-J) which lived in the "net.java" package. Adding this
> dependency meant code like the following:
>
>   package net.liftweb
>   import java.io.File
>
>   ...
>
> Would fail with:
>
>   error: value io is not a member of package net.java
>
> This was incredibly frustrating because we didn't cause the problem, there
> was no way to foresee it, and it affected pretty much every single Lift
> source file. To fix the problem, and preempt future problems of this kind,
> we _root_.ed every single statement which used an absolute path, including
> most imports. (The patches aren't pretty. Exhibit A:
> http://paste.pocoo.org/show/128668/, Exhibit B:
> http://paste.pocoo.org/show/128662/)
>
> I made a stink about it on the mailing list at the time. The consensus was
> that it was a problem, and the most popular solution was to allow absolute
> imports of the form "import .java.io.File" (leading dot), in addition to the
> current form "import _root_.java.io.File". The leading dot is much more
> pleasing to the eye than the hideous _root_, but I think this approach is
> inadequate for the following reasons:
>
> 1) It only works well for import statements, but not for other statements
> that might require absolute paths. Consider the following code:
>
>   val x = foo()
>   .bar.baz()
>
> Right now this parses as: val x = foo().bar.baz(). I've used this syntax
> extensively to break of long chains of method calls, like:
>
>   list
>     .map(...)
>     .filter(...)
>     .drop(...) etc
>
> (I've used this syntax in the past. Now I prefer to wrap such statements in
> parentheses.)
>
> If leading dots meant absolute paths for all statements, it would parse as:
> vall x = foo(); _root_.bar.baz();
>
> This presents a dilemma between breaking non-trivial amounts of existing
> code and disallowing leading-dot absolute paths for non-import statements.
>
> 2) It still requires touching every source file. The above-linked patches
> would be slightly less hideous (with a . instead of a _root_.), but they'd
> be no less huge. Consistently maintaining this standard across a large
> codebase is painful, and the risks of ignoring rooted absolute paths are
> real. (As Lift saw, even a second-degree dependency can break large swaths
> of your code.)
>
> Those are the reasons why I think the leading-dot proposal is inadequate.
> (That said, I still think it'd be an improvement over the current situation.
> At this point I'll take what I can get.) I'm interested in solutions that 1)
> work for both import and non-import statements, and 2) don't require
> touching every source file. I'd love to hear any proposals that address
> these two criteria. I'd like to outline one such proposal below.
>
> Proposal:
>
> All exisitng code has unchanged semantics.
>
> For new code, suppose there is some new syntax to mark a package object as
> rooted. (This is NOT the proposed syntax. I deliberately don't want to
> propose any particular syntax.)
>
>   ROOT package object net.liftweb { ... }
>
> Now any code inside the "net.liftweb" package, compiled with the
> "net.liftweb" package object in the classpath, can only use relative paths
> for things also inside "net.liftweb". Stuff in, say, "net.java" would
> require an absolute path. Now the code:
>
>   package net.liftweb
>   import java.io.File
>
> Does not give a compile error, because "java." refers to "_root_.java."
> rather than "_root_.net.java.". If there were a "java" package inside
> "net.liftweb" this would still be a problem, but that's within Lift's
> control rather than an artifact of including a dependency.
>
> This works for both import and non-import statements, and avoids having to
> touch and maintain large numbers of source files. It still means Lift has to
> be careful about not using packages called "java", "scala", "com", "net",
> "org", etc., but that's much more manageable than having to _root_ every
> absolute path.
>
> Thoughts?
>
> --j
>

Johannes Rudolph
Joined: 2008-12-17,
User offline. Last seen 29 weeks 20 hours ago.
Re: Revisiting absolute/relative paths

On Wed, Jul 15, 2009 at 1:08 PM, Miles Sabin wrote:
> On Wed, Jul 15, 2009 at 9:44 AM, David MacIver wrote:
>> I disagree. It would be a shame to have to insist on dramatically
>> complicating or breaking entirely a working feature of Scala because
>> people are using a broken package naming convention.
>
> That's a very tendentious claim ;-)
>
> In what way is the reverse domain name convention more broken than the
> alternatives?
In Scala it is quantitatively more broken because using TLDs as first
part of the package name is much more probable to produce collisions
than anything longer than 3 characters. Qualitatively because there is
no obvious reason why a package has to belong to a DNS address or this
aside, why packages have to be grouped by country.

Reverse domain names make sense in the moment you actually e.g. use
DNS to check signatures against certificates published through DNS.

DRMacIver
Joined: 2008-09-02,
User offline. Last seen 42 years 45 weeks ago.
Re: Revisiting absolute/relative paths

2009/7/15 Miles Sabin :
> On Wed, Jul 15, 2009 at 9:44 AM, David MacIver wrote:
>> I disagree. It would be a shame to have to insist on dramatically
>> complicating or breaking entirely a working feature of Scala because
>> people are using a broken package naming convention.
>
> That's a very tendentious claim ;-)

that's a very requiringmetolookitupinthedictionary word. ;-)

>
> In what way is the reverse domain name convention more broken than the
> alternatives?

In exactly the way I said above: It makes it far too easy for other
people to accidentally inject packages into your namespace.

milessabin
Joined: 2008-08-11,
User offline. Last seen 33 weeks 3 days ago.
Re: Revisiting absolute/relative paths

On Wed, Jul 15, 2009 at 12:18 PM, David MacIver wrote:
>> In what way is the reverse domain name convention more broken than the
>> alternatives?
>
> In exactly the way I said above: It makes it far too easy for other
> people to accidentally inject packages into your namespace.

No, it's the _combination_ of the reverse domain name conventions and
relative package names which is responsible for that.

Given that the reverse domain name convention has to stay for Java
compatibility, I'd rather see the relative import rules tweaked.

Cheers,

Miles

Florian Hars
Joined: 2008-12-18,
User offline. Last seen 42 years 45 weeks ago.
Re: Revisiting absolute/relative paths

Johannes Rudolph schrieb:
> Qualitatively because there is no obvious reason why a package has to
> belong to a DNS address

Uniqueness. You can name your classes any way you want without any fear
of name clashes if your package name corresponds to a (sub)domain you
control. Things like org.specs._ are inexcusable, though.

- Florian.

DRMacIver
Joined: 2008-09-02,
User offline. Last seen 42 years 45 weeks ago.
Re: Revisiting absolute/relative paths

As a side note (brought here from my pondering the same on IRC),
here's another possibly way this problem could be resolved:

The problem isn't actually about relative imports at all. It's about
namespace pollution from parents.

Conceptually, a Scala package declaration

package net.liftweb.stuff{
// stuff goes here
}

is equivalent to

package net {
package liftweb {
package stuff{
// stuff goes here
}
}
}

then, because everything in Scala inherits its defining scope, stuff
pulls everything out from net and thus acquires the problematic java.

If, instead, this was interpreted as something like the following
(obviously from a Java interop point of view this isn't what would
actually happen. I'm thinking purely in terms of semantics of what's
in scope, not what the real fully qualified class name would be):

package some_mangling_of_net_liftweb_stuff{
// stuff goes here
}

package net{
package liftweb{
package stuff = some_mangling_of_net_liftweb_stuff // not legal syntax
}
}

Some tinkering is needed to make this actually work sensibly, but the
basic idea is that without *explicit* nesting on the part of the user
you don't inherit the members of your parent packages at the
defintiion site.

I don't have a particularly strong opinion about this idea, largely
because I don't find this problem troublesome. It makes your imports
have to be a bit more explicit than they currently are, but maybe
that's not a bad thing.

Erkki Lindpere
Joined: 2008-12-19,
User offline. Last seen 42 years 45 weeks ago.
Re: Revisiting absolute/relative paths

For what it's worth, I kind of agree with this. This works for Java
because 'net.sf.hibernate' is treated as one identifier, and
'net.sf.hibernate.stuff' is a completely separate single identifier,
which just happens to share part of the name.

In Scala, if we have
net {
sf { hibernate { stuff } }
mycompany { myproject { mystuff} }
}

I really don't think this is conceptually right. Why should the packages
both be considered to be children of the 'net' package simply because
they happen to have the same TLD? And then hibernate moving to an .org
domain suddenly changes that relationship, as if it should somehow have
relevance in code.

Erkki

David MacIver wrote:
> I'd like to propose an alternative solution for this case: Don't use
> the Java reverse domain name convention for packages. It's ugly and
> useless in the first place, but it's also actively harmful in Scala
> because it allows other people to accidentally insert packages into
> your namespace like this.

Steve Jenson
Joined: 2009-07-16,
User offline. Last seen 42 years 45 weeks ago.
Re: Revisiting absolute/relative paths

On Tue, Jul 14, 2009 at 11:38 PM, Jorge Ortiz wrote:
> Hi all,
>
> This came up on Twitter today, so I thought I'd re-beat a not-yet-dead
> horse.
>
> Anyone with a non-trivial Scala code base and a non-trivial number of
> external dependencies has been bitten by Scala's relative paths.
>
> In Lift's case, this happened when one of our dependencies (Specs) added a
> dependency (Textile-J) which lived in the "net.java" package. Adding this
> dependency meant code like the following:
>
>   package net.liftweb
>   import java.io.File
>
>   ...
>
> Would fail with:
>
>   error: value io is not a member of package net.java

Isn't this strictly a problem with the package resolver exiting too
early? Since it wasn't found in net.java, it should have continued
until it found the package java.io. Seems like a bug unless I'm
misunderstanding some fundamental issue.

Steve

DRMacIver
Joined: 2008-09-02,
User offline. Last seen 42 years 45 weeks ago.
Re: Revisiting absolute/relative paths

2009/7/16 Steve Jenson :
> On Tue, Jul 14, 2009 at 11:38 PM, Jorge Ortiz wrote:
>> Hi all,
>>
>> This came up on Twitter today, so I thought I'd re-beat a not-yet-dead
>> horse.
>>
>> Anyone with a non-trivial Scala code base and a non-trivial number of
>> external dependencies has been bitten by Scala's relative paths.
>>
>> In Lift's case, this happened when one of our dependencies (Specs) added a
>> dependency (Textile-J) which lived in the "net.java" package. Adding this
>> dependency meant code like the following:
>>
>>   package net.liftweb
>>   import java.io.File
>>
>>   ...
>>
>> Would fail with:
>>
>>   error: value io is not a member of package net.java
>
> Isn't this strictly a problem with the package resolver exiting too
> early? Since it wasn't found in net.java, it should have continued
> until it found the package java.io. Seems like a bug unless I'm
> misunderstanding some fundamental issue.

You are. There is no such thing as a "package resolver". Root level
package names are always in scope. Things can be imported from stable
identifiers which are in scope. That is all that happens. When you
shadow a package name, shadowing happens exactly as normal for any
other identifer, and import java.stuff imports from the java
identifier in scope, not any java identifier it can somehow get its
hands on.

robey
Joined: 2008-12-24,
User offline. Last seen 1 year 21 weeks ago.
Re: Revisiting absolute/relative paths
On 14 Jul 2009, at 23:38, Jorge Ortiz wrote:
Hi all,

This came up on Twitter today, so I thought I'd re-beat a not-yet-dead horse.

Anyone with a non-trivial Scala code base and a non-trivial number of external dependencies has been bitten by Scala's relative paths.

I missed most of this because I was too busy too keep up with the thread, but I've just now skimmed most of it.

This is partially my fault because I ran into the bug on one of my projects earlier in the week, and [unwisely] checked IRC to see if anyone had any advice. I should've known better. :) I ran into it again on a different project today, so I think this is starting to become more common.

There are two reasons I think it should be fixed, which I don't think have been adequately expressed here:

1. A change in someone else's package -- even one you don't import, but which is pulled into your classpath by maven -- can require you to edit every file and add a "_root_" wart to every import.

2. The principle of least astonishment: As Steve Jenson puts it, the person doing the strange thing should be the one required to do extra work, not the one doing the common behavior.

That said, I don't think the syntax of relative or absolute imports needs to be changed. It's the resolution of package names that's causing the confusion: it appears to look for relative paths first, then absolute, and if it finds even a partial package-name match, it stops looking, even if the class or nested package isn't found.

My problem (and I bet most people's) could be solved by:
1. Looking for absolute package name matches first.
2. In the relative case, continuing to traverse up the package tree if a match fails.

I don't think it's particularly magickal. If I get some free time soon, I can try to dig into the scalac source and submit a patch.

robey
sadie
Joined: 2008-12-21,
User offline. Last seen 42 years 45 weeks ago.
Import selectors (Was: Revisiting absolute/relative paths)

I may regret wading into such a... *ahem* lively discussion, but it seems
there's a perspective that's been missed. The original post was a problem
was caused by a change in the dependency:

Jorge Ortiz-3 wrote:
>
> In Lift's case, this happened when one of our dependencies (Specs) added a
> dependency (Textile-J) which lived in the "net.java" package. Adding this
> dependency meant code like the following:
>
> package net.liftweb
> import java.io.File
>
> ...
>
> Would fail with:
>
> error: value io is not a member of package net.java
>

I think the real problem with the above is that the compiler and a human
being mean different things when they read the line. When I see the
identifier "java.io.File", I know perfectly well what the line is supposed
to do - even while understanding why it doesn't do it any more. I know that
the "java" package must refer to "_root_.java" rather than "net.java",
because of what it contains. But the compiler doesn't see this: it resolves
the identifier java to the most immediately accessible java package, then
fails to find the "io" package within it.

Others have proposed that the root package be disambiguated by making them
single identifiers: _root_.liftweb., ., etc. While such
solutions may technically work, I think the approach incorrect. The problem
is not that the packages themselves are wrong, but that the compiler isn't
able to find the one being referred to.

Now my proposed solution. It may be a result of having written too much
jQuery recently, but to me the import statement looks less like a sequence
of hard identifiers, and more like a selector. What I propose is that the
compiler allow the precise meaning of an import statement to remain
ambiguous until such point as it must be resolved. That probably sounds
hand-wavey, so here's a more precise version.

import java.io.File

The first identifer, "java", is ambiguous. In the established import space
there are at least two different "java" packages to which it could refer. At
this point, I propose the compiler does not select the best one, but keeps a
list of them all sorted by preference.

The second identifier, "io", is less ambiguous. Maybe only one of the list
of possible "java" packages contains a child called "io", so at this point
the list is whittled down to one member.

The third identifier, "File", is concrete. This forces the list to
disambiguate, selecting the single most likely match. It knows that it
should disambiguate here because it's the end of the line, and because the
most closely matched item is a class.

I think this would solve liftweb's problem, and many similar problems people
are bound to face with Scala's relative imports in the future, by making the
meaning of the code match more closely with what's going on in the
programmer's head. And it needs absolutely no change to the syntax of the
code.

odersky
Joined: 2008-07-29,
User offline. Last seen 45 weeks 6 days ago.
Re: Import selectors (Was: Revisiting absolute/relative paths)

On Wed, Jul 22, 2009 at 2:04 PM, Marcus Downing wrote:
>
> I may regret wading into such a... *ahem* lively discussion, but it seems
> there's a perspective that's been missed. The original post was a problem
> was caused by a change in the dependency:
>
>
> Jorge Ortiz-3 wrote:
>>
>> In Lift's case, this happened when one of our dependencies (Specs) added a
>> dependency (Textile-J) which lived in the "net.java" package. Adding this
>> dependency meant code like the following:
>>
>>   package net.liftweb
>>   import java.io.File
>>
>>   ...
>>
>> Would fail with:
>>
>>   error: value io is not a member of package net.java
>>
>
> I think the real problem with the above is that the compiler and a human
> being mean different things when they read the line. When I see the
> identifier "java.io.File", I know perfectly well what the line is supposed
> to do - even while understanding why it doesn't do it any more. I know that
> the "java" package must refer to "_root_.java" rather than "net.java",
> because of what it contains. But the compiler doesn't see this: it resolves
> the identifier java to the most immediately accessible java package, then
> fails to find the "io" package within it.
>
You might think that, but in fact I believe it's large convention. I
learned recently that C# and more generally all .NET languages have
exactly Scala's old behavior. So they would not have the same
expectations. But for Java programmers it's different, and that's why
we are going to change.

Cheers

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland