language icon indicating copy to clipboard operation
language copied to clipboard

Consider different name for "augmentation libraries"

Open lrhn opened this issue 1 year ago • 5 comments

The augmentation libraries feature specification introduces "augmentation libraries" which are not Dart libraries. An augmentation library has things in common with libraries (can have its own imports), and things in common with parts (has the same declaration scope as the parent library's), but it's really a neither.

I worry that using the word "library" sets the wrong expectations. Where we currently say "library", we'll have to say "non-augmentation library", unless we want to include it, in which case I'd say "augmentation or non-augmentation library". The word "library" itself will be lost, because it's ambiguous whether it refers to both the new (different kinds) of libraries, or just the old-style actual library.

If anything, staying in the terminology of augmentation, the file is more of a "library augmentation", which augments the main library, than it is an "augmentation library", with focus on the "library".

If we use that, then:

  • A library augmentation is a file that looks similar to a library in many ways, just like a class augmentation looks like a class.
  • It adds or modifies the existing library by having declarations or declaration augmentations, just like a class declaration modifes a class.

So, conceptually I think it feels OK.

_The biggest difference is that a library declares its own augmentations, where other declarations do not. A class augmentation just appears (later) in the same library as the class declaration. But since libraries do not exist in a container that can also hold augmentations, it's probably unavoidable that the link to the augmentation is in the library itself.

So, suggestion:

  • It's called a "library augmentation", not an "augmentation library".
  • It's imported using augment import "..."; or augment part "...";, just like any other augmentation declaration starts with augment. (And augment will be a built-in identifier, so that should not be a problem.)
  • It's marked at the top as augment of "parent.dart";, augment library "parent.dart", or augmented library "parent.dart". Not using a library declaration with library first, because it is not a library. Either treat it as declaring that it augments the parent library, or that it references the parent library using augmented, but the latter would be the only use of augmented outside of body code, so probably not worth it.

The library augmentation file doesn't have a library name. It cannot be imported directly. It's not a library.

Then we can keep saying "library" to refer to just the plain Dart library, and "library augmentation" to refer to the library augmentations that a library or library augmentation may include.

lrhn avatar Jan 22 '24 11:01 lrhn

All of this sounds good to me 👍

jakemac53 avatar Jan 22 '24 15:01 jakemac53

It's called a "library augmentation", not an "augmentation library".

Why not just "augments"? If we can augment a part, saying "library augmentation" feels wrong to me

rrousselGit avatar Jan 22 '24 16:01 rrousselGit

@MaryaBelanger For the documentation impact.

bwilkerson avatar Jan 22 '24 17:01 bwilkerson

To me "library augmentation" sounds consistent. It falls into the same patterns as "class augmentation".

AFAIK "augment" is not proper noun?

So, as I understand English, import augment should be import augmentation.

We can look at augment class A {} as at the command to augment A, so it seems fine to me. Or we could say class augmentation A {} to make it read as a description what it is. Although this is not consistent with other class modifiers, like abstract class A {}, but these read naturally in this order.

scheglov avatar Jan 22 '24 17:01 scheglov

There are, at least, two concerns here: the name of the concept and the syntax to express it. (And the name of the entire "language feature", but I consider that a marketing issue, not a design issue.)

The file that applies to a library, and which can contain augmentations that apply to the library declarations, as well as plain declarations added to the library, that file itself needs a name. It's not a Dart library file, and it's not a part file. I'd be fine with "augmentation file", "library augmentation file", or maybe something else that focuses on its ability to have its own imports, more than its ability to contain augmentations (especially if other files can do that too).

I'm opposing "augmentation library" because that suggests that it is a library, which is not, and that gets confusing when we have to distinguish it from an actual library, which is still a much more common concept to talk about. So "library" is an existing concept with a claim on that name. It's important that the concept names work well when read in prose.

Then there is the syntax for including that file in the parent library, and the syntax for the file to declare itself as that kind of file, and say which parent file it belongs to. It's important that the syntax is clear, less important that it can be read as prose.

Both of these can also use conceptual names, but don't have to. We have an import declaration, which we say imports a library into the current library. And we have a part declaration, where we don't have a consistent name for what it does. I tend to use "includes", but it really is just "a part declaration refers to a part file, which is a part of the library".

So we should figure out the syntax, how to refer to the declaration, and whatever we need a verb for what the declaration does.

I suggested augment import "…"; or augment part "…";, because I see what the declaration does as "applying a library augmentation to the library". And augment is already a built-in identifier, it would be nice to not need more. One could argue that for symmetry with other augment declarations, it should be followed by the declaration of the thing it augments, so augment library …. That is an option, but I don't necessarily think it's user friendly. And this isn't the actual augmentation, it's a reference to it, something other augmented declarations don't need to have.

In any case, the file it references is the library augmentation. I'd be fine with that file starting with augment library "parent_file.dart";, a consistent header for something that augments the library "named" parent_file.dart.

All in all, I'd say:

  • the file is a library augmentation file, or just an augmentation file.
  • it defines a library augmentation
  • the including syntax is a library augmentation application declaration. Or just an augment import-declaration.
  • it applies the library augmentation of the referenced file to the library that contains the declaration.
  • the library augmentation file starts with a library augmentation declaration which points to its parent file, which can be either a library file or a library augmentation file.

This is verbose. That's sometimes the cost of being precise.

I hope it will match the naming of, fx, class augmentations.

If we have a class declaration, and the same library or a library augmentation contains a class augmentation declaration (an augment class declaration with the same name), then the class augmentation of that class augmentation declaration is applied to the original class declaration, at its position in the augmentation application order.

lrhn avatar Jan 23 '24 19:01 lrhn

  • It's called a "library augmentation", not an "augmentation library".

SGTM. Jake's PR #3583 does this.

  • It's imported using augment import "..."; or augment part "...";, just like any other augmentation declaration starts with augment. (And augment will be a built-in identifier, so that should not be a problem.)

I still prefer import augment. When augment appears before a noun in the syntax, it always means that the thing after augment is an existing thing being augmented. So when you write augment class C, it means "Go find C and augment it." But augment import 'foo.dart' does not mean "Go find library 'foo.dart' and augment it." The arrow is pointing the wrong direction.

import augmentation "foo.dart"; would be grammatically a little better. But English is pretty loose and you can pretty much noun, verb, or adjective any word you want. In fact, "augment" is already treated as a noun in one weird use.

  • It's marked at the top as augment of "parent.dart";, augment library "parent.dart", or augmented library "parent.dart". Not using a library declaration with library first, because it is not a library. Either treat it as declaring that it augments the parent library, or that it references the parent library using augmented, but the latter would be the only use of augmented outside of body code, so probably not worth it.

I like using augment library 'main.dart'; (which I think was Jake's idea?) because then it really does mean "this file augments the library 'main.dart'".

The library augmentation file doesn't have a library name. It cannot be imported directly. It's not a library.

+1.

Then we can keep saying "library" to refer to just the plain Dart library, and "library augmentation" to refer to the library augmentations that a library or library augmentation may include.

+10. This is a very good point.

Jake's PR covers about half of your bullet points. For the others, I prefer the current syntax, so I'm going to go ahead and close this but please do re-open if you disagree and want to talk about it more.

munificent avatar Mar 19 '24 23:03 munificent

My main worry is that library augmentations is a useful feature even if it contains no augmentations. As has been suggested, it can act like a replacement for parts which has its own imports.

Focusing on the augmentation part of it seems like a too narrow a naming.

I'll repeat my recommendation from (elsewhere, earlier this thread?) to just use part.

  • Using part for the file, part of for the back-reference.
  • Allow any file to contain augmentation declarations.
  • Allow part files to contain imports, exports and other parts.
  • If they contain any import, they do not inherit the imports of the parent file.
  • Augmentation application order is source-order pre-order (current file declarations in source order first) depth-first (recursively apply part files in source order of the part declaration).
  • Macros effectively append a single final part include to the library.

Then this becomes four orthogonal features:

  • Declaration augmentations, which can be placed anywhere in the same library.
  • Recursive part files, which can contain other part files.
  • Exporting from part files.
  • Hermetic part files, which have their own imports instead of inheriting the imports of the parent file. (Opt in by having an import.)

Each has a well-defined behavior which can be defined without depending on the rest.

lrhn avatar Mar 20 '24 10:03 lrhn

  • If they contain any import, they do not inherit the imports of the parent file.

This is the part that makes me uncomfortable. I would rather have inheriting the imports of the parent file be something more explicit (but I realize this is a breaking change for part files). It feels too magic to have the behavior implicit based only on the presence of any other imports.

Alternatively, this could be the default behavior and we could have some way to opt out of it?

jakemac53 avatar Mar 20 '24 16:03 jakemac53