Confused with the switch-case outputs with nargin

I am a bit confued about the nargin function's behavior.
For the first example: narginExample(2, 5); ans = 7
Second example: narginExample(2, 5); ans = 4
My question is:
  1. Why the function chooses the second case to execute?
  2. What is the use of "otherwise"? I was assuming, when I pass 3 arguments (or no arguments), it would be considered as the "otherwise" case. But it's not.
% Example 1
function x = narginExample(y, z)
switch nargin
case 2
x = y + z;
case 1
x = y + y;
otherwise
x = x;
end
end
% Example 2
function x = narginExample(y, z)
switch nargin
case 1
x = y + z;
case 2
x = y + y;
otherwise
x = x;
end
end

12 Comments

The only thing I can think of is that you're not using varargin, which means that you will get an error when you supply 3 arguments.
I'm perplexed by what you are trying to test here. Both functions output what I would expect them to, though I was mildly surprised that calling with 0 arguments didn't produce an error that x is undefined, which certainly shows up as an M-Lint warning.
You can't pass 3 arguments to that function as it doesn't accept 3 arguments. Or rather, you can pass 3 arguments to it, but you will hit an error on the number of arguments before any of your code is executed.
nargin is a really simple function that does exactly what you'd expect. If you were to change the input arguments to just have
function x = narginExample( varargin )
then you would hit your otherwise case in all cases other than 1 or 2 arguments.
"...I was mildly surprised that calling with 0 arguments didn't produce an error that x is undefined..."
Exactly as expected. it does for me (R2012b):
Hmm, that's odd:
functiondef.png
functioncall.png
Rik
Rik on 30 Aug 2019
Edited: Rik on 30 Aug 2019
Bizar. On R2019a it simply ignores the x=x line (even step by step with the debugger), while on R2015a it triggers an error.
I suspect it is the JIT: changing the line to x=(2*x)/2 does trigger an error, which implies R2019a simply ignores x=x as it does nothing.
I wonder how many functions use something like this to trigger an error and now will not. Seems like a harsh punishment for bad code design.
@Adam: my gut feeling is that your MATLAB version is highly relevant to this...
"which implies R2019a simply ignores x=x as it does nothing."
Ouch! If so, that really needs to be fixed.
@Stephen, You can argue whether this is a bug or a feature. But wait, there is more:
You might think people could use this instead of disp. If that is the case, they will omit the semicolon. If you put x=x instead of x=x; in R2019a, it actually does trigger an error. So this isn't probably by accident. It is probably also difficult to find this in the release notes. I would like a smaller range of releases to scroll through to determine when the behavior changed.
"So this isn't probably by accident"
To me it seems to be accidental: with a semi-colon the JIT manages to "optimize the line away" (and mlint follows), but without the semi-colon JIT realizes that something might have to be printed... then fails due to the undefined variable. It seems like an unintended side effect of some JIT optimization.
Why did you edit away the question text? You're getting free help from strangers on the internet, so the least you can do is leaving your question as it is so future people with a similar question can benefit from this thread. Removing your question is extremely rude.
Original question from Google Cache:
"Confused with the switch-case outputs with nargin"
I am a bit confued about the nargin function's behavior.
For the first example: narginExample(2, 5); ans = 7
Second example: narginExample(2, 5); ans = 4
My question is:
  1. Why the function chooses the second case to execute?
  2. What is the use of "otherwise"? I was assuming, when I pass 3 arguments (or no arguments), it would be considered as the "otherwise" case. But it's not.
% Example 1
function x = narginExample(y, z)
switch nargin
case 2
x = y + z;
case 1
x = y + y;
otherwise
x = x;
end
end
% Example 2
function x = narginExample(y, z)
switch nargin
case 1
x = y + z;
case 2
x = y + y;
otherwise
x = x;
end
end
R2018b ignores x=x; and throws an error for x=x
(Answers Dev) Restored edit

Sign in to comment.

Answers (3)

"Why the function chooses the second case to execute?"
Because that is exactly what you wrote your functions to do.
You call both of your functions with two input arguments. That means nargin==2. That means that case 2 will run. So this is the code that runs when nargin==2:
1st function:
case 2
x = y + z;
2nd function:
case 2
x = y + y;
Your example input arguments are y=2 and z=5. So:
1st function: what does y+z equal? (hint: 7)
2nd function: what does y+y equal? (hint: 4)
"What is the use of "otherwise"?
otherwise runs when none of the cases run, exactly as the switch documentation states.
"...when I pass 3 arguments (or no arguments), it would be considered as the "otherwise" case. But it's not."
Lets look at those two situations:
  • If you pass zero input arguments then otherwise will run, but in both of your functions you try to access x which is undefined at that point, and so an error will be thrown.
  • If you pass more than two input arguments an error will be thrown because you defined the function signature with two input arguments (i.e. y and z). MATLAB knows that you only defined the inputs y and z, so there is no point in it trying to guess what to do with extra input arguments that your function was not written to handle.
"I am a bit confued about the nargin function's behavior."
I don't see that - you seem to be much more confused about switch and how functions work.
Why the function chooses the second case to execute?
Because you called the function with two inputs. MATLAB first checks the case 1 case but nargin is not equal to 1, so that case is skipped. Next it checks the case 2 case and since nargin is equal to 2, MATLAB executes the body of that case.
One key point to know, if you're familiar with other languages, is that cases in a switch / case do not "fall through". At most one case in a switch / case block will be executed.
What is the use of "otherwise"? I was assuming, when I pass 3 arguments (or no arguments), it would be considered as the "otherwise" case. But it's not.
The otherwise case would have been executed, if you called your function with 3 arguments and MATLAB had reached that point in your code. But the way you've defined your function:
function x = narginExample(y, z)
tells MATLAB that you will call this function with at most two input arguments. If you try to call it with 3, MATLAB has no "place" to assign that third input argument, and so it throws an error before even trying to execute any of the lines of code inside the function.
Calling this function with 0 input arguments would reach your otherwise case. Just because you've defined your function to accept one or more input arguments doesn't mean you have to call it with that many. You can call it with fewer.
You can write a function that accepts an arbitrary number of inputs, if you don't want to limit it by how many variable names you want to type in your function definition. To do that, use varargin as the last input argument in your function definition. That identifier is handled differently than any other identifier. See the "varargin and Declared Inputs" example on that documentation page. Even though the definition "looks like" it only accepts three inputs, because it accepts varargin you can call it with five inputs and any past the second get stored in the varargin cell array.
nargin tells you how many inputs your function has.
So, both examples will give you nargin = 2 because you are always entering two function inputs. So case=2 for both examples.
But because you change the order of the cases, in the first example, you have x = y + z and in the second case x = y + y.
Otherwise will work if you call the function with 0 or 3+ inputs. However, the function will return an error in both examples because x is not defined.

Categories

Find more on Argument Definitions in Help Center and File Exchange

Asked:

H
H
on 30 Aug 2019

Commented:

on 12 Dec 2019

Community Treasure Hunt

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

Start Hunting!