language icon indicating copy to clipboard operation
language copied to clipboard

Private Named Parameters

Open munificent opened this issue 5 months ago • 13 comments

Admin comment: this is moving to implementation.


This is the tracking issue for the Private Named Parameters proposal.

The proposal makes it easier to initialize and declare private instance fields using named constructor parameters. It addresses #2509 and turns code like this:

class House {
  int? _windows;
  int? _bedrooms;
  int? _swimmingPools;

  House({
    int? windows,
    int? bedrooms,
    int? swimmingPools,
  })  : _windows = windows,
        _bedrooms = bedrooms,
        _swimmingPools = swimmingPools;
}

Into this:

class House {
  int? _windows;
  int? _bedrooms;
  int? _swimmingPools;

  House({this._windows, this._bedrooms, this._swimmingPools});
}

The proposal harmonizes with (and in a couple of places mentions) the primary constructors proposal. When combined with that proposal, the above example becomes:

class House({
  var int? _windows,
  var int? _bedrooms,
  var int? _swimmingPools,
});

Without this proposal, the example here wouldn't be able to use a primary constructor at all without giving up either privacy on the fields or named parameters in the constructor.

munificent avatar Jul 15 '25 00:07 munificent

(I think that last example is meant to be

class House({
  int? _windows,
  int? _bedrooms,
  int? _swimmingPools,
});

)

Mike278 avatar Jul 15 '25 11:07 Mike278

Oops, you're almost right. Fixed, thanks!

munificent avatar Jul 15 '25 17:07 munificent

Consider adding examples of what it looks like to call the new functions.

reidbaker avatar Jul 16 '25 15:07 reidbaker

Oh, good point. Added one to this in-progress PR: https://github.com/dart-lang/language/pull/4468

munificent avatar Jul 18 '25 22:07 munificent

Do we consider to just introduce keyword private to handle this properly? It is strange, that Dart uses keywords everywhere except this, where usage is very obvious and do not require mental effort to understand such magic replacement as in proposal

gryznar avatar Jul 23 '25 09:07 gryznar

Do we consider to just introduce keyword private to handle this properly?

I think it would be really strange to use private as a modifier for privacy in one very small corner of the language when we don't use private for privacy anywhere else in the language.

Of course, it might be nice if we did use private everywhere instead of _ for privacy, but there's millions and millions of lines of Dart code out there, so that's not really a feasible change without a time machine.

munificent avatar Jul 24 '25 00:07 munificent

I mean everywhere. Of course, it may need supporting 2 possibilities (up to Dart 4/5?), but still I think it is worth it long term

gryznar avatar Jul 24 '25 07:07 gryznar

I mean everywhere.

There is no way to describe that feature with "just" then. It would be an absolute mountain of work and it's entirely likely that the result isn't worth the effort.

munificent avatar Jul 24 '25 21:07 munificent

Of course, it might be nice if we did use private everywhere instead of _ for privacy, but there's millions and millions of lines of Dart code out there, so that's not really a feasible change without a time machine.

@munificent Just out of curiosity, if such a change happened (_ -> private), isn’t that something that could be automated with a migration tool? Or are there edge cases?

rubenferreira97 avatar Jul 25 '25 00:07 rubenferreira97

@rubenferreira97 It will still make most packages on pub no longer work until developer uploads a new version. It is also a change that would touch a lot of code across projects and you will also end up with problems like the following that would require manually fixing:

class A {
  final int _a;

  A(int a) : _a = a;

  int get a => _a;
}

This is a simple example but we do have cases where people defines fields for both _a and a as e.g. one normal field and another as a getter.

And you can't argue that all this work would actually ends up fixing any real issues with e.g. stability, security, performance and so on. It is not like null-safety where we at least can argue that the huge amount of work related to fixing old code would be an overall benefit for the whole community.

The adding of private keyword would mostly (if not only) just be about syntax change. And asking for all developers across all projects to then start doing migrating work would be very painful when not everybody even supports the idea of adding such keyword.

Especially since there are now a lot more Dart code being written than back in the days of Dart 2.12 and null-safety was introduced.

julemand101 avatar Jul 25 '25 03:07 julemand101

isn’t that something that could be automated with a migration tool? Or are there edge cases?

It's very common for a class to have a private field named _foo and a public getter/setter named foo. If we tried to automatically rename _foo to private foo, those would collide. We'd have to do something more complex.

munificent avatar Jul 28 '25 19:07 munificent

It's very common for a class to have a private field named _foo and a public getter/setter named foo. If we tried to automatically rename _foo to private foo, those would collide. We'd have to do something more complex.

Maybe we could simply choose not to be clever at all and avoid renaming fields. Developers can keep their existing names. There are languages that use private while still keeping the _ prefix for readability (a pattern from the pre-intellisense era, C# did this and some developers still follow it). If developers want to rename it, sure, they can go ahead.

class A {
  private final int _a; // We add `private` here, even though `_` already implies privacy.

  A(int a) : _a = a;

  int get a => _a; // This remains public since there's no visibility modifier (or we could explicitly write `public`).
}

This way, we avoid automatic renaming and potential collisions between _foo and foo. However, this might result in two separate styles of marking something private. That said, it may slightly defeat the purpose of brevity of this feature, but the semantics would be clear.

rubenferreira97 avatar Jul 28 '25 23:07 rubenferreira97

Maybe we could simply choose not to be clever at all and avoid renaming fields. Developers can keep their existing names. There are languages that use private while still keeping the _ prefix for readability (a pattern from the pre-intellisense era, C# did this and some developers still follow it). If developers want to rename it, sure, they can go ahead.

+1. We may support old style _ for compatibility and private (the right one) as default with supporting new features related to privacy only for private

gryznar avatar Jul 29 '25 06:07 gryznar