Can a function known whether/which specific output is ignored (tilde operator)?
35 views (last 30 days)
Show older comments
A function can know the number of requested outputs via nargout.
But can it know if a specific output is replaced with tilde operator (~) ?
[x,~,z] = foo();
function [a,b,c] = foo()
% how to know that the second output is not needed?
end
26 Comments
Accepted Answer
Adam Danz
on 15 Sep 2020
Edited: Adam Danz
on 16 Sep 2020
"Can a function known whether/which specific output is ignored ?"
No. nargout tells you the number of output arguments specified in the caller but it counts outputs suppressed with a tilde (~). nargout(fun) tells you the number of ouputs a specific function has to offer but that tells you nothing about the caller.
What are the alternatives?
1. Pass an input to the function that specifies which outputs you're requesting. The tricky part is to remember to change that input value if a different set of outputs is requested.
You can also try the new and improved (vs.2.0.0) detectOutputSuppression() from the file exchange. It reads the caller line and parses the outputs to determine if any are suppressed.
Example
The main() function calls myFunc() and suppresses the 2nd and 3rd outputs.
function main()
[mst(1), ~, ~, data] = myFunc();
function [a, b, c, d] = myFunc()
a = 1; b = 2; c = 3; d = 4;
isTilde = detectOutputSuppression(nargout);
Result: isTilde = [0 1 1 0].
Supported syntaxes
- [a,~,~,d] = myFunc();
- a = myFunc();
- [a(1),a(2),~] = myFunc();
- [~,~,c(1:20),~] = myFunc();
- [~,b{3}] = myFunc();
- [~,b{3,1,5}] = myFunc();
- [~,~,~,g{1}{2}{4}(1)] = myFunc();
- q=cell(1); [~,q{:}] = myFunc(); % because q is 1x1.
- T=table(); [T.a,~] = myFunc();
- [j,u,n,k]; [~,~,~,~] = myFunc(); [j,u,n,k]
- [j,u,n,k], [~,~,~,~] = myFunc(), [j,u,n,k]
- S=struct; [S.x,~,S.t(4)] = myFunc();
- [v.a, v.b{1}, v.c(2,2), ~] = myFunc();
- myFunc + 1;
- y = [1, myFunc(), 1];
- assert(~isempty(myFunc()))
- [a,b,~,~] = myFunc(...
- inputs); %split in multiple lines after function name
- and more....
Syntaxes not supported
An error message is thrown when these syntaxes are detected.
- Outputs not separated by commas: [a b c] = myFunc()
- When myFunc() is not called from within an m-file or wasn't the most recent command called from the command window.
- When myFunc() is called in debug mode but isn't the line currently paused or executed by MATLAB.
- Output assignment to comma separated lists: x=cell(1,5); [x{:}] = myFunc();
- Caller line is split into multiple lines before the inputs (a split after the function name is OK).
- When myFunc() is wrapped in an anonymous function: f = @myFunc; f()
- When the parser matches more than one [...]=myFunc per line of code.
2 Comments
Stephen23
on 1 Dec 2022
"Supported syntaxes"
are not robust if they contain any comma-separated list (not just ones from a cell array, as Adam Danz wrote), In fact this also includes structures and strings:
This means that some syntaxes in the list are not possible to robustly detect, for example:
[v.a, v.b{1}, v.c(2,2), ~] = myFunc();
Some other syntaxes are also not robust because of MATLAB's weak typing:
table = @() struct('a',{1,2,3}); % could be any size.
...
T = table() % oops, not an instance of the table class.
[T.a,~] = myFunc() % how many outputs?
On top of that we have the possibility of EVAL/ASSIGNIN/etc replacing or clearing any variable... which all just proves, that the number/ignored output arguments can only be determined at runtime.
More Answers (2)
Bjorn Gustavsson
on 19 Aug 2020
Edited: Bjorn Gustavsson
on 19 Aug 2020
I'll merge parts of two of my comments to provide a KISS-type suggestion:
In a "gentle-downhill-slope-home" use-case you might be able to sort your a, b and c such that the expensive and avoidable output is the third output - then you can check how many outargs there are with nargout. That way you can avoid the expensive calculation if you only have 2 outputs, this generalizes well in some cases.
If this is a big problem in terms of time-consumption, then re-write the function with an optional argument, call it something like whichargouts that directs the function excecution. You could make it a bolean array with 1 for requested outputs. If the user doesn't supply the time-saving directive, no time-saving is made (too bad), if directives are given then time-savings are made. This is a QD-solution to a programming-wise tricky problem, but should work until a neat and robust automatic solution is available.
HTH
0 Comments
Matt J
on 1 Dec 2022
You can do it with this FEX download,
but there are some caveats to its use, mentioned in the documentation.
[x,~,z,~] = foo()
function [a,b,c,d] = foo()
[a,b,c,d]=deal([]);
unused=find(outputnames=="~")';
if ~isempty(unused)
disp("These outputs are not used:"+mat2str(unused));
end
end
These outputs are not used:[2;4]
x =
[]
z =
[]
0 Comments
See Also
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!