Subprograms and Functions

Procedural abstraction is the most important advancements in programming language technology.

Subprograms

Named sequence of statements that can be invoked from other places in the program.

There are four categories:

  1. Subroutines: No input/output
  2. Procedures: Input, no output
  3. Functions: Input and Output
  4. Methods: Function works in the context of a specific object.
Example: General Syntax
fun T_n fname (T_1 : p_1, T_2 : p_2, ..., T_n : p_n) is S end

Function Signature:

Compressed Signature: Like the function signature, except it lacks the return type.

Other:

Parameter Passing

There are two way parameters can be passed. (This is something you must specify)

  1. Pass by Value Copy: Pass a copy of the value. (R-value)
  2. Pass by Reference: Pass the memory address of the thing. (L-value)
Example: Real-World Use (TODO)

So the argument is everything is pass by value? And pass by reference is simulated (?).

In C

A *p : malloc(sizeof(A));
// you can do p += 1

In Java

A p : new A();
// this is an object, you cannot do p += 1
// you cannot type cast p as int

Parameter Profiles

List of parameters for a function, their type, and formatting features.

With IDEs, what parameter profile you chose doesn’t really matter.

Positional Parameters

The most common method to define these is with positional parameters, where order specifies what is bound where.

Example: Positional Parameters
fun f(x,y) is
  ...
end
z := call f(3,7)

This binds the 3 \to x, and 7 \to y, because of their position.

Keyword Parameters

Here, we don’t care about order, and instead say what is bound to what.

Example: Keyword Parameters
fun f(x,y,z) is
  ...
end
z := call f(z:=3,x:=7,y:=0)

The order no longer matters because we explicitly say what is bound to what.

Default Parameter Values

Some languages let you specific default values easily.

Example: Default Parameters
fun f(x,y:=0,z:0) is
  ...
end
z := call f(x:=1)

On Relation to Positional and Keyword:

You typically need keyword parameters to do this.

If you want to do this with a positional parameter system, only the last parameters can be default parameters.

Design Issues

  1. Statically Allocated Locals: Local variables in functions which are allocated statically (aka: they reside in the data section) persist between function calls
  2. Are nested functions allows?
Example: Nested Function
fun f() is
  ...
  fun helper_g() {
      ...
  }
end

This lets you avoid polluting the namespace with helper functions.

  1. Can functions be arguments to other functions?
Example: Function as Arguments
fun apply(f, arr) is
  arr.forEach((elem) \rightarrow {
      f(elem)
  });
end

In OOP languages like Java, we can simulate this by creating a class whose only reason to exist is to have a method; and pass that object around instead.

  1. Function closures

Recall — Closure: A function definition that is not only the code, but also an attached context to it that has binding to one or more locals/parameters.

Example: Function Closures
fun f(x,y) is
  return x \text{$+$} y
end fun
# This returns a function that only takes one arg
# This function just does x+1
fun plusOne := f(1)

Can be use to easily create families of functions, where an argument is a polymorphic type.

Example: Tuples v. Chain

Functional languages do this by defining functions not a tuples, but as a chain.

Suppose

fun(x,y) is R
  ...
end

Non Functional: Tuples f: T \times S \to R

Functional: f: T \to S \to R

Lambdas

Lambdas: Anonymous (nameless) functions