singly-linked list
See also

 Array
 Associative array: Creation, Iteration
 Collections
 Compound data type
 Doubly-linked list: Definition, Element definition, Element insertion, List Traversal, Element Removal
 Linked list
 Queue: Definition, Usage
 Set
 Singly-linked list: Element definition, Element insertion, List Traversal, Element Removal
 Stack
abstract type AbstractNode{T} end
 
struct EmptyNode{T} <: AbstractNode{T} end
mutable struct Node{T} <: AbstractNode{T}
    data::T
    next::AbstractNode{T}
end
Node{T}(x) where T = Node{T}(x::T, EmptyNode{T}())
 
mutable struct LinkedList{T}
    head::AbstractNode{T}
end
LinkedList{T}() where T = LinkedList{T}(EmptyNode{T}())
LinkedList() = LinkedList{Any}()
 
Base.isempty(ll::LinkedList) = ll.head isa EmptyNode
function lastnode(ll::LinkedList)
    if isempty(ll) throw(BoundsError()) end
    nd = ll.head
    while !(nd.next isa EmptyNode)
        nd = nd.next
    end
    return nd
end
 
function Base.push!(ll::LinkedList{T}, x::T) where T
    nd = Node{T}(x)
    if isempty(ll)
        ll.head = nd
    else
        tail = lastnode(ll)
        tail.next = nd
    end
    return ll
end
function Base.pop!(ll::LinkedList{T}) where T
    if isempty(ll)
        throw(ArgumentError("list must be non-empty"))
    elseif ll.head.next isa EmptyNode
        nd = ll.head
        ll.head = EmptyNode{T}()
    else
        nx = ll.head
        while !isa(nx.next.next, EmptyNode)
            nx = nx.next
        end
        nd = nx.next
        nx.next = EmptyNode{T}()
    end
    return nd.data
end
 
lst = LinkedList{Int}()
push!(lst, 1)
push!(lst, 2)
push!(lst, 3)
pop!(lst) # 3
pop!(lst) # 2
pop!(lst) # 1