Open tatumizer opened 4 years ago
I would love if noSuchMethod
's Invocation
had a tuple for the arguments, and not a pre-deconstructed list/map.
You'd need to know the structure in order to deconstruct the arguments, but you might be able to pass them on to something else in a dynamic call.
Allowing a function to access its own argument tuple as a tuple seems very reasonable. If you see all functions as unary functions from a tuple type to the result type, and argument lists just being implicit pattern matches on the argument tuple, then that pattern match should also be able to name the entire tuple.
If it's OK, @tatumizer, I'll leave this open. We don't currently have plans to support this, but I think it's a reasonable and useful extension of our plans around tuples and pattern matching.
This looks extremely useful, especially if we can extract the record type as an "arguments type" for the sake of <Fn extends Function(Args), Args extends Record>
which would be useful for passing along call(...Args args) => _fn(...args)
it could also open the door for more "pass along" type operations, like when implementing a type, just as an example;
class Foo {
void func({int? i, String? str}) {}
}
class Wrapper implements Foo {
const Wrapper(this.foo);
final Foo _inner;
void func(.../*({int? i, String? str})*/ args) => _inner.func(...args);
}
let alone wrappers as mentioned:
// Could be in a class with the function stored, and the `call(...Args)` function mapping to it
Fn wrap<Return, Args extends Record, Fn extends Return Function(...Args)>(Fn cb) {
// this could be debouncing, saving state, caching, timing, transforming errors, anything at all.
return (...Args args) => doSomeWork(() => fn(...args));
}
// could even choose to modify the return type
// this becomes much cleaner with type matching: (strawman)
Fn wrap<Fn extends <Return> Function(...<Args /*extends Record*/>)>(Fn cb) {...}
As it is I'm forced to either take records (not nice for call sites, and loses default and optional args) or take a class (not a particularly great API for what's supposed to be a "normal" function)
Could be super useful for storing arguments for later use too, when we as the tool-maker don't care about the actual shape or type of that data
I think its a shame that this doesn't have much activity.
The issue of forwarding was raised on multiple occasions during dart history. The tuple of actual arguments can help, it's just a matter of finding a good syntax. The first thing that comes to mind is
$arguments
:There's a related issue: how to declare tuple type based on the argument list of existing function? I can't find any prior example of anything like that in dart. One obvious variant is:
which I don't like because it works (kinda) only in the context of typedef, but is no good as a type expression - e.g. this declaration is weird:
Another variant can be
but this is too fancy.
EDIT: If dart introduces compile-time macros like
#nameOf(foo.bar)
then the natural idea would be to define yet another macro for the function argument tuples, with a more articulate syntaxor something to that effect