Comma separated function output requests

1 view (last 30 days)
The comma separated list expression A{1:0} generally produces an empty result, e.g.,
A={1,2,3};
[A{1:0}]
ans = []
Therefore, I might expect both A and B below to result in empty cells, but A does not. Why is this? Is it documented somewhere?
clear A B
S=struct('type','()','subs',{{3}});
x=10:10:50;
[A{1:0}]=subsref(x,S)
A = 1×1 cell array
{[30]}
[B{1:0}]=deal(x(3))
B = 0×0 empty cell array

Accepted Answer

Matt J
Matt J on 5 May 2021
Edited: Matt J on 5 May 2021
I assume the reason for the behavior is so that wrapper functions can have the same default outputs as the functions they are wrapping. For example, in the code below, nargout=0 when myWrapper(3) is called. So, if the comma separated list assignment had resulted in varargout={}, then myWrapper would not have returned a default output, as sin() does on its own. This is surely a good thing, however, I still wonder if/where this is all documented.
sin(3)
ans = 0.1411
myWrapper(3)
ans = 0.1411
function varargout=myWrapper(x)
[varargout{1:nargout}]=sin(x);
end
  2 Comments
Stephen23
Stephen23 on 5 May 2021
Edited: Stephen23 on 5 May 2021
It is a little bit quirky: the default ans counts as zero outputs:
myWrapper(3)
ans = 0
ans = 0.1411
Does the parser simply assume that all "zero output" situations are equivalent to this?
function varargout=myWrapper(x)
[varargout{1:nargout}]=sin(x);
nargout
end
Matt J
Matt J on 14 May 2021
Edited: Matt J on 14 May 2021
Bottom line - it looks to me as though [varargout{1:0}]=func() will return non-empty if and only if func() has a non-empty default output. I haven't been able to find where this is documented, but it seems to make sense in light of the conviences it brings to function wrapping.

Sign in to comment.

More Answers (2)

Stephen23
Stephen23 on 5 May 2021
Edited: Stephen23 on 5 May 2021
Is this documented?
[A{1:2}] = myone(1,2,3,4) % okay
ans = 4
ans = 2
A = 1×2 cell array
{[1]} {[2]}
[B{1:1}] = myone(1,2,3,4) % okay
ans = 4
ans = 1
B = 1×1 cell array
{[1]}
[C{1:0}] = myone(1,2,3,4) % NARGOUT==0 ... but one output is allocated.
ans = 4
ans = 0
C = 1×1 cell array
{[1]}
[D{1:0}] = myone(1) % NARGOUT==0 ... but one output is allocated.
ans = 1
ans = 0
D = 1×1 cell array
{[1]}
[E{1:0}] = myone() % NARGOUT==0 ... and no outputs allocated (correct).
ans = 0
ans = 0
E = 0×0 empty cell array
The different behaviors of different functions seems to depend on whether the function defines output arguments internally regardless of how many outputs are actually requested (as in myone above) vs. functions that only define exactly the number of outputs that are actually requested at the output (i.e. that use nargout to specify the outputs, as in mytwo below):
[H{1:2}] = mytwo(1,2,3,4) % okay
ans = 4
ans = 2
H = 1×2 cell array
{[1]} {[2]}
[I{1:1}] = mytwo(1,2,3,4) % okay
ans = 4
ans = 1
I = 1×1 cell array
{[1]}
[J{1:0}] = mytwo(1,2,3,4) % okay
ans = 4
ans = 0
J = 0×0 empty cell array
[K{1:0}] = mytwo(1) % okay
ans = 1
ans = 0
K = 0×0 empty cell array
[L{1:0}] = mytwo() % okay
ans = 0
ans = 0
L = 0×0 empty cell array
function varargout = myone(varargin)
% Defines as many outputs as are provided as inputs.
varargout = varargin;
nargin
nargout
end
function varargout = mytwo(varargin)
% Defines only as many outputs as are requested.
varargout = varargin(1:nargout);
nargin
nargout
end

Jan
Jan on 5 May 2021
Why do you expect A to be the empty cell? The right hanbd side is the scalar 30:
S = struct('type', '()', 'subs', {{3}});
x = 10:10:50;
subsref(x, S)
ans = 30
Then:
[A{1:0}] = 30
A = 1×1 cell array
{[30]}
assignes 30 to the elements of the cell array A, such that it is expanded. That [A{1:0}] on the right hand side is treated as empty is another point. You cannot mix the interpretations on the right and left side.
  1 Comment
Matt J
Matt J on 5 May 2021
Edited: Matt J on 5 May 2021
The right hanbd side is the scalar 30:
The right hand side doesn't simply have a value, though. It is a function call, and what a function call returns depends on how many output arguments are requested. You would think that [A{1:0}] would indicate to Matlab that zero outputs are requested, like in the following case.
h=figure('Visible','off');
clear A
[A{1:1}]=plot(1:5)
A = 1×1 cell array
{1×1 Line}
clear A
[A{1:0}]=plot(1:5)
A = 0×0 empty cell array

Sign in to comment.

Categories

Find more on Argument Definitions in Help Center and File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!