Continuing with my series about M, I'm going to talk today about defining functions today. I discussed how to call and use functions last time, and today we are going to learn how to make our own.
Functions are defined simply with the "function" keyword, and are terminated with the "endfunction" keyword. Here's an example:
function x()
disp("Hello World!");
endfunction
It's worth noting here that semicolons should probably be used to terminate all statements inside a function, because the values of statements will still be printed to the console otherwise.
Parameters can be defined as expected:
function foo(a, b, c)
printf("values: %d, %d, %d", a, b, c);
endfunction
Where things get a little different from what we (Perl programmers mostly) are used to is in return values. The return values of a function are defined in the function signature itself. The "return" keyword, while still useful for exiting a function prematurely, does not take a value itself.
function s = sum(a, b)
s = a + b;
endfunction
Here is almost the exact definition of the pi() function in the Matrixy repo:
function p = pi()
p = 3.141592653589
endfunction
M allows multiple return values too:
function [a, b, c] = bar()
a = 1;
b = 2;
c = 3;
endfunction
All input and output parameters in M are optional. Even if we define 3 named parameters, a caller could pass only one or two (or 4 or more!) without causing a problem. It's the function's job to count the number of values that it has received and modify it's behavior accordingly. This is done simply through the "nargin" and "nargout" keywords:
function [a, b] = baz(c, d)
if nargin == 1
d = 0
elsif nargin > 2
error("too many args passed!");
end
if nargout >= 1
a = c + d;
elsif nargout >= 2
b = c - d;
else
error("too many output args!");
end
end
There's no such thing as multidispatch in M, if you want a function to do different things with different numbers and compositions of arguments, you have to code the dispatching logic yourself.
If you want to account for argument lists of indeterminant length, you can use the slurpy "varagin" and "varargout" keywords:
function [c, varargout] = bazooka(a, b, varargin)
...
endfunction
varargin and varargout are special data types called "cell arrays" that we haven't discussed yet, so we won't see them used here.
That's a brief introduction to functions in M. We don't have all of this implemented in Matrixy yet, but we are making some pretty amazing progress. Come check it out.
Matrixy on Googlecode