Skip to content
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

Convert arguments of overwritten method to optional #1827

Closed
DartBot opened this issue Feb 23, 2012 · 17 comments
Closed

Convert arguments of overwritten method to optional #1827

DartBot opened this issue Feb 23, 2012 · 17 comments
Assignees
Labels
area-language Dart language related items (some items might be better tracked at github.com/dart-lang/language). closed-duplicate Closed in favor of an existing report type-enhancement A request for a change that isn't a bug

Comments

@DartBot
Copy link

DartBot commented Feb 23, 2012

This issue was originally filed by amat...@gmail.com


What steps will reproduce the problem?

  1. Create a base class with a method with one argument:
    class Base {
      testing(text) => print(text);
    }
  2. Inherit from this class and overwrite the method, set the param optional
    class Child extends Base {
      testing([text]) {
        if (text != null)
          super.testing(text);
        else
          super.testing("Hello!");
      }
    }
  3. Execute this sentence at main method:
    main() {
      new Child().testing();
    }

What is the expected output?
I expect overwritten to call it's super method with "Hello!"

What do you see instead?
Class definition throws an error: cannot override method method, number of named parameters doesn't match

What version of the product are you using? On what operating system?
Dartboard

Please provide any additional information below.
Dartboard link: http://try.dartlang.org/s/qqct

@floitschG
Copy link
Contributor

In other words: it should be possible to make the last positional arguments optional in a subclass.


Removed Type-Defect label.
Added Type-Enhancement, Area-Language, Triaged labels.

@ghost
Copy link

ghost commented Feb 23, 2012

The spec says:

It is a compile-time error if an instance method m1 overrides an instance member m2 and m1 has a different number of required parameters than m2. It is a compile-time error if an instance method m1 overrides an instance member m2 and m1 does not declare all the named parameters declared by m2 in the same order.

Therefore the reported behavior is correct.

@DartBot
Copy link
Author

DartBot commented Feb 24, 2012

This comment was originally written by @seaneagan


This should apply to function types in general, not just methods (with issue #1616 methods would not be a special case).

Assume we have the following function type:

typedef F(a, b, [c, d]);

The following should be subtypes of F:

typedef G(a, [b, c, d]);
typedef G([a, b, c, d]);

I would take this a step further and say that (as in JavaScript) when a function (or method) is called with extra positional or named arguments, then instead of calling noSuchMethod on the function or method receiver), just ignore the extra arguments. There of course should still be a static warning for this.

Then the following would also all be subtypes of the above function type F:

typedef G(x, y, [a]);
typedef G(x, [y, a]);
typedef G([x, y, a]);
typedef G(x, y);
typedef G(x, [y]);
typedef G([x, y]);
typedef G(x);
typedef G([x]);
typedef G();

The big use case for this is registering callbacks which will be passed arguments which you don't care about, and thus do not want to include in the formal parameters of your callback. For example, as with JavaScript's Array, Dart's List could add an "index" parameter to all of it's higher order methods (forEach, filter, map, every, some, etc.), for example:

void forEach(void callback(E item, int index));

allowing for things like:

list.forEach((item, index) => print("$index: $item"));

while still allowing for:

list.forEach((item) => print(item));

Also it would allow callbacks passed to Future#then where the future does not produce an actual value, to omit the "value" parameter.

@DartBot
Copy link
Author

DartBot commented Feb 27, 2012

This comment was originally written by amatia...@gmail.com


Comment #­3 - @­seaneagan1:
I don't agree

typedef G();

To be a subtype of

typedef F(a, b, [c, d]);

If at F I defined a and b as mandatory at least you function must be able to handle this arguments:

typedef G([a, b]);

This can be a subtype.
If you want to not force a handler to recive a argument you can do it optional:

