Sdk: Add tuple or out parameters

Created on 11 Nov 2011  路  9Comments  路  Source: dart-lang/sdk

_This issue was originally filed by domi...@google.com_


I have methods that I would like to return multiple values from. The two ways I could do this would be to return a tuple, or if output parameters were available I could use those.

I'd prefer output parameters to make it easier to optimize away copies of object references.

For example

class Sphere {
  bool Intersect(Ray ray, out double distance);
}

main {
  Ray ray;
  double distance;
  if (Intersect(ray, out distance)) {
    ....
  }
}

or

class Sphere {
  tuple<bool, double> Intersect(Ray ray);
}

main {
  Ray ray;
  tuple<bool, double> result = Intersect(ray);
  if (result[0])
    double distance = result[1];
    ....
  }
}
area-language core-m customer-fuchsia type-enhancement

Most helpful comment

Re-opening this for consideration.

All 9 comments

_This comment was originally written by [email protected]_


_Removed Type-Defect label._
_Added Type-Enhancement, Area-Language, Triaged labels._

There are some other possibilities for output parameters, using features already in the language. The closest to "out parameters" just uses closures, passing a setter of distance:
double distance
if intersect(ray, (out){distance=out;}) {
 ... distance ...
}

The closure and variable closed over can be in a higher scope, and outside loops, if avoiding object creation is important:

double distance;
Function distance_out(out) {distance = out;}

while (looping) {
    foo(input, distance_out);
    ... distance ...
}

Or you can pass a handle to a double:
var distance = new Out<double>;
if (intersect(ray, distance)) {
 ... distance.val ... distance.val ..
}
You could even write distance = distance.val after the function call.

Alternatively, pass in the calculation that needs multiple values as a callback:

sphere.intersect(Ray ray, (Bool intersects, Double distance) {
   if (intersects && distance > 1) {
     myLocalQueue.add(distance);
     any other calculations ...
   });

Map or list literals can be passed back. If you want to avoid object creation, you can use a static object, or pass one in.
var result = intersect(ray);
if (result[0]) {
 ... result[1];
}

var result = intersect(ray);
if (result["intersects"]) {
 ... result["distance"];
}

var out = new List(2)
if intersect(ray, out) {
  ... out[0] ... out[1] ...
}

_This comment was originally written by domi...@google.com_


Thanks for the comprehensive feedback. This bug can probably be closed.

It would be interesting to see a blogpost/article on this as there are so many options and I imagine each has pros and cons.

I'm closing this per the submitter's request. I will note that literal lists make it quite easy to return multiple values. Or passing in mutable list or map. I don't think we'll ever add out parameters.


_Added WontFix label._

_This comment was originally written by mtu...@getccna.ru_


I propose reopening this issue. I think all proposed methods have significant disadvantages:

  1. Passing setter method is overly complicated. I think the idea of Dart is to propose structured solutions to common patterns (as opposite to unstructured way to do it in JavaScript).
  2. Returning Map or list doesn't specify the dimensions.

I think there should be a way to pass the tuples of certain dimensions out of the function and ability to destructure them.

For example:

[User, bool] createOrUpdate(String name, id int) {
...
}

User user, bool created = createOrUpdate("admin", 2);

What do you think?

This makes me (and I bet many others) very sad - tuples are one of the most useful sugar present in Python, Ruby, Go, etc.
One super useful case is boolean that also retuns an error code/message on error - go have pretty nice pattern, in ruby I could use:

res, msg = isConditionValid(foo);
print msg if !res

in Dart I need specialized class for each case. There are at least two widely used patterns used as a workaround:
1) output parameters - just pass mutable class (like list of error message) to param
2) returning null for ok, string with message otherwise.

I bet there is way more code that would be much improved if this was allowed.

Re-opening this for consideration.

Fuchsia would very much like this feature.

The new language repository is tracking this feature at https://github.com/dart-lang/language/issues/68; presently 144 up-votes and a more recent and lively discussion; I proposed we close this in favor of that.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

DartBot picture DartBot  路  3Comments

sgrekhov picture sgrekhov  路  3Comments

55555Mohit55555 picture 55555Mohit55555  路  3Comments

nex3 picture nex3  路  3Comments

DartBot picture DartBot  路  3Comments