Cellfun, too many output arguments (2014b)

What is wrong with the first call?
>> cellfun(disp, {'how', 'are', 'you', '?'})
Error using disp
Too many output arguments.
>> cellfun(@(x) disp(x), {'how', 'are', 'you', '?'})
how
are
you
?
>>

 Accepted Answer

That first call attempts to call the disp function with 0 input arguments and 1 output argument, then pass the output argument from that disp call into cellfun as its first input argument. The disp function can have a maximum of 0 output arguments [it doesn't return anything.]
The second call creates an anonymous function and passes that into cellfun. When cellfun calls that anonymous function, since the cellfun call has 0 output arguments so does the anonymous function call. Because the anonymous function is called with 0 output arguments, so is disp.
You can simplify that second call a little bit by using a normal function handle.
cellfun(@disp, {'how', 'are', 'you', '?'})

15 Comments

OK, thank you, so the first parameter for cellfun needs to be a function handle.
If @disp is a function handle, why is disp also a function handle and why does it indicate a handle of a function with 0 input and 1 output arguments?
Generally yes, the first input to cellfun needs to be a function handle. This could be one that you create explicitly in the call, a variable containing a function handle, or the output of a call to a function that returns a function handle.
% function handle
cellfun(@disp, {1, 2, 3})
% Variable containing a function handle
h = @disp;
cellfun(h, {1, 2, 3})
% Call to a function that returns a function handle
% Calling f(5) returns a function handle @(y) disp(5+y)
f = @(x) @(y) disp(x+y);
cellfun(f(5), {1, 2, 3}) % will display 6, 7, 8
Looking at the specific code you're writing:
@disp is a function handle.
@(x) disp(x) is also a function handle, but it's also called an anonymous function.
disp is a call to the disp function with 0 input arguments. It is not a function handle. Because you're calling it inside the input argument list of a function call, it has to return something to use in the input argument list and that's why MATLAB threw an error.
disp() is also a call to the disp function with 0 input arguments. The main difference between this and "disp" is that the parentheses make it a bit clearer to humans reading the code that you're calling a function.
Alright. Can I propose to change the error message to something like this?
>> cellfun(disp, {'how', 'are', 'you', '?'})
Error using disp
disp is not a function handle
Thanks a lot, Arnfried
"Can I propose to change the error message to something like this?"
Your use of disp was not incorrect because disp is not a function handle, your use of disp was incorrect because you call disp with an output argument, equivalent to doing something like these:
x = disp(1)
x = disp()
which has absolutely nothing to do with function handles or lack of function handles, it is solely dependent on how you are calling disp. Even if you make a function handle to disp and call it in the same way, you will get the same error, because the problem has nothing to do with function handles or lack of function handles. The error is due to your incorrect calling disp with an output argument... which happens to be the error that MATLAB already gives. Try it yourself and see what happens:
So, function handle or not, you will get the same error.
Note that your error also has nothing really to do with cellfun, per se.
Thank you, but I still think the error message doesn't make sense.
>> x = disp(1);
Error using disp
Too many output arguments.
>> fun = @disp;
>> x = fun(1);
Error using disp
Too many output arguments.
>> cellfun(disp, {1, 2, 3});
Error using disp
Too many output arguments.
>> cellfun(fun, {1, 2, 3});
1
2
3
>>
@Arnfried Ossen: it boils down to these points:
  1. The number of outputs a function returns is demand-driven. Calling a function with one output returns one output, calling it with two outputs returns two outputs, etc..
  2. It is an error to demand outputs that are not defined by that function.
  3. An outer function demands exactly one output argument from a nested function. No more, no less.
  4. Nested code is evaluated from the inside out (for obvious reasons that don't apply to reverse polish notation).
  5. The syntax
somefun
calls/evaluates the function somefun. Forget what you might have learned with other languages, that is how MATLAB works. So when you write
anotherfun(somefun,...)
and considering points 4. and 5. you have already evaluated somefun. Now consider point 3.: anotherfun demands that somefun must return one output argument. Now consider point 1. ... but somefun returns zero output arguments! Ouch... contradiction! What happens now? Point 2.: an error message tells us that there are not enough output arguments. Which is exactly what MATLAB does.
Basically your code is equivalent to this:
x = disp()
cellfun(x,...)
which is an error because you are demanding an output argument from disp, but it defines none. The error has nothing to do with handles at all. In your last example
fun = @disp
cellfun(fun,...)
the function handle fun is not evaluated (function handles must be evaluated with parentheses), so it is actually the input argument that cellfun requires (function handles are one of the fundamental classes in MATLAB, so are variables much like any other. Note that functions are NOT variables in MATLAB!). You would get exactly the same effect by doing this:
cellfun(fun(),...)
which evaluates the function handle fun, just like you did with disp in your original code (possibly without knowing it). Try it and see what happens (hint: you get exactly the same error, showing that the error has nothing to do with function handles, just with evaluating a function that returns no output argument inside a function that demands one input argument).
This might help you to understand the situation:
If you provide a function handle and the respective number of arguments doesn't match, it is certainly OK for cellfun to issue a message about the mismatch, eg,
% function handle provided, but argument mismatch (1 expected, 0 provided)
>> x = cellfun(@disp, {1, 2, 3});
Error using disp
Too many output arguments.
And if we make the number of outputs match (0 expected, 0 provided), everything is fine again:
% function handle provided and matched number of arguments: all fine
>> cellfun(@disp, {1, 2, 3});
1
2
3
We can also make the number of arguments match for functions with a non-empty list of output arguments (1 expected, 1 provided)
>> x = cellfun(@sum, {1:2})
x = 3
But apparently, there is no way to make a call to cellfun work without a function handle.
It is an error and MATLAB should issue a respective error message.
>> % no function handle, misleading error message about argument mismatch
>> cellfun(disp, {1, 2, 3});
Error using disp
Too many output arguments.
"If you provide a function handle and the respective number of arguments doesn't match, it is certainly OK for cellfun to issue a message about the mismatch, eg,"
>> x = cellfun(@disp, {1, 2, 3});
Error using disp
Too many output arguments.
Interestingly you disprove your own argument with your own example. Read the error message again: does cellfun throw the error, as you wrote? Answer: no, the error actually comes from disp, because you demand an output from disp, which it can't deliver. Exactly like when you first evaluated disp in your original question, and then demand that it delivers an output (by nesting it inside another function).
"And if we make the number of outputs match (0 expected, 0 provided), everything is fine again:"
cellfun(@disp, {1, 2, 3});
Your statement is incorrect. @disp itself is the input argument (it is a function handle) that cellfun requires: it is actually one variable expected, one variable received (and that variable is the function handle).
"But apparently, there is no way to make a call to cellfun work without a function handle."
Yes, that is what the documentation states (with a few other special cases). But that is not really relevant to the error: all that is important is the disp is nested inside another function (which could be anything).
You have ignored points 4. and 5. in my previous comment: disp is evaluated first and because it is nested inside cellfun the evaluation demands one output variable as an input to cellfun. Evaluated disp returns no variable. That is all there is to it.
It has nothing to do with function handles. It has nothing to do with cellfun. Try it with a function that does not expect a function handle as its argument, e.g.
sqrt does not demand a function handle, but it does demand one output argument from any nested function, which of course is evaluated first...
Perhaps an analogy with robots instead of functions will clarify things.
Imagine a robot named Plus. In order for Plus to perform its job, it needs stuff to be placed in its left hand and in its right hand. If MATLAB or another robot puts two pieces of paper in Plus's hands (one with 1 written on it and another with 2), Plus can work with those pieces of paper and hand the result (a paper with 3 on it) to either MATLAB or a robot who's waiting for the results from Plus. The equivalent function call in MATLAB is plus(1, 2) returns 3.
Now suppose Plus has something in its left hand but is waiting for a robot named Disp to put something in the right. Disp gets a piece of paper in its left hand, shouts out what was written on it, and walks away. Plus says "Not cool, get back here and give me your paper!" but Disp just goes home. That's effectively what happened in your cellfun(disp, ...) example, only with Cellfun and Disp rather than Plus and Disp. The equivalent MATLAB code would be plus(1, disp(2)) which will throw an error (the equivalent of "Not cool!")
But if we extend this analogy a bit further, Cellfun doesn't want to have a piece of paper in its left hand. Instead, Cellfun expects to receive a cell phone (analogous to a function handle.) When Cellfun needs to know what it should do to work on the stack of papers in its right hand, it calls the number programmed into the phone, reads off the number on the top paper, and waits for a reply from the person on the other end.
When Cellfun calls Disp (using the cellfun(@disp, ...) syntax), if Cellfun was waiting for a response from Disp (because someone else is waiting for a reply from Cellfun) Cellfun is going to wait a long time. Disp is going to shout the number Cellfun tells him or her then hang up the phone. If on the other hand Cellfun knows it doesn't need to wait for a response from Disp, it can tell Disp the number then hang up immediately without waiting for a response.
The first scenario is x = cellfun(@disp, {1, 2, 3}) which will error while the second is cellfun(@disp, {1, 2, 3}) (no output argument) which will not.
Hopefully this helps rather than confusing matters further.
Two more points occurred to me that are very relevant to this discussion:
6. Functions are not variables.
7. MATLAB stops at the first error.
"It is an error and MATLAB should issue a respective error message."
It does already.
You seem to think that disp is a variable: it isn't, it is a function (see point 6.). Note that function handles are variables.
Your proposed message is not really possible: which function knows that cellfun requires a function handle as its first input? That is right, cellfun knows that (and test its inputs to check this). disp does not know what every other function expects for their input argument classes, nor is that its job: functions check their own inputs for themselves. And of course cellfun warns you if you give it an incorrect class of input argument.
But this is where your proposal fails: in order for cellfun to know that its input argument is not an function handle, it has to have an input argument. But you are not providing it with any input argument (point 6.). Instead you evaluated a function which returns nothing... and demanded one output argument (points 3. and 4.), and so throws an error (point 2.). So before cellfun could even begin to decide what to do, your code has already thrown an error (point 7.).
I would be interested what you would propose this should return as an error message:
size(disp)
size accepts an input argument of any class (numeric, char, cell, function handle,...), so what would your error message be?
Thank you for your elaborate explanations about why cellfun cannot issue a meaningful error message if you use disp (instead of @disp) as first argument. From a user's perspective, this is disappointing.
BTW, in simpler cases, it will issue exactly the message I was hoping for.
>> cellfun(max(1), {1})
Error using cellfun
First input must be a function handle.
"Thank you for your elaborate explanations about why cellfun cannot issue a meaningful error message if you use disp (instead of @disp) as first argument."
cellfun really has nothing to do with this error. It is only significant that disp is nested inside cellfun when disp is evaluated.
"BTW, in simpler cases, it will issue exactly the message I was hoping for."
Of course, because in that example you actually demand one output from max (no problem) and provide it as an input argument to cellfun:
But the code in your original question does not provide any input argument to cellfun, and in fact the code stopped with an error before MATLAB could even try to do that (it stopped when you demanded a non-existing output from the evaluated disp function).
Evaluating a function (in your original question) and passing an argument (in your last comment) are two totally different things. Your original code did not provide any input to cellfun and in fact the code evaluation had stopped before MATLAB could even ask cellfun what it prefers its inputs to be. How can you expect cellfun to have a say on this matter, when the error has already occurred and everything stops?
Your original question is equivalent to doing this:
x = disp() % evaluation throws an error!
... ten thousand lines of unrelated code.
cellfun(x,...)
and then expecting cellfun to know that it has a problem with a non-existent input argument... but the evaluation already stopped with an error, ten thousand lines before it could get to cellfun. Why would it be helpful to have an error message listed ten thousand lines after where the actual error is?
Also note that the error is not because of evaluating any function in that position: you could easily define a function that returns a function handle, and it would work perfectly:
function fun = myfun()
fun = @disp;
end
This is significant because it means that MATLAB cannot know in advance what functions are overloaded, what function will be called (the user can easily change the search path programmatically), or have function outputs that change depending on data... it is only when the code is evaluated that the actual output arguments are known (or in your question, the lack of any output arguments even though you demanded one). So MATLAB starts evaluating the code, you demand a non-existent output which causes an error and everything stops. cellfun (or whatever the outer function is) does not even get a chance to be asked what it wants!
I really would be interested to know what error you think this should deliver:
size(disp)
or its equivalent:
x = disp()
... ten thousand lines of unrelated code
size(x)
give that size works with all fundamental data classes (of which functions are not a member) (and of course ignoring that fact that the error occurs with trying to get an output from disp, and is not related to size at all). Please think about it and let me know.
From a user perspective, the message "Too many output arguments" is confusing and misleading, if the actual problem is an empty evaluation result.
But if this is what it is in MATLAB, so what.
In the cellfun(disp, {1, 2, 3}) case the cellfun function is not executed at all. MATLAB throws an error while it's evaluating the disp function to generate the input argument that it needs to call cellfun, so it never gets to the point where cellfun actually starts executing. Since it never starts running, it can't throw an error.
Since cellfun is a built-in function, let's use a different function to demonstrate this. Set a breakpoint in a MATLAB function file. I'm going to use factor since it's a nice simple function.
dbstop in factor
When you call factor with a number as input, you'll see that MATLAB stops on the first executable line of the function. In that case, MATLAB was able to successfully call factor.
factor(6)
Now quit debugging either with the "Quit Debugging" button in the Editor or using the following command.
dbquit
Next let's try to call factor and disp together.
factor(disp(7))
MATLAB threw an error. It didn't reach the breakpoint. It threw an error while preparing to call factor, not after it had started to call factor.
After running those pieces of code, you can clear the breakpoint.
dbclear all
From a user perspective, the message "Too many output arguments" is confusing and misleading, if the actual problem is an empty evaluation result.
But if this is what it is in MATLAB, so what

Sign in to comment.

More Answers (0)

Categories

Find more on Code Execution in Help Center and File Exchange

Products

Release

R2014b

Community Treasure Hunt

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

Start Hunting!