Records & Tuples, Lists & Unions, Pointers & References, and Garbage Collection

Record

Record: Aggregates multiple values of potentially different types.

Example: A record
// Declaration
record Student is
  string first-name
  string last-name
  int id
end record
// Instantiation
Student freddy := new Student
tag first-name := "Friedrich"
tag last-name := "Engels"
tag id := 1895

Important: Note the lack of data hiding. This is for abstraction, not encapsulation.

Tuple

Tuple; Aggregates values of potentially different types.

In most languages, tuples are immutable.

More on Tuples and Records — Object Oriented languages lack records because they already have objects. Tuples are also unnecessary if you have arrays.

Lists

List: ADT defined as a sequence of element, usually of the same type.

Appears in the definition of some languages.

Implementation

1. Linked List: The obvious.

2. Array: You could also implement a linked-list with arrays (e.g., buffered arrays, etc.)

In functional languages, option 1 is the only option.

Other Operations

Note — If you have singly-linked list, prepending is O(1), but appending is O(n).

Union

Union: Data types that are the union multiple other data typrs

Note — These things are useless in OOP languages.

// Define
union U is
    int x
    String S
end union
// Usage
U a := new U
int b := 42
int c := TODO

Pointers and References

Variables that hold memory addresses (L-values).

Example: Pointers and References

Pointers

char* str = "Hello";
str += 1;
print str;
// "ello"

References

String str = "Hello";
// can't do str += 1; 

Lifetime and Scope

In most languages, pointers and references are always active from creation to deallocation.

Example: Memory Leak
func f is
  ...
  D x := new D
  ...
// (end without deallocating)
end f

Another issue is aliasing, where we can have two references to the same thing and don’t fully deallocate (dangling pointers).

Example: Aliasing and Dangling Pointers
// Aliasing
p \to 0x0
q \to 0x0

// Free q
free q
// p has no idea it points to junk

Type Compatability

Two types are compatabile if we can assign one type to another.

Garbage Collection

Garbage Collector: Runtime support program that periodically identifiers and deallocates garbage.

Practice — In practice, because GC is undecidable, we simplify the definition to be “garbage is unreachable resources”

Algorithm: Naive Mark and Sweep

  1. Mark: Traverse through every variable/object/field accessible from the top context (and their children).
  2. Sweep: Deallocate all unmarked resources.

Memory leaks happen in the heap — Notice how you only have to do this on the heap, as stuff is never deallocated on the stack.

Algorithm: Generational Mark and Sweep

Generations:

  1. Break the heap into multiple generations.
  2. After some fixed time, you promote an object to the next (older) generation.

We’ll garbage collect more often from the younger generation than the older generations.

Why — Objects with a limited lifetime usually have a really short lifetime.

Example: Generational Mark and Sweep

Suppose you have three generations:

  1. Gen 0: Recently allocated objects
  2. Gen 1: Relatively older objects
  3. Gen 2: Oldest Objects

We’ll collect Gen 0 really often, and very rarely from Gen 2.

Java has a 3-generational mark and sweep garbage collector.

Type Equivalence

Two types T and S are equivalent, if whenver one is expected, the other may be used.

Example:

We say type S is compatible with type T if anything of type S can be assignment to type T