-
Notifications
You must be signed in to change notification settings - Fork 213
Add a "namespace" keyword #2272
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
For the enum Colors extends Color {
red(0xFFFF0000),
blue(0xFF0000FF),
// ...
purple(0xFFFF00FF),
;
const Colors(super.rgba);
} No need to have an extra I'd usually put the constants of a type into that type itself, so it would be Personally, I'd just use |
@lrhn I tried copy-pasting your snippet, and it gave me an error: I saw in the Dart language tour that
This is a great idea, at least for anyone who's going for the best combination of readability and functionality that we have right now. The I've updated my original issue comment to include this suggestion. |
Damnit, my bad. You can implement an interface, and apply a mixin, but an |
If we did have a We usually use UpperCamelCase for types, and it's probably just consistency that made us do the same for We do have a tradition for namespaces. The one namespace we already have is the import prefix, which uses snake_case. Library names too, which were originally thought of as a kind of namespace identifier. That makes it likely that we'll recommend We could introduce namespace aliases: |
@lrhn I'm glad you brought this up. I personally don't have a strong preference about Namespace aliases would be really nice to have; adding modifiers like We'd just have to decide which precedent makes more sense:
or
If namespaces do get implemented at some point, I'd be happy with either of these. |
const namespace Colors as Color {
red = Color(0xFFFF0000);
blue = Color(0xFF0000FF);
} I'd prefer a syntax like this although it looks like a variable declaration. const Color namespace Colors {
red = Color(0xFFFF0000);
blue = Color(0xFF0000FF);
} or namespace Colors as const Color {
red = Color(0xFFFF0000);
blue = Color(0xFF0000FF);
} Having |
It seems to me that namespaces could make (shorter dot syntax) #357 more general, and also maybe address (static extension methods) #723. namespace Colors on Color {
// Static keyword is implicit in all these declarations, as if these were top-level declarations,
// but they are actually registered in the static namespace of Colors
// as well as the Color class (when there is no conflicts)
const red = Color(0xFFFF0000);
const blue = Color(0xFF0000FF);
const myAwesomeColor = Color(0xFF0F0FFF);
Color get randomColor => Random()..nextInt(0xFFFFFFFF);
int _nextColor = 0x00000000;
Color nextColor() {
return Color(_nextColor++);
}
} The namespace makes these members accessible by the prefix return ColoredBox(color: .randomColor, child: Text('Something'));
return ColoredBox(color: .nextColor(), child: Text('Something'));
return ColoredBox(color: .myAwesomeColor, child: Text('Something'));
return ColoredBox(color: .red, child: Text('Something')); Edit: |
is |
@Hixie I believe so, although |
It would be nice to have an enum like a abstract class but with heavy restrictions enum Colors
{
blue = Color(0xFF0000FF),
red = Color(0xFFFF0000);
}
Color a = Colors.red; The idea is to prefer enum for constants without having to use a more general purpose notation like abstracts or a library. I know, depending on the declaration the call return type would change... |
Thanks to all the class modifiers introduced in Dart 3.0, I think we're good to close this issue. There wasn't anything that does exactly what I suggested, but we have several good options now— |
The Problem
There are many places in the Flutter repository where a class is used as a namespace, often to store many
const
values of the same type. I've found examples of this in autofill.dart, colors.dart, curves.dart, icons.dart, and unicode.dart.And there are many other places in the Flutter repo where a class is used to hold static members that aren't just
const
values, which directly goes against Dart's style guide. I found 7 files in the services/ folder with a class that's structured in this way (clipboard.dart, deferred_component.dart, haptic_feedback.dart, system_channels.dart, system_chrome.dart, system_navigator.dart, and system_sound.dart).Despite how it's apparently a bad coding practice, using a class as a namespace seems to provide a lot of utility within the Flutter repository, and I'm sure many others (myself included) are creating classes as namespaces in their own projects.
Workarounds
Let's use a simplified version of
Colors
as an example:There are some great ways to store a bunch of
const
values of the same type, includingList
andMap
:Sadly, these options can't match the autofill convenience that classes provide:
Dart 2.17 allows
enum
s to contain other types:But why would you want to type out
Colors.red.color
every time you need the color red when you can just useColors.red
by making a class instead?The Dart style guide recommends implementing a namespace as a library:
But this would require you to devote an entire
.dart
file to a single namespace, which can be inconvenient in many situations.Fortunately, I learned from @lrhn that you can create an extension on the
Never
class as a makeshift namespace:This syntax, while definitely not intuitive, is better than
class Colors
with aColors._()
constructor since it can't be implemented, making it functionally identical to a namespace. There's currently a pull request open on the Flutter repo to enact this change, so perhaps this is what namespaces likeColors
will look like in the future.And if you're hoping for a syntax that's intuitive enough that you don't need a comment explaining what it does, you can use the
abstract
keyword:This doesn't prevent you from extending the class, implementing it, or using it as a mixin, but a Dart developer who knows how to use
extends
,implements
, andwith
will understand that anabstract class
with allstatic
members is meant to be used as a namespace.Proposal
It looks to me like we have two options moving forward.
1. Don't change the Dart language
If we don't end up implementing any changes to the Dart syntax, we still should update the Dart style guide with information about using an
extension on Never
(assuming we decide to go through with the aforementioned pull request).Alternatively, we could update our documentation to recommend using an
abstract class
withstatic
members in place of a namespace, since it's much more intuitive thanextension on Never
.2. Add a
namespace
keywordcould instead be constructed as
We could even have keywords that cover common use cases:
or maybe even
Even just a quick and dirty keyword addition (i.e.
namespace [Name]
=extension [Name] on Never
with allstatic
members) would be beneficial to people who use or contribute to the Flutter codebase, which is nearly everyone who uses Dart.The text was updated successfully, but these errors were encountered: