Comments (49)
6 years and still no var args? 😀
from language.
Its almost essential, since dart doesn't inherit constructors.
Extending a class requires one to look up the full constructor of parent.
For me, that's just too much typing.
Like, this
class CustomPageRoute<T> extends MaterialPageRoute<T> {
CustomPageRoute(*args, **kwargs) : super(*args, **kwargs);
}
compared to this
class CustomPageRoute<T> extends MaterialPageRoute<T> {
CustomPageRoute({
@required builder,
RouteSettings settings,
maintainState: true,
bool fullscreenDialog: false,
}): super(
builder: builder,
settings: settings,
maintainState: maintainState,
fullscreenDialog: fullscreenDialog,
);
}
I get the reasons behind not inheriting constructors. Explicit is better than implicit. But *args, **kwargs is a great way to prevent excessive typing.
from language.
Waiting for this.
from language.
We really need this. and dart is falling behind many other laguages. Java, Javascript, Python, C# all these langages have varargs and dart doesn't. I know that dart is pretty new, laguage but It would be really cool if we had this.
I hope that someona will finally implement this.
from language.
issue opened on 23 Jan 2014
from language.
9 years and counting...
In my case, I need to pass varargs in JS Interop function. It expects varargs instead of List.
from language.
I'm not sure this will ever be implemented, but with Records someone could make a typeDef vararg = record and inline (())
into ()
from language.
This comment was originally written by [email protected]
Yah, I agree that supporting varargs just for the sake of porting python code is not a good argument.
However, I would say that supporting varargs for the sake of having a clean, flexible, readable langauge is a good argument.
We can get around the lack of vararg support using tricks like the one described in Yu Asakusa's blog post. (Nice, by the way!). But to me built-in vararg support would still be nice to have.
At this point I suppose the decision on this rests in the hands of the Dart committee (or however these things get decided? Is there a benevolent dart-tator for life?)
from language.
9 years and counting...
In my case, I need to pass varargs in JS Interop function. It expects varargs instead of List.
BTW, you could try fixed arguments instead of List
: dart-lang/sdk#38578 (comment)
Or @staticInterop
: flutter/flutter#97357 (comment) and https://github.com/dart-lang/site-www/pull/4528/files
Or comment on dart-lang/sdk#35084
from language.
Supporting variable numbers of arguments would improve console logging methods in dart:html and for Flutter.
from language.
Variadic arguments are going to be very helpful, and make Prototyping as well as Writing code Easier.
If both C# and JS have them then that means that Dart which sits in between is starting to fall behind
from language.
For those saying they need this feature, can you elaborate on why using a List
won't work? In cases where all the arguments are of the same type, you can use List<int>
or another type, and when they're not, you'd use List<Object>
or just List
. Either way, you lose type safety, so one isn't worse than the other.
from language.
This comment was originally written by @seaneagan
Strawman:
varPositionals(required, [optional, String ...rest]) {
assert(rest is List<String>);
}
varNamed (required, {optional, String ...rest}) {
assert(rest is Map<Symbol, String>);
}
(...rest is used by ES6)
from language.
Any news on this? I'm working on a "ramda like" library and the lack of varargs is really limiting :/
from language.
For those saying they need this feature, can you elaborate on why using a
List
won't work? In cases where all the arguments are of the same type, you can useList<int>
or another type, and when they're not, you'd useList<Object>
or justList
. Either way, you lose type safety, so one isn't worse than the other.
It's mostly about code quality.
Very very simple example:
final a = 42;
final b = 90;
void argsFn(...int args) {};
void arrayFn(List<int> array) {};
main() {
argsFn(a, b);
arrayFn(<int>[a, b]);
};
I would choose argsFn
all time...
Also don't forget SQL has variadic parameters and using array won't work for the SQL code generators where args needed
because arrays and args are fundamentally different things. So it's literally necessity after all.
Edit: Workarounds are always possible but I'm and most of you as I guess not big fan of language of workarounds...
from language.
If dart ever does implement varargs, it would be nice if it supported using the equivalent of collection if
and collection for
at the call site, otherwise it would seem less expressive than just accepting a collection literal.
void argsFn(...int args) {}
void main() {
argsFn(
for (int i = 0; i < 10; i++)
if (i % 2 == 0) i,
);
}
Additionally, I think it would be nice if you weren't limited to only collecting the arguments into a List<A>
. Why not allow varargs to collect to a Set<A>
or Map<A, B>
or Iterable<A>
or even custom user defined data structures?
void varArgsList(...List<int> args) {}
void varArgsSet(...Set<int> args) {}
void varArgsMap(...Map<int, int> args) {}
void varArgsIterable(...Iterable<int> args) {}
void varArgsCustom(...Custom<int> args) {}
A rough idea for how this might work, is that perhaps classes with an .of
constructor can be used with varargs. If the constructor accepts an Iterable<A>
like with List<A>.of
and Set<A>.of
then the arguments are collected into an Iterable<A>
and passed to the .of
constructor. If the .of
constructor accepts a Map<A. B>
instead, like with Map<A, B>.of
, then at the callsite you would pass in the varargs as key/value pairs.
Iterable
itself, does not have an .of
constructor, but perhaps a special case could be made for the Iterable
type, which would ideally collect the arguments as a lazy iterable (like a sync*
function).
Basically this:
void varArgsList(...List<int> args) {}
void varArgsSet(...Set<int> args) {}
void varArgsMap(...Map<int, int> args) {}
void varArgsIterable(...Iterable<int> args) {}
void varArgsCustom(...Custom<int> args) {}
void main() {
varArgsList(for (int i = 0; i < 10; i++) if (i % 2 == 0) i);
varArgsSet(for (int i = 0; i < 10; i++) if (i % 2 == 0) i);
varArgsMap(for (int i = 0; i < 10; i++) if (i % 2 == 0) i: i);
varArgsIterable(for (int i = 0; i < 10; i++) if (i % 2 == 0) i);
varArgsCustom(for (int i = 0; i < 10; i++) if (i % 2 == 0) i);
}
Could be syntactic sugar for this:
void varArgsList(List<int> args) {}
void varArgsSet(Set<int> args) {}
void varArgsMap(Map<int, int> args) {}
void varArgsIterable(Iterable<int> args) {}
void varArgsCustom(Custom<int> args) {}
void main() {
varArgsList(List<int>.of(() sync* {
for (int i = 0; i < 10; i++) if (i % 2 == 0) yield i;
}()));
varArgsSet(Set<int>.of(() sync* {
for (int i = 0; i < 10; i++) if (i % 2 == 0) yield i;
}()));
varArgsMap(Map<int, int>.of({
for (int i = 0; i < 10; i++)
if (i % 2 == 0) i: i,
}));
varArgsIterable(() sync* {
for (int i = 0; i < 10; i++) if (i % 2 == 0) yield i;
}());
varArgsCustom(Custom<int>.of(() sync* {
for (int i = 0; i < 10; i++) if (i % 2 == 0) yield i;
}()));
}
from language.
As for suggestion 1, it's pretty much a given that if dart adds varargs, it will support spreads
...
at the call site. So why notfor
andif
as well?
Yeah, if we do varargs, I certainly want to push to support all three of those.
from language.
On this 1st April, 8 years after the issue open, nothing ...
Maybe a fool joke on this day ?
from language.
this could be also used with js_bindings to have nice interoped variadic methods with JS
from language.
Hi, I just discovered a use case where I think using arguments unpacking to be the most elegant solution. However, I'm new to Dart so I might be wrong.
I have a function in Dart which has some optional arguments
List<num> arange(num start, [num end, num step = 1]) {
if (end == null) {
end = start;
start = 0;
}
int length = (end - start) ~/ step;
return List<num>.generate(length, (i) => start + i * step);
}
I want to call this function from Javascript, so I wrote my main as this:
import 'dart:js';
void main() {
context['arange'] = arange;
}
However, when called from Javascript, this returns a Dart object, while what I want was a Javascript array. So the solution would be to use JsObject.jsify to convert the Dart list into a Javascript array.
If argument unpacking was available the implementation would be a simple one-liner edit using anonymous functions:
context['arange'] = (varargs) => JsObject.jsify(arange(*varargs));
Instead, without it, I think that I would need to write another function with the same signature as the function I want to convert, for each function I want to expose in this way.
JsObject arangeJS(num start, [num end, num step = 1]) {
return JsObject.jsify(arange(start, end, step));
}
void main() {
context['arange'] = arangeJS;
}
I might be missing something, as I'm new to the language, but this is the best I could come out with. Please feel free to comment or point any mistake.
Full main.dart
:
import 'dart:js';
void main() {
context['arange'] = arangeJS;
}
List<num> arange(num start, [num end, num step = 1]) {
if (end == null) {
end = start;
start = 0;
}
int length = (end - start) ~/ step;
return List<num>.generate(length, (i) => start + i * step);
}
JsObject arangeJS(num start, [num end, num step = 1]) {
return JsObject.jsify(arange(start, end, step));
}
Compiled with dart2js -O2 -o arange.js main.dart --packages=.packages
.
from language.
I am also looking forward to this. Made some memoization methods and had to write one method for each arg count, up to 4. Really cumbersome and breaks DRY principles...
from language.
This would be really useful for utility functions which need to be versatile.
For example:
Function debounce(Function func, int milliseconds) {
Timer timer;
return (arg) {
if (timer != null) {
timer.cancel();
}
timer = Timer(Duration(milliseconds: milliseconds), () => func(arg));
};
}
Which unfortunately can be used only with fixed arguments.
As @seaneagan pointed out, something similar to rest parameters in JavaScript would be very useful:
Function debounce(Function func, int milliseconds) {
Timer timer;
return (...arg) {
if (timer != null) {
timer.cancel();
}
timer = Timer(Duration(milliseconds: milliseconds), () => func(...arg));
};
}
from language.
To add an example of usefulness of this : There was a request on to add the index to list.forEach in the dart language. Unfortunately it couldn't be done because dart doesn't allow to pass more arguments than the function can take in.
Imo this is kinda related to varargs where you should be able to pass more arguments than you need to, to a function.
from language.
@mmcdon20 too complicated and why not T ...name
:
int sum(int ...args);
int sumFn(Iterable<int> args);
also there are other issues for maps and objects.
from language.
Removed Type-Defect label.
Added Type-Enhancement, Area-Language, Triaged labels.
from language.
This comment was originally written by [email protected]
+1 for the Strawman in #2. I like the '...' syntax, because it (1) semantically jibes for me, and (2) it echoes coffeescript varargs syntax, which folks are already familiar with.
from language.
This comment was originally written by @zoechi
As it's just another sytax for a parameter of type List, why not just stay with List?
from language.
This comment was originally written by [email protected]
I'm not sure that using a 'List' parameter has the effect I'm looking for.
If I used a 'List' parameter, wouldn't I have to explicitly put the arguments into a list when I call the function?
For example, if I have:
varPositionals (required, [optional, List theRest])
wouldn't I need to call this like:
varPositionals('required', 'optional', ['a', 'b', 'c'])
?
I'm looking instead for something more like python's behavior e.g. I want to call the function like this:
varPositionals('required', 'optional', 'a', 'b', 'c')
and have 'a', 'b', and 'c' get aggregated into the variable 'theRest'.
I hope that this helps to clarify.
from language.
This comment was originally written by @zoechi
I understand your request but I'm not sure if special syntax is worth this little (IMHO) gain.
from language.
This comment was originally written by [email protected]
This would make porting python code to dart much cleaner.
As a user of Dart, I personally do not find it important to make it easy to port code from Python to Dart, or from any language for that matter (perhaps except for JavaScript). After all, Dart and Python are different languages.
I am not saying that supporting variadic functions in Dart is useless. But “Python supports them, so Dart should also support them to make porting easy” is a weak argument.
By the way, it is possible to emulate variadic functions in Dart by a dirty hack in case you need them for some reason. See my post at http://yuasakusa.github.io/dart/2014/01/23/dart-variadic.html.
from language.
Set owner to @gbracha.
Added Accepted label.
from language.
I see that task has been assigned to someone... but it's been a year since the last activity... my question is... how much longer we have to wait for this syntax?
from language.
Someone will need to create a dart enhancement proposal for it first.
from language.
Is it possible that this feature will be included into the Dart 2.0?
from language.
No, it is not planned (or started)
from language.
@devxpy There were discussions about improving constructors, but as distinct topic, but most improvements are planned after Dart 2. Dart 2 was mostly about moving to common frontend (CFE) and sound type system.
from language.
Question to the original reporters of this issue:
Given that a variable number of arguments of the same type – ex. List<String> *args
Python style or List<String> ...args
JS style – wouldn't be too useful, how do you imagine expressing their types? List<Object> ...args
on the other hand forces the function to forego static typing.
What is the prior art on statically typed varargs?
from language.
I'm not sure if varags would solve the forwarding case or not. For another discussion around wrapping functions of unknown arity and argument type see #157
from language.
Please add this to Dart.
see: https://stackoverflow.com/questions/3941517/converting-list-to-args-when-calling-function
from language.
I have some code like the following.
import 'dart:async';
typedef throttle_debounce_callback = dynamic Function(List<dynamic>? positionalArguments,
[Map<Symbol, dynamic>? namedArguments]);
throttle_debounce_callback throttle(Function callback, int interval) {
var enableCall = true;
return (List<dynamic>? positionalArguments, [Map<Symbol, dynamic>? namedArguments]) {
if (!enableCall) return;
enableCall = false;
Function.apply(callback, positionalArguments, namedArguments);
Future.delayed(Duration(milliseconds: interval), () => enableCall = true);
};
}
throttle_debounce_callback debounce(Function callback, int interval) {
Timer? debounceTimeoutId;
return (List<dynamic>? positionalArguments, [Map<Symbol, dynamic>? namedArguments]) {
debounceTimeoutId?.cancel();
debounceTimeoutId =
Timer(Duration(milliseconds: interval), () => Function.apply(callback, positionalArguments, namedArguments));
};
}
However the shortcoming is that I need to pass positional arguments as a list, instead of variable length arguments. I hope I can write code like this.
import 'dart:async';
typedef throttle_debounce_callback = dynamic Function([dynamic ...positionalArguments],
[Map<Symbol, dynamic>? namedArguments]);
throttle_debounce_callback throttle(Function callback, int interval) {
var enableCall = true;
return ([dynamic ...positionalArguments], [Map<Symbol, dynamic>? namedArguments]) {
if (!enableCall) return;
enableCall = false;
Function.apply(callback, positionalArguments, namedArguments);
Future.delayed(Duration(milliseconds: interval), () => enableCall = true);
};
}
throttle_debounce_callback debounce(Function callback, int interval) {
Timer? debounceTimeoutId;
return ([dynamic ...positionalArguments], [Map<Symbol, dynamic>? namedArguments]) {
debounceTimeoutId?.cancel();
debounceTimeoutId =
Timer(Duration(milliseconds: interval), () => Function.apply(callback, positionalArguments, namedArguments));
};
}
This would be more user-friendly.
Now the test code need to be
import 'dart:async';
import 'package:simple_throttle_debounce/simple_throttle_debounce.dart';
void main() async {
var limit = 100;
var tick = 0;
var interval = 1000;
var simpleTask = (tick) => print('tick: $tick');
var throttleSimpleTask = throttle(simpleTask, interval);
var debounceSimpleTask = debounce(simpleTask, interval);
while (true) {
print(tick);
throttleSimpleTask([tick]);
// debounceSimpleTask([tick]);
await Future.delayed(Duration(milliseconds: 100), () => tick++);
if (tick > limit) break;
}
}
from language.
Good point cedvdb, then non-vararg functions could also have static type safety with spread arguments as long as all the rest of the parameters are optional and the same type as the list
Also, the hash functions of quiver could benefit from varags, then it could be reduced to a single hash
function instead of hash2
, hash3
, hash4
, and hashObjects
if you have more - I'd like to suggest that a list of the same type as the varags could also be passed to the function and act like a positional argument, that way you don't need to explicitly spread it just to become a list within the function again (possible performance improvement? wouldn't create a new list, whereas spread args i'd imagine creates a new list?)
from language.
from language.
I think multiple assignment is also related to this feature. Both args
and multiple assignment
can reduce significantly amount of code written in many cases.
from language.
Is a dart way to use different method for collections/arguments, like add/addAll, build/buildAll, ....
Easy way to implement this is transforming argsFn(varargs int args)
to argsFn(List<int> args)
and replace calls with list in CFE.
from language.
final a = 42; final b = 90; void argsFn(...int args) {}; void arrayFn(List<int> array) {}; main() { argsFn(a, b); arrayFn(<int>[a, b]); };
Except if a
and b
are known to be ints
, which they have to be in order to be passed to argsFn
, then you don't need to include <int>
around the brackets, so the code ends up being just as short:
final a = 42;
final b = 90;
void fn1(...int args) {}
void fn2(List<int> array) {}
void main() {
fn2(a, b);
fn2([a, b]);
}
As for code generators, well those can be considered workarounds in and of themselves, although I don't use them as much so I can't really sympathize. To clarify, I do think this would be a neat feature (if all the var-args were of the same type and collapsed to a List<E>
), I was just trying to gauge how high of a priority this should be when there are other high-profile issues going around.
from language.
too complicated
@ykmnkmi which part is too complicated?
To summarize, I suggested 2 things:
- varargs should allow
if
andfor
at the call site. - You should be able to pick a data structure to collect the arguments into.
If you think about it, dart already has varargs, its just limited to collection literals. And collection literals support the above features.
As for suggestion 1, it's pretty much a given that if dart adds varargs, it will support spreads ...
at the call site. So why not for
and if
as well?
As for suggestion 2, I admit I expected this suggestion would be a bit more controversial. I can't think of any other programming language that allows you to do this, so it would be going against the norm. But it would add some more flexibility compared to only collecting the arguments as a List<T>
like other programming languages do.
and why not
T ...name
I don't have a preference between T ...name
and ...T name
.
from language.
Any progress on this? It is blocking dart-lang/sdk#38578
from language.
No progress yet. We're mostly focused on static metaprogramming, views, and pattern matching.
from language.
9 years and counting...
In my case, I need to pass varargs in JS Interop function. It expects varargs instead of List.
dart:ffi: Support variadic C functions is closed
I suppose dart:ffi
or dart2wasm
have more priority
from language.
Related Issues (20)
- Consider creating `macros` repo; how to use it for `dart_model` HOT 7
- Allow a library prefix (not an import prefix) to support access to shadowed names HOT 6
- More flexibility for the `base` keyword HOT 3
- Next steps for `dart_model` prototype integration HOT 16
- Static type metadata guided shorthands and features HOT 4
- No macro.TypeDeclarationImpl for `dynamic` HOT 5
- Adoption of functional programming in the Dart language HOT 2
- Enhancing `library` and `part of` Declarations in Dart HOT 1
- Create the type `Monad` HOT 4
- Allow `import` and `part` to have wildcard path to import every lib in specific directory HOT 1
- Adding conditional imports/parts with macros. HOT 2
- Consider changing the context for the operand of `throw` to `Object`. HOT 4
- Allow statically known class fields to be used in switch statements HOT 4
- could support static extension? HOT 2
- Macro - Augment class with generic HOT 7
- Macro annotation information in yaml files next steps HOT 3
- Network paths don't work anymore with version 3.4.0 HOT 2
- "Merge to source" for macros that only need Phase 3 HOT 26
- Follow up on "spawn isolate from kernel blob" implementation
- Allow pattern `case` conditions in `while` statements. HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from language.