Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Push, pop, and walk an owned chain

Each node owns its successor. Insertion allocates before transferring the old head so a failed allocation preserves the caller’s chain. Pop transfers the successor out before destroying the removed node.

pub class Node:
    pub value: i64
    pub next: Option[Box[Node]]

pub class Linked:
    pub head: Option[Box[Node]]

pub def push(xs: &mut Linked, value: i64) -> Result[(), AllocError]:
    mut node = Box(Node(value, Nothing))?
    node.next = replace(xs.head, Nothing)
    xs.head = Some(node)
    Ok(())

pub def pop(xs: &mut Linked) -> Option[i64]:
    match replace(xs.head, Nothing):
        case Some(node):
            mut removed: Node = node
            xs.head = replace(removed.next, Nothing)
            Some(removed.value)
        case Nothing:
            Nothing

pub def bump(xs: &mut Linked) -> Result[(), OverflowError[i64]]:
    match &mut xs.head:
        case Some(head):
            mut cursor: &mut Node = head
            while True:
                cursor.value += 1
                match &mut cursor.next:
                    case Some(next):
                        cursor = next
                    case Nothing:
                        break
        case Nothing:
            pass
    Ok(())
from linked import Linked, push, pop, bump

def main() -> Result[(), AllocError | IoError | OverflowError[i64]]:
    mut xs = Linked(Nothing)
    for value in range(1, 4):
        push(&mut xs, value)?
    bump(&mut xs)?
    print(pop(&mut xs))?
    print(pop(&mut xs))?
    print(pop(&mut xs))?
    print(pop(&mut xs))?
    Ok(())
Option[i64].Some(4)
Option[i64].Some(3)
Option[i64].Some(2)
Option[i64].Nothing

cursor advances by borrowing from its current referent. It does not create stored references or require a recursive call. Pop and this traversal allocate nothing. bump propagates overflow and retains increments already performed; it does not roll back the chain. Each successful push allocates one box; its failure destroys the incoming value, not the existing chain.

This is a teaching module with public links, not a packaged collection that enforces an abstract API. Use a contiguous list for an ordinary stack unless the workload benefits from separate nodes. See representation choices.