%% Lesson 4a: Functions % % Objectives: % - Explore MATLAB's function-calling syntax and semantics. % - Explore anonymous functions. % - Explore local functions. % - Explore regular functions. clear; clc; close all; %% Functions % Functions in any programming language are the means of abstraction. In % functional programming, they are a fundamental structure with the power to % build any complex form. In imperative and scientific computing, functions are % useful to prevent code duplication and improve maintainability. % % There are a few varieties of MATLAB, each of which has very different syntax % and semantics, so buckle up! % % (Insider information from MathWorks: MATLAB is working on improving the % support/accesibility of functional programming! So there may be some % improvements in the near future!) % % Note: this lecture was heavily modified by a functional-programming fan! %% Using functions % All functions are called (invoked) in the same manner: by using the % function's name followed by the list of parameters with which to invoke the % function. z = zeros(1, 3); mean([1, 2, 3, 4, 5]); % Functions may have optional parameters, and they may behave differently when % called with different inputs (polymorphism) or when different numbers of % outputs are expected. They may also return zero, one, or multiple values. size1 = size(z); size2 = size(z, 2); % optional second parameter hist(1:10); % displays a historgram a = hist(1:10); % stores a histogram into the variable a, and does % not display a histogram [r1, r2] = HelloWorld("Jon", "Lam"); % Function returning multiple % values (HelloWorld defined later in % file) % There is a second way that you've seen to call functions, called "command % syntax." These are translatable to the regular function syntax. Any textual % arguments in this syntax will be interpreted as strings, which is similar to % UNIX sh commands arguments (hence "command" syntax). clear a b; % clear("a", "b") close all; % close("all") mkdir test; % mkdir("test") rmdir test; % rmdir("test") % Note that if a function takes no arguments, the parentheses may also be % omitted. (This is not true for anonymous functions, as we will see.) clc; % clc() figure; % figure() %% Anonymous functions % Anonymous functions are defined with the following syntax: % % @(arg1, arg2, ...) fun_body % % These allow us to conveniently define functions inline, and perform some % functional programming capabilities. In other programming languages, they may % be known as "arrow functions" or "lambda functions." cube = @(x) x.^3; parabaloid = @(x, y) x.^2 + y.^2; % Call these functions like any other function. cube(3); parabaloid(3, 4); % As the name suggests, anonymous functions don't have to be assigned names; by % themselves, they are "function values" or "function expressions" and can be % handled like any other expression. (I.e., "first-class" functions). Usually, % we assign it to a variable to name it, just as we do for most useful % expressions. @(x) x.^3; cube_fnval = ans; % Anonymous functions can capture variables from the surrounding scope. They % may exist anywhere an expression may exist (e.g., within the body of another % function). outside_variable = 3; capture_fn = @() outside_variable; outside_variable = 4; capture_fn; % What will this return? capture_fn(); % What will this return? % Lexical scoping and closures apply! This allows for some degree of functional % programming (e.g., function currying). curried_sum = @(x) @(y) x + y; add_two = curried_sum(2); add_two(5); % The binding x <- 2 is captured in % add_two's lexical closure % add_two(2)(5) % Can't do this due to MATLAB's syntax, % just like how you can't double-index % an expression %% Example: Higher-order functions % An example of passing functions around like any other variable. (Functions % that accept other functions as parameters or return a function are called % "higher-order functions.") % % In this example, compose is the function composition operator. compose(f,g) % = (f o g). It is a HOF because it takes two functions as parameters, and it % returns a function. compose = @(f, g) @(x) f(g(x)); add_three = @(x) x + 3; times_four = @(x) x * 4; x_times_four_plus_three = compose(add_three, times_four); x = 0:10; y = x_times_four_plus_three(x); plot(x, y); grid on; %% Normal Functions % "Normal functions" (so-called because they were the first type of function in % MATLAB) are defined using the syntax shown below, and are invoked in the same % way as anonymous functions. % % Note that normal functions cannot be passed around as variables, and this % makes a functional-programming style impossible using normal functions. % % Unlike anonymous functions, normal functions may include multiple statements, % may return multiple values, are invoked if appearing in an expression without % parentheses (unless you use a function handle), and do not capture variables % from the surrounding scope/workspace. % % There are two types of normal functions: "public" normal functions, which % must be placed at the beginning of a *.m file with the same name as the % function, or local/private normal functions, which may appear at the end of a % *.m file (after anything that is not a function). Both types of normal % functions must appear after any statements in the file; in other words, a % file defining a non-local function can only contain a list of function % definitions, the first of is public and the rest of which are private. As the % name suggests, local functions are only in scope in the file in which they % are defined, whereas public functions may be accessible if they are on the % MATLAB path. % % You don't need to understand all this right now; this brief explanation and % the MATLAB documentation can serve as a reference for your future MATLAB % endeavors. %% The MATLAB Path % In order to call a public function defined in another file, the function file % must be in the current folder or on the MATLAB path. matlabpath; % Print out MATLAB path %% Invoking regular functions % Note that this section is before the local function definition because the % local function must be defined after all statements in the script. % % eye() is a builtin function. Here we call it with no arguments, so the first % argument's value defaults to 1. distance() is a public function defined in % the file distance.m HelloWorld() is a local function defined below eye; distance(3, 4); HelloWorld("Jon", "Lam"); % Invoking HelloWorld and ignoring outputs %% Defining a local function function [res1, res2] = HelloWorld(name1, name2) fprintf("Hello, world! %s %s\n", name1, name2); res1 = 3; res2 = [5 6]; end %% Other fun stuff: % Function handles % `feval` on function handles and strings % Double-indexing using functions % Viewing source code using `edit`