--
For other discussions, see https://groups.google.com/a/dartlang.org/
For HOWTO questions, visit http://stackoverflow.com/tags/dart
To file a bug report or feature request, go to http://www.dartbug.com/new
To unsubscribe from this group and stop receiving emails from it, send an email to misc+uns...@dartlang.org.
With imports, you have two ways to make your library robust against changes in your dependencies:1. Always prefix (imports as) to avoid name collisions.2. Always use show to explicitly control what is imported.For exports, only the 2nd option makes sense. A prefix is internal to your library, and exporting under a prefix, even if it were possible, what not guarantee the absence of conflicts downstream.The simplest advice is to always use show. That also has the benefit that you can tell at a glance what your using. However, if you have a very large set of imported names, a prefix may be more convenient.In any event, tools such as the Dart Editor (or any IDE) should assist in this, much as they do in Java, where people have learned that wildcard imports should be avoided.
On Tue, Oct 22, 2013 at 4:53 PM, James deBoer <deb...@google.com> wrote:We have an open "to be discussed" issue in Angular.dart (#24) and would love the community's input:What is the best practice for avoiding symbol collisions when importing libraries? Especially collisions with core libraries.For example, dart:async defines a class Zone. So does Angular. This situation is not a problem in Angular, since we use "import dart:async as async". When we want to reference dart:async's Zone, we say "async.Zone".This is great -- we like this method internally. It is clear which Zone we are talking about. However, it has the potential to break Angular.dart customers:If you have an app that imports both Angular and dart:async, e.g.import "dart:async";import "package:angular/core/module.dart"The Dart compiler will complain that Zone is defined twice: once in dart:async and once in Angular.==> One solution is to import Angular "import package:angular/angular.dart as ng". Any references to Angular classes would need to be prefixed with "ng.". "import as" is viral, if a library uses it, the customers of the library are forced to use it as well.
--
Assuming that "as" is used only to avoid name collisions, I wonder if it should be allowed to use names that are not in collision directly without prefix even if its library has been imported with "as".
For instance let lib "l1" constains 2 classes (A and B) and lib "l2" constains 2 classes (A and C). There's a collision for A so at least one of the imports should specify "as" to resolve that :
import "package:l1/l1.dart";
import "package:l2/l.dart" as l2;main(){
A aFromL1;
l2.A aFromL2; // prefix is mandatory because of name collision
B b;C c; // I can use C directly because there's no name collision}In google_maps library I decided to use GMap instead of Map to avoid forcing users to use a prefix (because of Map in dart:core) and having that prefix everywhere in their code only for 1 name collision. With this new "as" behaviour only Map should be prefixed.
That way the code could be lighter.What do you think ?
On Tue, Oct 22, 2013 at 5:16 PM, Gilad Bracha <gbr...@google.com> wrote:
With imports, you have two ways to make your library robust against changes in your dependencies:1. Always prefix (imports as) to avoid name collisions.2. Always use show to explicitly control what is imported.For exports, only the 2nd option makes sense. A prefix is internal to your library, and exporting under a prefix, even if it were possible, what not guarantee the absence of conflicts downstream.The simplest advice is to always use show. That also has the benefit that you can tell at a glance what your using. However, if you have a very large set of imported names, a prefix may be more convenient.In any event, tools such as the Dart Editor (or any IDE) should assist in this, much as they do in Java, where people have learned that wildcard imports should be avoided.The beginnings of this have landed: https://code.google.com/p/dart/issues/detail?id=12012On Tue, Oct 22, 2013 at 4:53 PM, James deBoer <deb...@google.com> wrote:We have an open "to be discussed" issue in Angular.dart (#24) and would love the community's input:What is the best practice for avoiding symbol collisions when importing libraries? Especially collisions with core libraries.For example, dart:async defines a class Zone. So does Angular. This situation is not a problem in Angular, since we use "import dart:async as async". When we want to reference dart:async's Zone, we say "async.Zone".This is great -- we like this method internally. It is clear which Zone we are talking about. However, it has the potential to break Angular.dart customers:If you have an app that imports both Angular and dart:async, e.g.import "dart:async";import "package:angular/core/module.dart"The Dart compiler will complain that Zone is defined twice: once in dart:async and once in Angular.==> One solution is to import Angular "import package:angular/angular.dart as ng". Any references to Angular classes would need to be prefixed with "ng.". "import as" is viral, if a library uses it, the customers of the library are forced to use it as well.I don't understand this statement, how is "import as" viral?
Just tested and found how to minimizing using prefix when name conficts.
Works without "show" and "hide" combinators.
Can be assumed as "import as" best practices.
Let' look into.
future.dart
+++++++++++++++++++++++++
library future;
import 'dart:async';
import 'dart:async' as async;
import 'future.dart' as this_library; // prefix itseld
class Future2 {
Future2() {
print('called new Future2() on future.dart');
}
Future2.withOnwFuture(this_library.Future future) {
print('called Future2.withOnwFuture()');
// Simulate we need class from 'dart:async'
// It not conficts by name
// Using it from 'dart:async' w/o prefix
new Completer();
}
Future2.withAsyncFuture(async.Future future) {
// Here we using 'dart:async' Future class
// It conficts with own Future class
// We using it with prefix (see method parameter)
print('called Future2.withAsyncFuture()');
}
}
class Future {
Future() {
print('called new Future() on future.dart');
}
}
+++++++++++++++++++++++++
test.dart
import 'dart:async';
import 'dart:async' as async;
import 'future.dart';
import 'future.dart' as future;
void main() {
// use 'dart:async' with prefix
var f1 = new async.Future(() => 41);
// use 'future.dart' with prefix
var f2 = new future.Future();
// use 'dart:async' w/o prefix
var c = new Completer();
// use 'future.dart' w/o prefix
var a = new Future2();
// use 'future.dart' in both combinations
var a1 = new Future2.withOnwFuture(new future.Future());
var a2 = new Future2.withAsyncFuture(new async.Future(() => 41));
}
+++++++++++++++++++++++++
All works fine!
Using prefix are minimized only to where it reqired.
Are we really sure that this construction:import 'dart:async';
import 'dart:async' as async;
doesn't cause any problem?
You are introducing all symbols of dart:async duplicated (at least it worked like this some time ago). Thus, you have Future and async.Future which, to the compiler, are two totally different classes (even though you know they are the same).
For regular use cases this may work, but I'm not sure if mixing things from async.X and the raw dart:async will fail. For instance, say I have a lib named LIB, with classes A and B. Say A's constructor receives a B argument. And then I do:import "LIB";import "LIB" as L;new L.A( new B ); <--- this used to fail compilation (but I'm not sure whether it should or not and whether it fails as of latest version)
new L.A( new L.B ); <-- this should workIf the first failure must hold, imagine this scenario with lots of interrelated classes. You may end up with runtime problems because you are mixing classes. In some way this is similar to randomly mixing classloaders in Java.What do you think?
>> Are we really sure that this construction:import 'dart:async';
import 'dart:async' as async;
>> doesn't cause any problem?
It's not my problem. If something work wrong in Dart then I assume this is a problem of designers but not the my problem.
Or you think this prohibited by language specification?
import 'dart:async';
import 'dart:async' as async;
>> You are introducing all symbols of dart:async duplicated (at least it worked like this some time ago).
I think this can be called name isolation. If some names not used in some namespace then them must be assumed as not used.
I not looked how works optimizations in "mirrors" library. My be this is a problem, may be not a problem.
In all other cases this is not a problem.
P.S.
If the Dart compiler is an intellectual tool that for him the same name in different namespaces from the same library must be the same but not different.
Also duplicated means the same and can reduced.
What a problem?
What is the best practice for avoiding symbol collisions when importing libraries? Especially collisions with core libraries.For example, dart:async defines a class Zone. So does Angular. This situation is not a problem in Angular, since we use "import dart:async as async". When we want to reference dart:async's Zone, we say "async.Zone".