# Functions and Scripts¶

## Encapsulation¶

A key idea of structured programming:

- package code into self-contained functions
- avoid side effects

A function should only change the rest of the world through the outputs it explicitly returns. This is called encapsulation.

For this to work, all variables inside a function must be invisible to other code – they are **local**.

### Example:¶

```
function y = f(x)
a = 5;
y = x + a;
end
% Command line:
>> a = 3; y = f(0); disp(y)
5
>> disp(a)
3
% Now the converse
function y = g(x)
z = x + a;
end
>> g(0)
% Error: `a is not defined`
```

## Namespaces¶

A namespace is a set of functions or scripts that can “see” the same objects.

Example:

- In the function
`f(x)`

above,`a`

was in`f(x)`

’s namespace, but not in`g(x)`

’s. - Conversely, the
`a`

inside`f(x)`

is local and not in the command line’s namespace.

In Matlab, there are only 2 namespaces:

- Global: this is what you can access from the command line.
- Local: inside a function.

Note: This is not exactly true because there are nested functions.

This means in particular that all global variables and all functions are visible everywhere. Their names must be unique.

Other languages have more control over namespaces (using “modules”).

## Functions versus Scripts¶

Scripts are simply collections of commands that are run as if they were typed at the command prompt.

Scripts run in the global workspace. This is, generally speaking, not good. They create side effects.

Rule of thumb:

Always use functions, never scripts!

Functions are similar to scripts with one crucial difference:

- All variables inside a function are
**private**. - Other functions cannot see the variables inside a function (
*encapsulation*). - Any variable a function should know must be passed to it as an input argument.
- Any variable to be retained after the function finishes must be passed out of it as a return argument.

An important principle of structured programming:

Package a well-defined task into a function with a simple interface.

A function looks like this

```
function [y1, y2] = fname(x1, x2)
% Do stuff with x1 and x2 to generate y1 and y2
end
```

This would be stored in a text file called `fname.m`

.

A side note: Even built-in Matlab commands are often written in Matlab.

Try `open sub2ind`

. You get to see (and you can modify) the source code for the built-in `sub2ind`

command (`sub2ind.m`

).

Now try `open zeros`

. This opens `zeros.m`

.

- you get an m-file that is blank except for comments
- this means:
`zeros`

is not written in Matlab (it’s truly built-in)

## The Matlab Path ¶

The Matlab path determines which m-files are visible in the global namespace (and inside all functions).

In contrast to other languages, this is an all or nothing affair: If a function is visible somewhere, it is visible everywhere.

When the user issues a command, such as `m = zeros([3,4]))`

, Matlab searches for a matching m-file, in this case `zeros.m`

and runs it.

It does not matter whether `zeros`

is a built-in command or an m-file written by a user.

Where Matlab looks is defined by the `matlab path`

.

This is a list of directories that Matlab goes through when it looks for functions.
In case you wonder, this is done as a `cell array`

of strings.

You can see what’s on the path by typing `path`

.

You add directories to the path with addpath.

In addition, Matlab searches the current directory (the one shown in the file browser).

Therefore, every time you write new code, you need to put the directories on the `path`

before the code can be called.

There is no way to allow one function to access some code without changing the `path`

globally. This differs from other languages. It makes it hard to organize code.

There is one exception: local functions are only visible to functions within the same m-file.

## Organizing Code¶

When you write new commands, you need to make sure Matlab can find them. This is best accomplished in two ways:

For files that belong to the one particular project, place them in a project directory. Then switch the current directory to that directory using

`cd`

.Or put the directory on the

`path`

using a startup routine.For files that are

**shared**between several projects, place them in a special directory (`blah/shared`

). Place this directory on the path:`addpath('blah/shared')`

.

Over time you will write many general purpose routines that should be stored in this `shared`

directory. Reusable code!

### Name Conflicts¶

Now you run into a problem: **name conflicts**.

Each time you write a new function, you need to make sure that there is no other function with the same name.

There are 2 ways of ensuring this:

Suffixes: For each project, invent a suffix and append it to every function name.

Such as

`plot_821.m`

Packages: If you place an m-file into a directory that starts with

`+`

, let’s say`+econ821`

, you can access it like this:`econ821.plot(x)`

.For this to work, the parent dir of

`+econ821`

must be on the`path`

.This is also useful to organize your code within a project (which may contain hundreds of functions).

## Example of a Function¶

Imagine we want to compute the sum of 3 variables.

Type the following code in a text editor:

```
function xSum = sum3(x1, x2, x3);
% This function sums 3 variables
sum1 = x1 + x2;
xSum = sum1 + x3;
end
```

Save it as `sum3.m`

in a directory Matlab knows to find.

