Can "package:" replace "dart:" ?

35 views
Skip to first unread message

Sean Eagan

unread,
May 17, 2012, 4:24:23 PM5/17/12
to General Dart Discussion
I'm wondering if "dart:" will still be needed once "package:" / pub
is fully implemented. Couldn't "package:html" be used instead of
"dart:html" for example, and pub (or any other package manager) could
just ignore package imports for which there is no local package
installed, assuming it corresponds to a builtin package, such as
"html". One pain is that "package" is a bit longer than "dart".
Possibly when importing plain identifiers, i.e. no uri scheme such as
"http:" is provided, then treat it as a package identifier:

#import("html");
#import("http://github.com/foo/bar");

Sean Eagan

Sean Eagan

unread,
May 17, 2012, 5:19:10 PM5/17/12
to General Dart Discussion
I forgot to mention the main reason that this could be useful which is
to mock out builtin libraries.

Also, realized that plain identifiers are already treated as relative
URIs, thus "package:" (or similar) is necessary after all.

Also, I don't think it is currently allowed to import a "package:" URI
without a "/foo.dart" suffix. Maybe:

#import('package:foo');

could be short for:

#import('package:foo/foo.dart');

also allowing for e.g.:

#import('package:html');

Sean

Matthew Butler

unread,
May 18, 2012, 8:53:04 AM5/18/12
to mi...@dartlang.org
Personally I like the 'dart:html' or 'dart:io' or what not as an identifier that they are part of the standard dart libraries as opposed to being packages someone else has written which happen to over-ride or mask the standard ones. I'd like to see standard dart library kept distinct from 3rd party packages. Also think it can help avoid someone creating intentional package clashes with the standard library.

Matt

Bob Nystrom

unread,
May 18, 2012, 1:10:59 PM5/18/12
to Sean Eagan, General Dart Discussion
On Thu, May 17, 2012 at 1:24 PM, Sean Eagan <seane...@gmail.com> wrote:
I'm wondering if "dart:" will still be needed  once "package:" / pub
is fully implemented.  Couldn't "package:html" be used instead of
"dart:html" for example, and pub (or any other package manager) could
just ignore package imports for which there is no local package
installed, assuming it corresponds to a builtin package, such as
"html".

This is a great question. Like all great questions, it doesn't have a neat simple answer. :)

The answer is sort of "yes" in that we have things that are "dart:" libraries now that don't need to be. They are implemented in pure Dart code and are just regular libraries. The reason they use "dart:" is (as far as I know) mostly to make them easier to import. Once pub is farther along, we shouldn't need to use "dart:" as a crutch here. I'm thinking things like "dart:utf" and "dart:uri". Those could just be regular patches.

One pain is that "package" is a bit longer than "dart".

There's a lot of pain with the current import syntax. When you see:

#import('package:foo/foo.dart');

You've got 32 characters of text, and only like 9 that actually mean something useful ("import" and "foo"). I really hope we can iterate on this at some point.

Possibly when importing plain identifiers, i.e. no uri scheme such as
"http:" is provided, then treat it as a package identifier:

#import("html");
#import("http://github.com/foo/bar");

If we do poke at the import syntax, I think we can do better than that, but that's just my personal opinion. The language designers are very cautious about syntax changes, so I don't know what/when/if we'll do anything here.

- bob

Bob Nystrom

unread,
May 18, 2012, 1:15:11 PM5/18/12
to Sean Eagan, General Dart Discussion
On Thu, May 17, 2012 at 2:19 PM, Sean Eagan <seane...@gmail.com> wrote:
I forgot to mention the main reason that this could be useful which is
to mock out builtin libraries.

Mocking and configuration-specific libraries are definitely on our radar with the package manager. It's a bit of a blunt instrument to have to swap something out at the package level instead of being able to, say, mock a single class, but it may be worth pursuing. As it is now, Dart the language doesn't have any built-in support for dependency injection, so doing it at the package level may be the easiest path.


Also, realized that plain identifiers are already treated as relative
URIs, thus "package:" (or similar) is necessary after all.

Exactly right.
 

Also, I don't think it is currently allowed to import a "package:" URI
without a "/foo.dart" suffix.  Maybe:

#import('package:foo');

could be short for:

#import('package:foo/foo.dart');

