List and Unions

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

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

TODO I don’t understanding returning head and tail’s explanation

Union

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

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 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 causing dead pointers.

Example: Aliasing
// Aliasing
p \to 0x0
q \to 0x0
// Free q
free q
// p has no idea it points to junk

Garbage Collection

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

Typically runs every few hundred milliseconds.

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.