- Transition to Processing
- Primitive Operations
- Algorithms
- Variables
- Debugging in Processing
- Conditions
- Loops
- Functions
- Scope
- Compound Data
- Reference Semantics
- Refactoring
- Program Design
- Transition to Java
- Debugging in Java
- Unit Testing
- Classes - Writing your own Types
- Classes - Copying objects
- Classes - Functions inside objects
- Classes - Composition
- Classes - Array of objects
- Classes - Class holding array(s)
- Recursion - What goes on during a function call
- Recursion
- Recursion with String data
- Tail-optimized recursion
- Recursion with arrays
- Lists
- Iteration
- Custom-built ArrayList
- Recursive data structures - 1
- Recursive data structures - 2
- Searching

- Logic and Proofs
- Relations
- Mathematical Functions
- Matrices
- Binary Numbers
- Trigonomtry
- Finite State Machines
- Turing Machines
- Counting - Inclusion/Exclusion
- Graph Algorithms

- Algorithm Efficiency
- Algorithm Correctness
- Trees
- Heaps, Stack, and Queues
- Maps and Hashtables
- Graphs and Graph Algorithms
- Advanced Trees and Computability

- Command line control
- Transition to C
- Pointers
- Memory Allocation
- IO
- Number representations
- Assembly Programming
- Structs and Unions
- How memory works
- Virtual Memory

- Version Control with Git
- Inheritance and Overloading
- Generics
- Exceptions
- Lambda Expressions
- Design Patterns
- Concepts of Concurrency
- Concurrency: Object Locks
- Modern Concurrency

- System Models
- Naming and Distributed File Systems
- Synchronisation and Concurrency
- Fault Tolerance and Security
- Clusters and Grids
- Virtualisation
- Data Centers
- Mobile Computing

- Transition to Scala
- Functional Programming
- Syntax Analysis
- Name Analysis
- Type Analysis
- Transformation and Compilation
- Control Abstraction
- Implementing Data Abstraction
- Language Runtimes

- Transition to Coq
- Proof by Induction, Structured Data
- Polymorphism and Higher-Order Functions
- More Basic Tactics
- Logical Reasoning in Proof Assistants
- Inductive Propositions
- Maps
- An Imperative Programming Language
- Program Equivalence
- Hoare Logic
- Small-Step Operational Semantics
- Simply-typed Lambda Calculus

- Know the syntax of functions
- Understand how functions relate to algorithms
- Be able to pass values into a function
- Be able to get values back from a function
- Be able to write your own functions
- Be able to reason about the flow of a program that uses functions

A function is a named piece of code that can be supplied with some inputs (known as parameters) and may return a value back to the caller.

Chapter 7 of Learning Processing by Danel Shiffman.

Let’s be precise about functions.

For example, we may have a function that determines the higher of two integers. We can call it by passing it two integers. If we pass the values 2 and 5, it should return 5.

However, if we pass only one value, it cannot be executed, as it expects two integers.

Similarly, you cannot pass it more than 2 values.

Even if you pass two values, you must ensure they are of the right type. For example, we cannot pass a `boolean`

instead of an integer.

All functions have *just one* function definition - the place that the function itself is described. Syntax of a function *definition* is:

1
2
3
4
5
6
7
8

returnType function(<parameters>) {
<some code>
<if>
<return statement>
<endif>
<some code>
<return statement>
}

Once this exists, you can have *many* function calls - the place that the code asks the function to run. Syntax of a function *call* is:

1

functionName (<parameters>);

For example, the following function *definition*

1
2
3

int foo(int a, int b){
return a + b;
}

can be run by any of these function *calls*

1
2
3

int t = foo(1,3);
int y = foo(12, 13);
int z = foo(foo(1,3), 8)

Note the feature in the above example, anywhere an `int`

is expected, you can put a calls to `foo`

because it returns an `int`

.

Since we have both function definitions and function calls, and parameters appear in each, it is useful to be able to distinguish the two uses.

