How Matlab functions return values

Table of Contents

      
 
 
 
 
 
 
 

1 Executive summary

  1. In a generic function definition

    function [ <outarg1>, <outarg2>, ... <outargn> ] = <function name>(<inarg1>, ...)
    

    the <outargi> are the output arguments, or outargs.

  2. In the function body treat all of the outargs as local variables that can be used exactly like any other Matlab variables. Local means the same thing that it did in Maple, i.e. that only the function knows about the existence of its local variables and they will not conflict with variables with the same names that are used in other functions or scripts. with variable

  3. Ensure that each and every outarg has a value assigned to it before the function returns, which will happen either when execution reaches the end of the function definition is reached, or when an explicit return statement is encountered.

    That is, each and every outarg must appear on the left hand side of at least one assignment statement.

    Nothing stops you from reassigning the outarg one or more times in the function body so that it appears on the LHS of more than one assignment statement, but it must be assigned at least once, or the function definition is incorrect.

2 Preamble

This is an extremely important concept that you must master. It can be tricky, especially if you are relatively new to programming and especially since you have done some Maple programming and thus may be apt to program a Matlab function in the same way you code a Maple procedure.

First, bear in mind that the mechanism by which functions return values is different in the two languages and you must understand the difference, and more generally, precisely how we make Matlab functions return values, where I remind you that in this context return means give back to the environment, in precisely the same sense as if I view \(\sin(x)\) as a machine or black-box, when I give it the input \(\pi/4\), it returns \(\sqrt{2}/2\).

Second, as was the case in Maple, it is of fundamental importance for you to understand the distinction between the following:

  1. The value that a function returns.
  2. Information ("values") that a function displays as it executes.

A key reason that this is a confusing issue is that Matlab (like Maple) routinely produces output to the command window that "echoes" the effect of every statement that is executed.

