Multiple values - BenoitKnecht/julia GitHub Wiki

Design

Supporting multiple values is a classic area of difficulty in programming language design and implementation. On the design side, the problem is that most things you want to compute are naturally just one value, and yet occasionally you *really* need to return two values (or maybe a few more). On the implementation side, the feature is complex and slow.

In scientific computing there are some additional requirements. Here's what I think you need:

  • The ability to return >1 value
  • The ability to catch those values with concise syntax
  • The ability to tell a function how many values you need, so it can avoid unnecessary work
The third requirement is the unusual one, but necessary because (for example) sometimes you need a sorted vector and the permutation, and sometimes you just need the sorted vector and computing the permutation would be a waste.

In julia, functions can return multiple values by returning a tuple. You get the values with the syntax:

(a, b) = f(x)

which is just tuple destructuring. It generalizes to allow things like

(x, y) = (y, x)

The number of left-hand-side values is determined statically through the syntax; it cannot vary at run time. To handle the last requirement, if the right-hand-side is a function call, the compiler inserts a keyword argument specifying the number of requested values:

(a, b) = f(x, nargout=2)

If a function wants to be able to return multiple values, it must accept this keyword argument. I haven't decided whether it will be up to the function author to write this explicitly, or if the compiler can insert it automatically somehow.

Calls involving keywords will be slower. You have to weigh this against the cost of computing the extra values. If computing the extra values is so expensive that you need to know nargout, then the extra cost of the call is negligible.

This is also easier to interface to other languages, because if a julia function returns multiple values you get it as a single tuple object.

If you want to delegate to another function preserving full call information, in matlab you do this:

varargout=cell(1,nargout);
[varargout{:}]=f(varargin{:});
return;

in julia you would do this:

return f(args..., nargout=nargout)

Issues:

  • The tuple lengths on the left and right must match exactly
  • What if you want to unconditionally return, say, 2 values and not pay the price of keywords? Tough luck?
  • You have to follow the above pattern to "delegate"
  • If you ask for 1 value as in "y = f(x)" no nargout is passed, which is not totally consistent (although within f nargout would have a default value of 1 hopefully)
  • If you ask for 1 value and the function returns >1 value anyway, you get either a tuple or an error, which might not be what you expect (i.e. i haven't specified any automatic dropping of values)
⚠️ **GitHub.com Fallback** ⚠️