Session 11: Writing Scilab Functions
Objectives
In this session you will learn the following:
- Writing inline functions
- Number of input and output arguments and parameters
- Setting default values to input arguments
Introduction
In session 10, we saw the basic skeleton for a Scilab function and a simple example to illustrate how to develop and use a function. Here we will take a closer look at counting input and output arguments. We will also see how do define an inline function.
Inline Functions
An inline function is a short function that can be defined without having to use the function skeleton discussed in Session 10. This is useful only when the body of the function is short (in case the body of the function is long, it could be first stored in a string and then used to define the inline function). We will again use the same function used in Session 10 as an example. The syntax for defining an inline function is:
deff(func_interface_str, func_body_str)
where func_interface_str is a string containing the interface of the function and func_body_str is a string containing the body of the function. The function to find the length of a line segment in 3D space can therefore be written as:
-->deff('[L] = len(p1, p2)', 'L = sqrt(sum((p2 - p1).^2))');
Alternately, the function could also be defined as:
-->s1 = '[L] = len(p1, p2)';
-->s2 = 'L = sqrt(sum((p2 - p1).^2))'
-->deff(s1, s2)
-->len([0 0 0], [3 4 5])
ans =
7.0710678
This could be advantageous when the body of the function contains a very long statement and is difficult to fit it on a single line. If you want to define an inline function with multiple lines, use an array of strings as the second input argument. The above function could be split into multiple lines as shown below:
-->s1 = '[L] = len(p1, p2)';
-->s2 = ['delta = p2 - p1;', 'ss = sum(delta.^2);', 'L = sqrt(ss);'];
-->deff(s1, s2)
-->len([0 0 0], [3 4 5])
ans =
7.0710678
Number of Arguments
The number of input and output parameters are defined when the function is defined. It is quite easy to understand what happens when you supply the same number of input and output arguments during a function call. However, it is possible to call a function without the correct number of matching arguments.
With reference to function definitions and their use during a function call, parameters appear in function definition and arguments appear in function calls (See this article section on Wikipedia).
Here are some rules you must remember about input arguments and input parameters:
- Number of input arguments can be equal to or less than the number of parameters.
- Providing more input arguments than the number of input parameters is an error.
- If you provide fewer arguments than the number of parameters, it is an error to use an argument that is not provided. As an example, if the number of input parameters is 3 and number of input arguments is two, attempting to use the third parameter within the body of the function results in an error. If you can check how many arguments have been supplied at run time and avoid using the ones not provided does not result in an error.
- It is possible to determine the number of arguments to a function at run time, and assign default values to those parameters which do not have corresponding arguments. This is akin to default values assigned to parameters in languages such as C++, but this has to be done explicitly by the programmer and does not happen automatically.
- Input arguments may be either variables or constants.
Here are some rules you must remember about output arguments and output parameters:
- Number of output arguments can be equal to or less than the number of output parameters.
- It is an error to provide more output arguments than the number of output parameters.
- If you provide fewer arguments than the number of output parameters, values of the output parameters without a corresponding output argument are lost and not available to the parent function.
- If no output arguments are provided, the value of the first output parameter is assigned to the built-in variable ans, values of other output parameters are lost.
- Output arguments must be variables, they cannot be replaced by constants. In C language parlance, they must be an lvalue (capable of storing a value in them).
Scilab provides the function argn() to count the number of unput and output arguments at run time. Let us use the following function to show how this can be used and also illustrate the above points:
function [a, b] = testarg(x, y, z)
[out, inp] = argn(0);
mprintf("Output: %d, Input = %d\n") // print function similar to printf in C
if inp < 3 then, z = 20, end
if inp < 2 then, y = 10, end
if inp < 1 then, x = 5, end
disp([ x, y, z]);
a = x + y; b = 2 * z;
endfunction
Save this function in a file and load it into Scilab workspace. Let us call this function in the following different ways. Note what we have done within the body of the function:
- We determine the actual number of output and input arguments provided to the function at run time using the function call [out, inp] = argn(0).
- We print out the number of output and input arguments provided to the function at run time.
- We check to see if the number of input arguments is less than 3 (that is, either 1 or 2; which implies that argument corresponding to parameter z is not provided). If so, we assign an arbitrary default value to z.
- We check to see if the number of input arguments is less than 2 (that is, 1; which implies that argument corresponding to parameter y is not provided). If so, we assign an arbitrary default value to y.
- We repeat this operation for parameter x.
- We display the values of the input arguments x, y and z.
- We compute the values of the two output arguments using the input values (the relationships between a and b and x, y and z are arbitrary, only for the purpose of explaining this concept of number of input and output arguments and parameters).
// all input and output arguments provided exactly as required
-->[a, b] = testarg(1, 2, 3)
Output: 2, Input: 3
1. 2. 3.
b =
6.
a =
3.
-->[a, b] = testarg(1, 2) // 3rd input argument not provided
Output: 2, Input: 2
1. 2. 20.
b =
40.
a =
3.
-->[a, b] = testarg(1) // 2nd and 3rd input arguments not provided
Output: 2, Input: 1
1. 10. 20.
b =
40.
a =
11.
-->[a, b] = testarg() // No input arguments provided
Output: 2, Input: 0
5. 10. 20.
b =
40.
a =
15.
-->[a, b] = testarg(1, 2, 3, 4) // more input arguments than parameters
!-- error 58
Wrong number of input arguments:
Arguments are:
x y z
Now, let us test the output arguments:
-->[a] = testarg(1, 2, 3) // 2ns output argument not provided
Output: 1, Input: 3
1. 2. 3.
a =
3.
-->testarg(1, 2, 3) // No output arguments
Output: 0, Input: 3
1. 2. 3.
ans =
3.
-->[a, b, c] = testarg(1, 2, 3) // Extra output argument
Output: 3, Input: 3
1. 2. 3.
!-- error 4
Undefined variable: c