Right now, the semantics for interpreting a "package:" are very simple, which is good. Every Dart implementation (the VM, the editor, Dartium, frog, dartc, and dart2js) has to implement it, so it's not easy to iterate on. I definitely don't like the "foo/foo" redundancy, but I haven't put time into trying to eliminate just yet. It is on my radar, though.

- bob

Seth Ladd

unread,
May 18, 2012, 1:21:44 PM5/18/12
to Matthew Butler, mi...@dartlang.org
I've seen people get confused by the syntax of 'dart:html'. Most of our samples show this:

#import('dart:html');

so they naturally assume they can do this:

#import('my:lib:is:awesome');

when in fact they need to do:

#import('my/lib/is/awesome.dart');

So while it should be clear what is a standard library, I think we need to be aware of the different syntaxes we already have. Users will follow our lead, so the core/built-in libs should be written out in a way that makes it easy for other developers to follow our lead. Right now, this is not the case.

(granted, you could argue each of our samples should include comments or show both dart:html and my/lib/is/awesome.dart as two different ways to import.)

John Messerly

unread,
May 18, 2012, 1:57:27 PM5/18/12
to Seth Ladd, Matthew Butler, mi...@dartlang.org
Yeah, I was also surprised when I learned that dart: was a URI. If we used something like:
  #import('dart://html'); 

...then it would look more like a URI. I don't actually want that though--we don't need 2 more redundant punctuation characters in the import :)

- John

Sean Eagan

unread,
May 19, 2012, 4:42:39 PM5/19/12
to Bob Nystrom, General Dart Discussion
On Fri, May 18, 2012 at 12:15 PM, Bob Nystrom <rnys...@google.com> wrote:
> Right now, the semantics for interpreting a "package:" are very simple,
> which is good. Every Dart implementation (the VM, the editor, Dartium, frog,
> dartc, and dart2js) has to implement it, so it's not easy to iterate on. I
> definitely don't like the "foo/foo" redundancy, but I haven't put time into
> trying to eliminate just yet. It is on my radar, though.

Well, packages _can_ consist of multiple libraries, but a good portion
of the time they will only consist of one. So the single library case
probably deserves a more convenient form. A package is essentially a
"variable" library path, right ? So maybe packages could appear in
import statements, similarly to how variables appear in Dart code.
This import:

#import('package:foo/foo.dart');

could be shortened to:

#import(foo);

It could additionally be considered whether dropping parentheses from
the directive syntax would be an improvement:

#import foo;


Cheers,
Sean Eagan

Bob Nystrom

unread,
May 21, 2012, 12:11:04 PM5/21/12
to Sean Eagan, General Dart Discussion
On Sat, May 19, 2012 at 1:42 PM, Sean Eagan <seane...@gmail.com> wrote:
On Fri, May 18, 2012 at 12:15 PM, Bob Nystrom <rnys...@google.com> wrote:
> Right now, the semantics for interpreting a "package:" are very simple,
> which is good. Every Dart implementation (the VM, the editor, Dartium, frog,
> dartc, and dart2js) has to implement it, so it's not easy to iterate on. I
> definitely don't like the "foo/foo" redundancy, but I haven't put time into
> trying to eliminate just yet. It is on my radar, though.

Well, packages _can_ consist of multiple libraries, but a good portion
of the time they will only consist of one.

It will be a while before we have empirical data on that. If we move away from using #source and start using #import for everything, then packages will consist of multiple libraries because every source file will essentially be its own library. But it's yet to be seen if that's the way things are going to go. Nathan and I are planning to try it out for pub to see how it feels.

So the single library case probably deserves a more convenient form.  A package is essentially a
"variable" library path, right ?

That's definitely one critical piece, yes. There's lots of other stuff too: metadata, versioning, distribution and discovery, etc.
 
So maybe packages could appear in import statements, similarly to how variables appear in Dart code.
This import:

#import('package:foo/foo.dart');

could be shortened to:

#import(foo);

Given this, would #import(foo.bar) mean "package:foo/bar.dart" or "package:foo/bar/bar.dart"?


It could additionally be considered whether dropping parentheses from
the directive syntax would be an improvement:

#import foo;

If it were up to me, I'd ditch the "#" too:

import foo;

- bob

Sean Eagan

