// A linked list uses nullable links and mutable object fields.
// let fixes the binding; methods may still update the object's var fields.
class Node {
    public let value: Int64
    public var next: Node?

    fn get() {
        return value
    }
}

class LinkedList {
    public var head: Node?

    fn push(value: Int64) {
        head = Node(value: value, next: head)
    }

    fn len() {
        var count = 0
        var cursor = head
        while cursor != null {
            let node = cursor.unwrap()
            count = count + 1
            cursor = node.next
        }
        return count
    }

    fn sum() {
        var total = 0
        var cursor = head
        while cursor != null {
            let node = cursor.unwrap()
            total = total + node.value
            cursor = node.next
        }
        return total
    }
}

let numbers = LinkedList(head: null)
numbers.push(30)
numbers.push(20)
numbers.push(10)
print("Length")
print(numbers.len())
print("Sum")
print(numbers.sum())
print("First value")
print(numbers.head.unwrap().get())
let alias = numbers
print("Aliases share identity")
print(alias == numbers)
alias.push(5)
print("Length after an update through the alias")
print(numbers.len())