Specifically, as we have seen, the basic interaction cycle with Matlab goes as follows (this isn't complete, but it illustrates the central point):

  1. We type an expression---a Matlab statement---that Matlab can evaluate, such as

    >> pi
    

    or

    >> 1:5
    

    or

    >> x = 42
    
  2. Provided that the output is not suppressed by a semi-colon terminator, Matlab will show us what happened, always in the form of an assignment statement.

    So we see

    ans = 3.1416
    

    or

    ans = 1     2     3     4     5
    

    or

    x = 42
    

    where I have suppressed the newlines that Matlab adds after the = sign.

  3. We type another statement, and the cycle goes on.

As an aside, if what we've typed isn't an explicit assignment statement (e.g. cases 1 and 2 above) the Matlab always assigns the value of the expression to the special variable ans as a matter of convenience. If we want to save (temporarily) the value of some calculation but don't want to invent the name of a variable to save it in, then it is convenient for it to get stuffed into a default variable whose name is fairly logical and easy to type. And if we don't particularly want to save the value, then assigning it to ans isn't going to hurt.

3 The way things should NOT be done: example

Consider the following (incorrect) definition of a function mymax2_bad that is to return the maximum value of its two input arguments x and y. Particularly if Maple programming is still fresh in your mind, you might be inclined to write something like this:

function val = mymax2_bad(x, y)
    if x > y
        x
    else
        y
    end
end

(This function is included in the course demonstration package so you should be able to verify that this is the definition using type mymax2_bad.)

In Maple this is the correct way to code things since the value of the last expression that is evaluated is the value that is returned by the procedure.

Now let's see what happens when we call the function:

>> mymax2_bad(3, 4)

y =

     4

The output---i.e. what appears in the command window after we enter the statement---looks reasonable, especially if we weren't scrutinizing it carefully.

But now let's try to assign what it returns to a variable

>> max34_bad = mymax2_bad(3, 4)

Error in <a href="matlab:helpUtils.errorDocCallback('mymax2_bad', ...
   if x > y

Output argument "val" (and maybe others) not assigned during call to ...

where ... denotes omitted diagnostic information. The mere appearance of the error message tells us that something is amiss, and the text of the error message does actually does tell us how to fix the problem. However, in order to make sense of the message, we have to understand how values are returned from functions in Matlab. And the reason that we made the mistake in the first place was that we didn't understand this. So the message isn't very useful at this point.

Another aside: before proceeding to a description of a correct implementation of the function, let us note that it is a fact that we will frequently find ourselves in situations like this when learning a computer language, and it certainly isn't unique to that activity. The first time or few times that we run into a particular problem we may have no clue as to what is wrong or what "the computer is telling us" when it spits out some error message. It may take time, sometimes a lot of time, to resolve the issue. But eventually two things tend to happen. First, we tend to make the specific type of mistake less frequently. Second, and more importantly, we learn how to more swiftly diagnose the problem---through understanding what diagnostic messages mean, for example---and how to more swiftly fix it. Ultimately, as with most activities we deem worth mastering, mastery is largely a function of experience.

4 The way things SHOULD be done: example

OK, a correct version of the function is

function val = mymax2_good(x, y)
    if x > y
        val = x;
    else
        val = y;
    end
end

and there are two differences in the correct code relative to the incorrect implementation:

  1. Each clause of the if the statement is an assignment of a value to val.

    This is the crucial difference that makes the second form correct.

  2. The assignment statements are terminated with semicolons, which suppress the normal output.

    This is a technical difference, but one that is worth noting since accidentally omitting a terminator at the end of one or more statements in a function can lead to confusing and difficult-to-diagnose behaviour, especially for novices.

When we invoke mymax2_good(3, 4) and assign the return value, the correct thing happens:

>> max34_good = mymax2_good(3, 4)

max34_good =

     4

5 The difference between right and wrong

Now, if we go back and look at the output from mymax2_bad(3,4) we can understand what is happening and what makes the coding of mymax2_bad incorrect:

>> mymax2_bad(3, 4)

y =

     4

In this case the output

y =

     4

comes from within the function as it runs, because we neglected to end the statement with a semicolon, and is simply Matlab showing us what happens when the function executes

y

Note that once y has a value, then y by itself as a line of Matlab code is a Matlab statement, even if it doesn't seem syntactically complicated enough to be one.

Since on entry to the function the mappings

x -> 3
y -> 4

are made, what appears in the command window as mymax2_bad executes is precisely what we see when we type the following interactively in the command window:

>> y = 4;
>> y

y =

     4

So although the 4 we see in the output of

mymax2_bad(3, 4)

y = 

     4 

is obviously the same value as the 4 we see in the output of

>> max34_good = mymax2_good(3, 4)

max34_good =

      4

there's a fundamental distinction between the two:

  1. In the bad invocation, the 4 is literally only being displayed, it can't, for example, be assigned to a variable that we want to define in the command window.
  2. In the good invocation, the 4 is the actual value returned by the function. It can be assigned to a variable, which is precisely what we have done with the statement

    >> max34_good = mymax2_good(3, 4)
    

    Also, because this statement doesn't end with a semi-colon, the value 4 is also displayed:

    max34_good = 4
    

Let's go one step further to make a final point about the distinction between the good code and the bad code.

  1. If we suppress the output from the good call/assignment

    >> max34_good = mymax2_good(3,4);
    

    then max34_good is still assigned the value 4, but nothing appears in the command window.

  2. If we suppress the output from bad/call assignment

    >> max34_bad = mymax2_bad(3,4);
    

    then we still see

    y = 4
    

    before the error message appears.

    That output is coming from within the function, has nothing to do with the assignment of max34_good at the command prompt and can only be suppressed by changing the source file mymax2_bad so that the (incorrect) statement y has a semicolon at the end.

    y -> y;
    

6 The way things SHOULD be done: general

So let's now focus on the issue of how we properly code functions in Matlab by looking at the key elements of the definition of mymax2_good

function val = mymax2_good(x, y)
    if x > y
        val = x;
    else
        val = y;
    end
end

First we look at the header and simply do some counting and identification:

  1. How many input arguments are there? I.e. how many comma-separated names appear within the set of parentheses that follows the name of the function, mymax2_good?

    Answer: 2

    What are the names of the input arguments?

    Answer: x and y

  2. How many output arguments are there? I.e. how many names appear between the keyword function and the name of the function mymax2_good?

    Answer: 1

    What is the name of the output argument?

    Answer: val

Second, let's note that there are three pieces of code that all look like assignments to the output argument val:

function val = mymax2_good(x, y)

and

val = x;
val = y;

The last two are assignment statements---they define (or equivalently, set or change its value.) These are active pieces of code, pieces that do something, pieces that we refer to as executable statements, irrespective of what computer language we are using.

The first statement, however, is not an assignment statement. It is not an executable statement and should be viewed as passive, rather than active. It defines:

  1. What the function is called: mymax2_good
  2. How many input arguments it has: 2, and what their names are: x and y.

    In generic programming terminology we call these the formal arguments.

    The values or variable names that we supply when we call the function, e.g. 3 and 4 in

    >> mymax2_good(3, 4)
    

    or in1 and in2 in

    >>  in1 = 3;
    >>  in2 = 4;
    >> mymax2_good(in1, in2)
    

    are the actual arguments. Whenever we call the function a mapping is established between the actual and formal arguments and then everywhere that the name of a formal argument (x for example) appears in the body of the function, the value of the actual argument (3 for example) is used.

  3. How many output arguments it has: 1, and what its name is: val

FINALLY!!

QUESTION:

How do we make Matlab functions return values?

ANSWER

Treat every output argument as a variable that is local to the function, and make sure that it has been assigned a value before the function return.

CORRECT IMPLEMENTATION

In our example

function val = mymax2_good(x, y)
    if x > y
        val = x;
    else
        val = y;
    end
% function returns at this point
end

The output argument, val, is assigned a value no matter which clause of the if executes.

Thus, when execution reaches the point where the function returns---in this case where the function definition ends as indicated by the comment that I've added, val has been assigned and the function returns the correct value.

Note that we can view the assignment of the return value from a function to a variable, as in

>> q = mymax2_good(3, 4)

as another mapping. In this interpretation mymax2_good(3, 4) will ultimately be mapped to (replaced by) the value that val has when the function returns.

INCORRECT IMPLEMENTATION

In contrast

function val = mymax2_bad(x, y)
    if x > y
        x
    else
        y
    end
end

contains no assignments to val, and is thus fundamentally incorrect. When we use it ...

>> max34 = mymax2_bad(3, 4)

... the error message from Matlab tells us what is wrong:

Output argument "val" (and maybe others) not assigned during call to ...

7 End note

For some of you, all of this will seem obvious, in which case it is highly unlikely that you read this far. For the rest of you, if the picture still isn't clear, or doesn't become clear after you've written a couple of functions, ask for help!