unread,
May 21, 2012, 1:34:06 PM5/21/12
to Bob Nystrom, General Dart Discussion
On Mon, May 21, 2012 at 11:11 AM, Bob Nystrom <rnys...@google.com> wrote:
>> This import:
>>
>> #import('package:foo/foo.dart');
>>
>> could be shortened to:
>>
>> #import(foo);
>
> Given this, would #import(foo.bar) mean "package:foo/bar.dart" or
> "package:foo/bar/bar.dart"?

I would say the latter, since that would allow for arbitrarily nested
packages (e.g. foo.bar.baz). It would also allow other support files
to co-exist in a library's directory, such as tests.dart, the pubspec,
etc. In this case, I might also prefer using a standard name for the
entry point source file, such as library.dart or main.dart.

> If it were up to me, I'd ditch the "#" too:
>
> import foo;

+1

Cheers,
Sean Eagan

Bob Nystrom

unread,
May 21, 2012, 3:50:30 PM5/21/12
to Sean Eagan, General Dart Discussion
On Mon, May 21, 2012 at 10:34 AM, Sean Eagan <seane...@gmail.com> wrote:
On Mon, May 21, 2012 at 11:11 AM, Bob Nystrom <rnys...@google.com> wrote:
>> This import:
>>
>> #import('package:foo/foo.dart');
>>
>> could be shortened to:
>>
>> #import(foo);
>
> Given this, would #import(foo.bar) mean "package:foo/bar.dart" or
> "package:foo/bar/bar.dart"?

I would say the latter, since that would allow for arbitrarily nested
packages (e.g. foo.bar.baz).

Right, that's important. But requiring each library to be in its own directory is pretty cumbersome, especially if we move towards not using #source. In that model, every source file would be a library, and it would suck majorly to have a directory for each one.
 
 It would also allow other support files
to co-exist in a library's directory, such as tests.dart, the pubspec,
etc.  In this case, I might also prefer using a standard name for the
entry point source file, such as library.dart or main.dart.

We've toyed with that off and on. One motivation against that is it looks pretty nasty in your editor if you have a bunch of entrypoints open and they're all just "main.dart".
 
- bob

Ladislav Thon

unread,
May 21, 2012, 4:25:21 PM5/21/12
to Bob Nystrom, Sean Eagan, General Dart Discussion
> Given this, would #import(foo.bar) mean "package:foo/bar.dart" or
> "package:foo/bar/bar.dart"?

I would say the latter, since that would allow for arbitrarily nested
packages (e.g. foo.bar.baz).

Right, that's important. But requiring each library to be in its own directory is pretty cumbersome, especially if we move towards not using #source. In that model, every source file would be a library, and it would suck majorly to have a directory for each one.

I solved this in DPM by having the "package descriptor" (pubspec, in your words) declare the "main script" of the package. If this main script wasn't defined, full path was needed in the #import.

LT

Christopher Wright

unread,
May 21, 2012, 4:49:12 PM5/21/12
to Sean Eagan, Bob Nystrom, General Dart Discussion
On 21 May 2012 17:34, Sean Eagan <seane...@gmail.com> wrote:
On Mon, May 21, 2012 at 11:11 AM, Bob Nystrom <rnys...@google.com> wrote:
>> This import:
>>
>> #import('package:foo/foo.dart');
>>
>> could be shortened to:
>>
>> #import(foo);
>
> Given this, would #import(foo.bar) mean "package:foo/bar.dart" or
> "package:foo/bar/bar.dart"?

I would say the latter, since that would allow for arbitrarily nested
packages (e.g. foo.bar.baz).  It would also allow other support files
to co-exist in a library's directory, such as tests.dart, the pubspec,
etc.  In this case, I might also prefer using a standard name for the
entry point source file, such as library.dart or main.dart.

So you arrange your source code as:
foo/bar.dart
foo/bar/baz.dart

I was tempted to suggest, search for one and then the other; but any amount of complexity in the lookup rules will result in aggravation and annoyance, and some outright bugs.

Bob Nystrom

unread,
May 21, 2012, 5:30:58 PM5/21/12
to Christopher Wright, Sean Eagan, General Dart Discussion
On Mon, May 21, 2012 at 1:49 PM, Christopher Wright <dhas...@google.com> wrote:
On 21 May 2012 17:34, Sean Eagan <seane...@gmail.com> wrote:
On Mon, May 21, 2012 at 11:11 AM, Bob Nystrom <rnys...@google.com> wrote:
>> This import:
>>
>> #import('package:foo/foo.dart');
>>
>> could be shortened to:
>>
>> #import(foo);
>
> Given this, would #import(foo.bar) mean "package:foo/bar.dart" or
> "package:foo/bar/bar.dart"?

