Dart functions currently can have only either optional named parameters or optional positional parameters, but not both.
While developing libraries repeatedly run into cases where this restriction gets in the way of the signature we want.
It would be preferable if you could have both kinds of parameters on the same function.
The only syntax change necessary is to the declaration of functions. The call syntax is unaffected, and so is noSuchMethod/Function.apply.
This issue is related to issue dart-lang/sdk#6496, but asks for less.
_This comment was originally written by @seaneagan_
Is this asking for:
The former could be solved by non-overlapping [] and {}. If overlapping [] and {} are allowed, then would have to decide whether to allow both {[ and [{ as well as }] and ]].
It is asking for non-overlapping [] and {}.
Examples:
new List([length = 0], {fill: null});
Stream.subscribe([onData], {onError, onDone})
new Date(year, [month, ...., milliseconds], {isUtc: false})
_This comment was originally written by @seaneagan_
Sounds perfect! The only other thing I would change (also mentioned in issue dart-lang/sdk#6496) is to use = instead of : for named positional default values:
new List([length = 0], {fill = null});
The = to default positional optionals doesn't mimic call site syntax, so why does the named positional default syntax try to? I think it's more importatnt to be consistent between how to default optional parameters regardless of whether they are named or positional.
_This comment was originally written by @rbishop-bah_
Related: Issue dart-lang/sdk#17101
_Removed this from the Later milestone._
_Added Oldschool-Milestone-Later label._
_Removed Oldschool-Milestone-Later label._
Issue dart-lang/sdk#17101 has been merged into this issue.
_Marked this as blocking dart-lang/sdk#21406._
Since 2.0 is thinking of some drastic changes is there any way the more extreme do like C#, Python, of dart-lang/sdk#6496 can be revisited.
@gbracha would a DEP be required for this?
@donny-dont if this issue is fixed then we will be able to do:
greet([String salutation = 'Hello'], {String who}) {
print('$salutation $who!');
}
Then if there is really a need to allow parameters to be both named _and_ positional, we could further allow something like this syntax:
greet({[String salutation = 'Hello', String who]}) {
print('$salutation $who!');
}
But personally, I think that creates unnecessarily bloated API surface.
Any guesses when this might get implemented?
I would like to have the ability to have a parameter be either positional or named, for a common usage case in Flutter -- the children/child of a widget (note that this case also applies to any place where you are building tree-structured values).
Consider the following Flutter widget tree:
new Center(child:
new Column(children: [
new Text("Hello, World!"),
new Icon(Icons.star, color: Colors.green)
])
)
Once "new" is optional, this starts looking like a reasonable replacement for HTML, as soon as we can treat child or children arguments as positional, like this:
Center(
Column([
Text("Hello, World!"),
Icon(Icons.star, color: Colors.green)
])
)
We kinda already have this in that Text doesn't specify the 'Hello, World!' string as a child, even though it kinda is. Same thing for Icon.
It would be nice (albeit not required) if the positional argument did not have to be the first argument so you could specify the named arguments first before following them with the children specified as a positional argument.
I would love to see this, together with making child en children positional in Flutter 馃檹
In maintaining the protobuf library we have functions that take positional optional arguments, making it hard to add further optional arguments.
Refactoring the existing functions to take only named arguments is probably the 'right thing to do(tm)' but that is a breaking change and thus very costly.
For example GeneratedMessage.fromBuffer currently has the signature
void mergeFromBuffer(List<int> input,
[ExtensionRegistry extensionRegistry = ExtensionRegistry.EMPTY]);
If we want to add more options to the parsing (for example bool ignoreUnknownFields) it would be nice to add as a named optional, but that is currently not possible.
Something new? This sounds like a useful feature...
Is such a thing allowed now?
Future<Database> connect({String dbName, [String dbUserName, String dbPassword]}) {}
connect(dbName:"sample");
connect(dbName:"sample", dbUserName:"username", dbPassword:"password");
Or do you know similar issue for this one problem?
Is such a thing allowed now?
Future<Database> connect({String dbName, [String dbUserName, String dbPassword]}) {}connect(dbName:"sample"); connect(dbName:"sample", dbUserName:"username", dbPassword:"password");
That wasn't the problem. The problem was using them as separate, and not nested, like this:
Future<Database> connect({String dbName}, [String dbUserName, String dbPassword])
I too ran today into this while working on a new API and I actually don't understand this restriction. If it's possible to mix named and positional parameter , why can't that positional not being optional?
+1 for this feature
Most helpful comment
I would like to have the ability to have a parameter be either positional or named, for a common usage case in Flutter -- the children/child of a widget (note that this case also applies to any place where you are building tree-structured values).
Consider the following Flutter widget tree:
Once "new" is optional, this starts looking like a reasonable replacement for HTML, as soon as we can treat child or children arguments as positional, like this:
We kinda already have this in that Text doesn't specify the 'Hello, World!' string as a child, even though it kinda is. Same thing for Icon.
It would be nice (albeit not required) if the positional argument did not have to be the first argument so you could specify the named arguments first before following them with the children specified as a positional argument.