Home > CS4080: Programming Languages > List and UnionsList and Unions
List: ADT defined as a sequence of element, usually of the same type.
Appears in the definition of some languages.
- e.g., Functional languages can’t have arrays (arrays need constructive updates, which are forbidden), so they define lists in their language.
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.
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: Data types that are the union multiple other data typrs
These things are useless in OOP languages.
- Useful in C because you lack polymorphism.
// Define
union U is
int x
String S
end union
// Usage
U a := new U
int b := 42
int c := TODO
Variables that hold memory addresses (L-values).
Pointers
char* str = "Hello";
+= 1;
str ;
print str// "ello"
References
= "Hello";
String str // can't do str += 1;
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 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”
- i.e., stuff without pointers to it
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.
Generations:
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.
- e.g., variables in a typical function or loop counter are usually only used for a few milliseconds
Suppose you have three generations:
We’ll collect Gen 0 really often, and very rarely from Gen 2.
Java has a 3-generational mark and sweep garbage collector.