I would say the latter, since that would allow for arbitrarily nested
packages (e.g. foo.bar.baz).  It would also allow other support files
to co-exist in a library's directory, such as tests.dart, the pubspec,
etc.  In this case, I might also prefer using a standard name for the
entry point source file, such as library.dart or main.dart.

So you arrange your source code as:
foo/bar.dart
foo/bar/baz.dart

That works for sub-libraries, but is a bit trickier for the top-level library (i.e. #import(foo)).
 

I was tempted to suggest, search for one and then the other; but any amount of complexity in the lookup rules will result in aggravation and annoyance, and some outright bugs.

Yeah, we can't do any searchpath-style lookup. This needs to be handled by the browser and we don't really want to do poke in multiple directories over HTTP to try to find something.

If we do look into optimizing the syntax here, maybe the semantics would just be:

1. A single identifier "import foo" desugars to: "package:foo/foo.dart".
2. A dotted identifier "import foo.bar.baz" desugars to: "package:foo/bar/baz.dart".

This implies that "import foo" and "import foo.foo" desugar to the same thing, but that's probably OK.

But I should clarify that all of this is pure speculation at this point. We don't have any current plans to change the import syntax.

- bob

Eric Leese

unread,
May 21, 2012, 8:00:57 PM5/21/12
to General Dart Discussion
But we'd want to encourage people to use package nesting to make their
code uniquely identifiable, so there will be a lot of "import
com.foocorp.bar.bar". Just have a way of distinguishing the two cases
in syntax:

import foo.bar -> "foo/bar/bar.dart"
import foo.bar:baz -> "foo/bar/baz.dart"
import dart:html -> "dart/html.dart"

On May 21, 2:30 pm, Bob Nystrom <rnyst...@google.com> wrote:
> On Mon, May 21, 2012 at 1:49 PM, Christopher Wright <dhase...@google.com>wrote:
>
>
>
>
>
>
>
>
>
> > On 21 May 2012 17:34, Sean Eagan <seaneag...@gmail.com> wrote:
>
> >> On Mon, May 21, 2012 at 11:11 AM, Bob Nystrom <rnyst...@google.com>

Bob Nystrom

unread,
May 22, 2012, 1:34:07 PM5/22/12
to Eric Leese, General Dart Discussion
On Mon, May 21, 2012 at 5:00 PM, Eric Leese <le...@google.com> wrote:
But we'd want to encourage people to use package nesting to make their
code uniquely identifiable, so there will be a lot of "import
com.foocorp.bar.bar".

We definitely want package names to not collide, but it's subject of debate about how many identifier parts are required to achieve that. There are strong opinions on all sides, which usually tells me there is an absence of actual data. :)

Just have a way of distinguishing the two cases in syntax:

import foo.bar -> "foo/bar/bar.dart"
import foo.bar:baz -> "foo/bar/baz.dart"
import dart:html -> "dart/html.dart"

We've already seen from the hackathons and other feedback that users are confused by having multiple "path separators" in import statements with ":" and "/" so I'd like to move away from that.

- bob

Daniel Rubel

unread,
May 22, 2012, 4:51:40 PM5/22/12
to Bob Nystrom, Eric Leese, General Dart Discussion
On Tue, May 22, 2012 at 1:34 PM, Bob Nystrom <rnys...@google.com> wrote:

Just have a way of distinguishing the two cases in syntax:

import foo.bar -> "foo/bar/bar.dart"
import foo.bar:baz -> "foo/bar/baz.dart"
import dart:html -> "dart/html.dart"

We've already seen from the hackathons and other feedback that users are confused by having multiple "path separators" in import statements with ":" and "/" so I'd like to move away from that.

Some of the confusion could be cleared up with better error messages from the Dart Editor, VM, and what not.
For example, if someone tries...

#import('package:foo:bar.dart');

... then the error message could be ...

Invalid import "package:foo:bar.dart"... did you mean "package:foo/bar.dart" ?

... or something like that which would not only point out the problem, but perhaps suggest the appropriate action for the user to take.
Obviously this could be adapted to whatever syntax we choose.

Reply all
Reply to author
Forward
0 new messages