Skip to content

Meta-issue for discussion of the proposal to allow named arguments everywhere #30353

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

Closed
leafpetersen opened this issue Aug 7, 2017 · 10 comments
Labels
area-language Dart language related items (some items might be better tracked at github.com/dart-lang/language). language-discussion

Comments

@leafpetersen
Copy link
Member

leafpetersen commented Aug 7, 2017

This issue is to provide a forum for community discussion and feedback related to the proposal to allow named arguments to appear at any position in an argument list.

That is, named arguments may appear before positional arguments when calling a function. Example:

expectAsync(count: 2, () { 
   some.long.function.body;
});

This entry will be updated when a proposal is available.

cc @munificent @eernstg @floitschG @lrhn

@leafpetersen leafpetersen added area-language Dart language related items (some items might be better tracked at github.com/dart-lang/language). language-discussion labels Aug 7, 2017
@matanlurey
Copy link
Contributor

I'm constantly confused whether I should use a named or positional optional argument. I like the terseness of the latter sometimes, but it's a huge pain to refactor and deprecate later on, so I usually choose named:

void doThing([bool someFlag = false]);
void doThing({bool someFlag = false});

My understand is that this proposal would simply allow:

void doThing([bool someFlag = false]);

doThing(true);
doThing(someFlag: true);

Is that correct? That makes it seem like "named" is just an alias for the tools (i.e. new frontend), and everything is actually a positional argument. I like this simplification from the perspective of understanding what a compiler will do at a user-level.

Some downsides or questions I'd have:

  • What would be the strategy for deprecating long functions, i.e.:
Widget createWidget([
  @Deprecated('This flag is no longer supported and will be removed')
  bool someFlag = false,
  @required String title,
  List<Widget> children = const [],
])

If any user could use this function like createWidget(false, 'Hello', []), I'd have to change all call-sites to remove any argument (not required before). I guess we could ask for additional optional metadata annotations, i.e. @requireNamedInvocations, but then we lose terseness. Maybe the style guide though could just say any number > n should be invoked named?

  • How would matching functions work, i.e.:
void printOnFailure(void Function(String message, {int times}) write);

I guess I could write:

printOnFailure(() => 'Bad, times = 10);

Or:

printOnFailure(() => 'Bad', 10);

Is that correct?

@lrhn
Copy link
Member

lrhn commented Aug 8, 2017

That's not correctly guessed. I have extended the initial message to make guessing less necessary :)

@a14n
Copy link
Contributor

a14n commented Aug 8, 2017

Regarding this comment from @lrhn my understanding is that this proposal is to allow to write:

m(a: 10, p1Value, b: false, p2Value)

(named parameter anywhere) for fonction defined by

void m(Object p1, Object p2, {int a, bool b})

@JFixby
Copy link

JFixby commented Aug 8, 2017

How about

void doThing(Object p1, Object p2);

to be allowed both:

doThing(x, y);

and

doThing(p1: x, p2: y);

@eernstg
Copy link
Member

eernstg commented Aug 8, 2017

@JFixby, that's actually a different proposal, much closer to issue #30255, and Lasse already gave a very detailed response on why that idea has substantial software engineering costs; Arduin referred to the same comment above.

This is a simpler proposal where named arguments must always be passed as named arguments, and positional arguments always positionally, but you can put the named arguments anywhere you want in the actual argument list, and the positions of the positional arguments are computed by not counting the named arguments along the way (so in doThing(p1: x, y), y is the first positional argument).

@JFixby
Copy link

JFixby commented Aug 8, 2017

@eernstg

My concern is only that when you change function declaration between

void doThing( Object p1, Object p2 );

and

void doThing( { Object p1, Object p2 } );
void doThing( [ Object p1, Object p2 ] );
void doThing( Object p1, { Object p2 } );

and so on.

Then you have to go and fix each line calling this function, even if you didn't change anything in the callings from technical point of view:

doThing(p1: x, p2: y); // is still the same call, right?

@JFixby
Copy link

JFixby commented Aug 8, 2017

Should I create a separated ticket for that?

@eernstg
Copy link
Member

eernstg commented Aug 8, 2017

It's definitely a different issue than this one. I haven't checked exactly whether/how it differs from #30255, but if it's significantly different from #30255 as well then it should be a brand new issue.

@eernstg
Copy link
Member

eernstg commented Jul 9, 2018

Note that we also have #15398 'Allow named function arguments anywhere in the argument list'

@mit-mit
Copy link
Member

mit-mit commented Apr 1, 2022

Closing as dart-lang/language#1072 has landed

@mit-mit mit-mit closed this as completed Apr 1, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-language Dart language related items (some items might be better tracked at github.com/dart-lang/language). language-discussion
Projects
None yet
Development

No branches or pull requests

7 participants