Row 1 defines the name of the function, its input arguments and its output arguments.

Row 2 is a comment starting with %. Matlab ignores it.

Rows 3 and 4 contain the commands to be executed.

To run `sum3.m`

:
At the command prompt type

```
sum3(1, 2, 3)
ans =
6
```

To illustrate that the variables inside `sum3.m`

are private, try typing `sum1`

at the command prompt. The result:

```
??? Undefined function or variable 'sum1'.
```

Matlab complains that variable `sum1`

does not exist.

`sum1`

was visible inside of sum3.m, but not outside of it.

## More on Private Variables¶

Variables inside of `sum3.m`

are also not visible in functions called from within `sum3.m`

.

**Example**

Modify `sum3.m`

to read:

```
function xSum = sum3(x1, x2, x3);
sum1 = x1 + x2;
sum3sub;
xSum = sum1 + x3;
end
```

Then create the function:

```
function sum3sub
disp(sum1)
end
```

Running `sum3.m`

results in an error: sum1 is not found.

## Global Variables¶

To make a variable visible from anywhere, define it as a `global`

(in `sum3.m`

and `sum3sub.m`

):

```
global sum1;
```

Now running `sum3.m`

does not yield an error message.

Remark: Avoid globals where possible.

A function should be a self-contained unit with a clear interface to the outside world (via its input and output arguments).

Globals create confusion.

## Nested Functions¶

If you need a function to see the local variables in another function, nest it inside the other function.

Example:

```
function f
a = 5;
disp(g(17));
% After calling g(), a == 52
% Nested function can see `a`
function z = g(x)
z = x + a;
a = 52;
end
end
```

The main use of this: optimization. See below.

## Passing by Value¶

In Matlab, all function arguments are passed **by value**.

That means, Matlab creates a copy of the variable and passes it to the function.

However, Matlab is smart enough not to create a copy when the function does not change the variable (“copy on change”).

Still, this can be very inefficient. If you pass a gigantic array to a function and change one element inside the function, the entire array needs to be copied.

There is no way of passing by reference.

## Examples¶

### Example: Cobb-Douglas production function¶

This is a general purpose Cobb-Douglas function

Notable features:

block comment describing inputs and outputs

this is all the rest of the world needs to know about the function

a unique name

self-test code governed by debugging switch

`dbg`

### Example: Finding the Zero of a Function¶

Task: Find the solution to the equation \(f(x)=\ln(x)-5=0 \).

Set up a function that returns the deviation f(x)

```
function dev = dev1_821(x);
dev = log(x) - 5;
end
```

Use the built-in function `fzero`

to search for the solution:

```
fzero('dev1_821', [0.1 100])
ans =
7.3891
```

What if I want to pass additional parameters to the objective function? Make it a nested function.

Example here.

## Example: Two period household¶

Household solves \(\max u\left(c,g\right)\)

subject to \(y=c+s \) and \(g=z+sR\)

A solution: \(c,g,s\)

that solve 2 budget constraints and Euler equation

\(u_{c}=u_{g} R \)

Assume \(u\left(c,g\right)=\frac{c^{1-\sigma}}{1-\sigma}+\beta\frac{g^{1-\sigma}}{1-\sigma} \)

### Pseudo code¶

This is not a trivial program to write. So we break it down into trivial steps.

We design top-down.

#### Level 1:¶

Task: Find optimal \(c\).

- Set parameters. Set up a grid of values for c
- For each c: Calculate deviation from Euler equation.
- Find the c with the smallest deviation.

Note: Usually one would not restrict \(c\) to lie on a grid.

#### Level 2:¶

Task: Calculate deviation from Euler equation.

Given: guess for \(c\), parameter values

- Use budget constraints to calculate \(s,g\)
- Return deviation: \( dev=u_{c}-u_{g}R \)

### Code¶

We write the code bottom up.

Utility function:

- Allow matrix inputs (cM, gM).
- Parameters as arguments.
- This should really be a general purpose function (my library contains an OOP version).

Sample call:

```
>> hh_example_821(2, 0.5, 1.04, 0.9, 1.5)
c = 1.224490 Dev = 0.034947
```

## Exercises¶

- Write a CES utility function that computes \(u’(c)\) and \(u(c)\).
- Write a function that computes the inverse of \(u’(c)\).
- Write a test function that checks properties of the utility function: 4. The inverse of the inverse equals \(u’(c)\). 5. Marginal utility is decreasing.

Extra credit:

- Package all of that into an object (a user defined data type).
- Now write all of this for \(u(c)=e^{-\phi c}\).
- In your test function, set things up so that you only need to change a single line of code to test both utility functions (the benefit of OOP in action).