void forEach(void callback(E item, [int index]);

With this the function

void myCallback(item);

Should be a valid callback for a forEach because it's a subtype of the expected callback.

@DartBot
Copy link
Author

DartBot commented Feb 27, 2012

This comment was originally written by @seaneagan


I agree that it shouldn't be a "subtype" per se when parameters are missing, and a static warning would help catch errors, but at runtime it shouldn't call noSuchMethod, but instead ignore the extra arguments passed. My basic argument is that, as in JavaScript, you shouldn't have to declare parameters that you don't care about, similar to how you don't have to declare types you don't care about.

@DartBot
Copy link
Author

DartBot commented Feb 27, 2012

This comment was originally written by amatiasq...@gmail.com


Javascript does not have optional arguments, dart does.

@DartBot
Copy link
Author

DartBot commented Feb 27, 2012

This comment was originally written by @seaneagan


JavaScript has optional arguments, what it doesn't have is required
arguments:

function greet(name, salutation) {
  // salutation is optional, so default if falsey
  salutation = salutation || "Hello";
  alert(salutation + ", " + name);
}

greet(); // alerts ", " and and no error since JS does not have required
arguments

@DartBot
Copy link
Author

DartBot commented Feb 27, 2012

This comment was originally written by amatiasq...@gmail.com


And that behaviour dart implements it as optional arguments.

So the new behaviour are the non-optional arguments, so we cannot compare them with Javascript.

If you want Javascript-like behaviour you can use optional arguments.

@DartBot
Copy link
Author

DartBot commented Feb 27, 2012

This comment was originally written by amatia...@gmail.com


I mean, whay do we have optional and non-optional arguments if you want to make they all optional?

@DartBot
Copy link
Author

DartBot commented Feb 27, 2012

This comment was originally written by @seaneagan


I'm not talking about making the passing of arguments optional, we already have that. I'm talking about making the declaration of trailing (required or optional) arguments optional when registering callbacks or overriding methods, and then merely ignoring any extra arguments passed at runtime instead of treating it as though the "call" operator is not supported, when in fact it is.

@DartBot
Copy link
Author

DartBot commented Feb 27, 2012

This comment was originally written by amatiasq...@gmail.com


I know you are not talking about passing of optional arguments, me neither, I'm talking about if I said that parameter is needed it's because you must recive it, otherwhise this could be a error, for example:

File.exists(() => print("LOL!"));

If the argument is not mandatory I should set it as optional so you are not forced to recive it.

@gbracha
Copy link
Contributor

gbracha commented Feb 28, 2012

Set owner to @gbracha.
Added Accepted label.

@DartBot
Copy link
Author

DartBot commented Apr 24, 2012

This comment was originally written by @seaneagan


@12:

I agree that in that particular case, it doesn't make sense to ignore the argument, but there are many cases where it does, and as I mentioned above you should still get a warning there.

@DartBot
Copy link
Author

DartBot commented Apr 24, 2012

This comment was originally written by micaela...@gmail.com


In this case I must set this arguments as optional, so you can ignore them.

void File.setContent(string value, void handler([Date modificationDate]));
void File.exists(void handler(bool result));

File.setContent("asdfasdfasfd", () => print("DONE"));
File.setContent("asdfasdfasfd", (modDate) => print("DONE"));
File.exists((result) => print("Callback"));
File.exists(() => print("Callback")); // ERROR

In the case of forEach it should be

void List.forEach(void handler(item, [int index, List self]);

[ 1, 2, 3 ].forEach((item, index, list) => ...);
[ 1, 2, 3 ].forEach((item, index) => ...);
[ 1, 2, 3 ].forEach((item) => ...);
[ 1, 2, 3 ].forEach(() => ...); // ERROR

@DartBot
Copy link
Author

DartBot commented Apr 24, 2012

This comment was originally written by @seaneagan


void forEach(void handler(item, [int index, List self]);

this implies that the List implementation may omit some arguments when calling your handler, which is not true.

[ 1, 2, 3 ].forEach((item, index, list) => ...);
[ 1, 2, 3 ].forEach((item, index) => ...);
[ 1, 2, 3 ].forEach((item) => ...);
[ 1, 2, 3 ].forEach(() => ...); // ERROR

I think they should all be static type warnings, but that the passed handlers should still get called, and just ignore the extra arguments being passed to them by the List implementation.

@DartBot
Copy link
Author

DartBot commented Apr 26, 2012

This comment was originally written by amatias...@gmail.com


Ok, I see what you mean, optional arguments have another meaning, but I don't see to allow ignore non-optional parameters to be better

@gbracha
Copy link
Contributor

gbracha commented May 24, 2012

Added Duplicate label.
Marked as being merged into #2706.

@DartBot DartBot added Type-Enhancement area-language Dart language related items (some items might be better tracked at github.com/dart-lang/language). closed-duplicate Closed in favor of an existing report labels May 24, 2012
@kevmoo kevmoo added type-enhancement A request for a change that isn't a bug and removed type-enhancement labels Mar 1, 2016
copybara-service bot pushed a commit that referenced this issue Jan 10, 2023
…_server, http_parser, logging, mockito, path, pool, shelf, source_map_stack_trace, sse, stream_channel, term_glyph, test, typed_data, watcher, web_socket_channel, webdev, webkit_inspection_protocol, yaml

Revisions updated by `dart tools/rev_sdk_deps.dart`.

cli_util (https://github.com/dart-lang/cli_util/compare/5a8e8ee..32bc077):
  32bc077  2023-01-09  Sam Rawlins  Migrate from no-implicit-casts to strict-casts (#73)

clock (https://github.com/dart-lang/clock/compare/6b8b7bf..65e8a13):
  65e8a13  2023-01-09  Sam Rawlins  Migrate from no-implicit-casts to strict-casts (#42)

csslib (https://github.com/dart-lang/csslib/compare/d776535..7054945):
  7054945  2023-01-09  Sam Rawlins  Migrate from no-implicit-casts to strict-casts (#157)

dartdoc (https://github.com/dart-lang/dartdoc/compare/29a1bbf..c4ab682):
  c4ab6824  2023-01-10  Sam Rawlins  Regenerate so latest analyzer is happy (#3293)

fixnum (https://github.com/dart-lang/fixnum/compare/714381c..71f0d4d):
  71f0d4d  2023-01-09  Sam Rawlins  Migrate from no-implicit-casts to strict-casts (#103)

glob (https://github.com/dart-lang/glob/compare/7adf833..4579281):
  4579281  2023-01-09  Sam Rawlins  Migrate from no-implicit-casts to strict-casts (#68)

http_multi_server (https://github.com/dart-lang/http_multi_server/compare/beb40a7..cce5080):
  cce5080  2023-01-09  Sam Rawlins  Migrate from no-implicit-casts to strict-casts (#48)

http_parser (https://github.com/dart-lang/http_parser/compare/16a4f34..6f73e4a):
  6f73e4a  2023-01-09  Sam Rawlins  Migrate from no-implicit-casts to strict-casts (#66)

logging (https://github.com/dart-lang/logging/compare/b525d5c..34ed68f):
  34ed68f  2023-01-09  Kevin Moore  Move to new analyzer language settings (#126)

mockito (https://github.com/dart-lang/mockito/compare/942dd03..9cc958a):
  9cc958a  2023-01-09  Sam Rawlins  Migrate from no-implicit-casts to strict-casts

path (https://github.com/dart-lang/path/compare/1299791..9768908):
  9768908  2023-01-09  Sam Rawlins  Migrate from no-implicit-casts to strict-casts (#133)

pool (https://github.com/dart-lang/pool/compare/713e631..ad4e2a7):
  ad4e2a7  2023-01-09  Sam Rawlins  Migrate from no-implicit-casts to strict-casts (#60)

shelf (https://github.com/dart-lang/shelf/compare/32e342d..a44e95e):
  a44e95e  2023-01-10  Kevin Moore  Fix doc comment references (#323)

source_map_stack_trace (https://github.com/dart-lang/source_map_stack_trace/compare/e5f9564..adea3e5):
  adea3e5  2023-01-09  Sam Rawlins  Migrate no-implicit-casts to strict-casts (#32)

sse (https://github.com/dart-lang/sse/compare/3c37edb..be426a2):
  be426a2  2023-01-09  Sam Rawlins  Migrate from no-implicit-casts to strict-casts (#74)

stream_channel (https://github.com/dart-lang/stream_channel/compare/0a7800a..3b99268):
  3b99268  2023-01-09  Sam Rawlins  Migrate from no-implicit-casts to strict-casts (#84)

term_glyph (https://github.com/dart-lang/term_glyph/compare/2bf4594..8cd9318):
  8cd9318  2023-01-09  Sam Rawlins  Migrate from no-implicit-casts to strict-casts (#31)

test (https://github.com/dart-lang/test/compare/3415089..932a652):
  932a652b  2023-01-09  Nate Bosch  Add a Map operator[] extension (#1830)
  1f2e963e  2023-01-09  Nate Bosch  Add Future.doesNotComplete condition (#1827)

typed_data (https://github.com/dart-lang/typed_data/compare/dbf81a7..9c209b9):
  9c209b9  2023-01-09  Sam Rawlins  Migrate no-implicit-casts to strict-casts (#58)

watcher (https://github.com/dart-lang/watcher/compare/2e0db71..3b49c7e):
  3b49c7e  2023-01-09  Sam Rawlins  Migrate from no-implicit-casts to strict-casts (#134)

web_socket_channel (https://github.com/dart-lang/web_socket_channel/compare/ebd0fe9..28d7b82):
  28d7b82  2023-01-10  Kevin Moore  Fix CI link in readme (#248)
  c6ce895  2023-01-09  Sam Rawlins  Update analysis_options.yaml (#247)

webdev (https://github.com/dart-lang/webdev/compare/49f97b8..094ee97):
  094ee97  2023-01-10  Anna Gringauze  Add back setExceptionPauseMode (#1871)
  2e65ddf  2023-01-10  Anna Gringauze  Prepare for dart 3.0 alpha breaking changes (#1880)
  2e2587a  2023-01-10  Elliott Brooks (she/her)  Add hotfix instructions to DWDS (#1876)
  fe39123  2023-01-10  Elliott Brooks (she/her)  Re-enable `reload_tests` (#1877)
  e71c0e3  2023-01-09  Anna Gringauze  Fix crash on processing devtools event (#1875)

webkit_inspection_protocol (https://github.com/google/webkit_inspection_protocol.dart/compare/ddb624c..15244ff):
  15244ff  2023-01-09  Kevin Moore  Add cron to CI (#97)

yaml (https://github.com/dart-lang/yaml/compare/02be51e..b2fce6c):
  b2fce6c  2023-01-10  Sam Rawlins  Migrate from no-implicit-casts to strict-casts (#134)

Change-Id: I4fb257fe7c697fab562f4d18e4ea50c5903b4cd8
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/278807
Auto-Submit: Devon Carew <devoncarew@google.com>
Reviewed-by: Samuel Rawlins <srawlins@google.com>
Commit-Queue: Samuel Rawlins <srawlins@google.com>
This issue was closed.
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). closed-duplicate Closed in favor of an existing report type-enhancement A request for a change that isn't a bug
Projects
None yet
Development

No branches or pull requests

4 participants