- Parameters appearing in the top line (signature) of a function definition are called
*formal parameters*and are defined in the same way as any other variable declaration - Parameters appearing in a function call are called
*actual paramters*and work like any other value in Processing.

When the function is executed, the actual paramters are copied into the formal paramter slots and the function is run.

Suppose we have a function that accepts a real number (`double`

) and returns its square.

Draw a block diagram for the interaction when a caller calls the function with the value 2.5. Assume the name of the formal parameter is `val`

, and the value returned by the function is copied into a variable `sqr`

.

Consider the following function definition,

1
2
3

int roundOff(float a) {
return (int)(a+0.5);
}

Write a statement that calls the function `roundOff`

with the parameter 6.8 and stores the value returned in a variable `result`

.

1
2

int result;
result = roundOff(6.8);

Which of the following are valid calls to function `roundOff`

?

`int a = roundOff(4.5);`

`int b = roundOff(8);`

`roundOff(2.6);`

`float c = roundOff(-1.53);`

`int d = roundOff(3.2, 4.8);`

`int e = roundOff();`

`int e = roundOff(true);`

- Yes
- Yes, the integer is treated like a float when it arrives in the formal parameter. It is identical to writing
`float a = 8`

- Yes, the return value is thrown away, but that is allowed
- Yes, the return value is treated like a float when it arrives in
`c`

- No, too many actual parameters
- No, not enough acutal parameters
- No, actual parameter type does not match formal parameter type.

Define a function that when passed two integers, returns their average. Remember that 15/2 is 7 while 15/2.0 is 7.5.

1
2
3

float average(int a, int b){
return (a + b)/2.0;
}

- function declarations are statements.
- function calls are statements if the function returns
`void`

. - function calls are statements
*and*expressions if they return a value. - formal parameters are statements.
- actual parameters are expressions.

The fact that a function call in processing can *do* something and also *evaluate to a value* makes them special. In fact, this double-life is a bit of a point of friction in language design. Some languages insist that functions must be statements and others insist they must be expressions, but those are rare. The situation we have here, while strange, is quite common.

Define a function that when passed an integer, returns the number of digits in the integer.

1
2
3
4
5
6
7
8

int digits(int input){
int totalSoFar = 0;
while (input > 0) {
totalSoFar++;
intput = input / 10;
}
return totalSoFar;
}

Given two integers (store in formal parameters `a, b`

), define a function that determines if either of them is divisible by the other. Some input-output mappings are:

`a = 14, b = 6`

–> return`false`

`a = 14, b = 7`

–> return`true`

`a = 9, b = 30`

–> return`false`

`a = 9, b = 36`

–> return`true`

`a = 12, b = 0`

–> return`true`

(0 is divisible by 12)

1
2
3

boolean isDivisible(int a, int b){
return (a % b) == 0;
}

An year is leap if it satisfies one of the two conditions,

- it’s divisible by 400, or,
- it’s divisible by 4 but
**NOT**by 100.

Define a function that determines if an year passed (store in formal parameter `year`

) is `leap`

. Return `true`

if it’s a leap year, and `false`

otherwise. Some input-output mappings are:

`year = 2016`

–> return`true`

`year = 1800`

–> return`false`

`year = 2018`

–> return`false`

`year = 1600`

–> return`true`

1
2
3

boolean isLeapYear(int year){
return (isDivisible(year, 400) || (isDivisible(year, 4) && !isDivisible(year 100)));
}

I would like to count the number of non-trivial (apart from 1 and itself) divisors of a given integer. Some input-output mappings are:

`n = 18`

–> return`4`

(as there are 4 non-trivial divisors: 2, 3, 6, 9)`n = 31`

–> return`0`

(as there is no non-trivial divisor of 31)`n = 77`

–> return`2`

(as there are 2 non-trivial divisors: 7, 11)

1
2
3
4
5
6
7
8
9

int divisors(int input){
found = 0;
for(int i = 2; i < input; i++){
if (isDivisible(input, i){
found++;
}
}
return found;
}