-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Allow passing extra unused parameters to a function #10811
Comments
Set owner to @gbracha. |
I think we should find a way to address this, but it won't be by allowing wholesale calls with the wrong arity. The current Dart rules do catch errors and allow for efficient execution as well. Ideas to address the problem without turning Dart into Javascript might involve variants of Function.apply() that tolerate excess arguments. Something like Smalltalk's valueWithEnoughArguments:. We'll see if dart2js can tolerate this sort of thing. Or maybe someone will have a better idea. Added Accepted label. |
Bob noted that you can define several supported function signature and use is checks to dispatch. typedef void OneArg(a); void foo(f) { |
I disagree that dropping extra arguments does not catch bugs. if x.startswith('foo', 1): I ported this as if (x.startsWith('foo', 1)) ... But Dart's String.startsWith is defined as follows: abstract bool startsWith(String other) Without detecting unwanted extra parameters I would not found the error until much much later. If a callback takes a number of values, perhaps group of values is better passed as an object that implements an interface. The interface can be extended without breaking existing clients. |
This comment was originally written by Misko.H...@gmail.com Some more thoughts. We could say that the extra arguments on object is an error but on stand alone function it is fine. x.startsWith('foo', 1) is an error because startsWith is a method on String fn(a); fn(1, 2); is not an error because it is a closure/function/callback. ================= Doing this: is not a solution but a hack. There are 100s of placets where framework needs to call back into dev code and many of them are performance intensive, it would be expensive both runtime, as well as developer code to expect that the framework would do this everywhere. ================= Calling with hashes is also not a good options since it would require that the writer of the callback would have to do extra work like this: list.forEach((element:null) => ...); To me this syntax implies that I can get called with no arguments, which is not the case. |
This comment was originally written by @seaneagan @sra: you could catch that bug via a compile time static warning, which could either be part of the language spec, or just an option in an IDE like "warn on extra arguments". |
FWIW, this would be very nice for futures- it's extremely common to see future callback functions naming parameters '_' when the param could just be omitted. Example (creates a fresh indexed DB database): |
If we keep seeing uses like Removed Type-Defect label. |
This comment was originally written by @seaneagan @9: or have var result = callback is _Nullary ? callback() : callback(arg); typedef _Nullary(); |
This comment was originally written by Misko.H...@gmail.com What you are describing puts the burden on the author of the method (user of the API/library). What the bug is requesting is that the burden is with the caller (the API/library developer). |
I don't think this is worth keeping open. There are workarounds for now, and I don't see this on the radar of any of our existing frameworks. |
This issue was originally filed by Misko.Hever...@gmail.com
myFn(a) {};
myFn(); // fails not enough arguments
myFn(1); // Works
myFn(1,2) // fails too many arguments. I would like this to pass.
The above rule helps to catch bugs, but it makes it hard to write framework code.
class Framework {
doSomething(fn) {
// Framework calls developer function with all of the data which the developer could
// possibly need. But the arguments are sorted by how likely it is that the developer
// actually needs them. Most developers need just the first one.
fn('veryCommon', 'somewhatCommon', 'rarelyUsed', 'almostNeverUsed');
}
}
var f = new Framework();
// To call the above we need to do something like this.
// Notice we don't need most of the arguments, but we still have to declare them.
f.doSomething((a, b, c, d) => a > 1);
// We really want to write this:
f.doSomething((a) => a > 1);
// If we could do above then it would also be nice to write this:
noop(){}
f.doSomething(noop);
noop() and identity() are two most useful functions in functional programing, but they are useless in dart, since the argument length is unlikely to match the caller.
Here is an example of functional library: https://github.com/documentcloud/underscore/blob/master/underscore.js
Notice how often _.identiy is referenced. The above code could not be ported to dart as is.
But there is another issue. As a framework developer I discover that I need to add one more argument to the callback.
So I change my framework from
fn('veryCommon', 'somewhatCommon', 'rarelyUsed', 'almostNeverUsed');
fn('veryCommon', 'somewhatCommon', 'rarelyUsed', 'almostNeverUsed', 'newArgument');
Now I have not broken anyone since I am just passing one more parameter to function and no one is referencing it, yet all of the users of my framework now can't upgrade to the new version since their code would fail. They all have to add a bogus parameter to all of their function calls, which no one will reference. This is an issue.
REQUEST:
calling a function with fewer parameters then function requires should be an error. // This catches bugs
calling a function with more parameters then function requires should be OK. // This does not catch bugs, only restricts
The text was updated successfully, but these errors were encountered: