;;;; A data type a package exports, which is what vendor/edn's Value needed. ;;;; ;;;; A struct imports by renaming one name. A data type has a second half — the ;;;; case table — and the question this package exists to answer is where each ;;;; half ends up. The answer is that a case is not a top-level name: it has no ;;;; existence apart from its type, so the only thing to qualify is the [Node.] ;;;; in front of it, and an importer's [(Leaf n)] pattern stays bare because it ;;;; resolves against the scrutinee's type and never against a name. (defdata Node [(Leaf [n i64]) (Branch [kids (Vec Node)]) (Empty [])]) ;; Built inside the package, where the constructor is written unqualified and ;; the import has to rewrite it. (defn leaf [n i64] Node (Node.Leaf {.n n})) ;; A case with no fields is a value and not a call, so this is the [Var] node ;; where the others are [Struct] nodes — the second shape the rename has to ;; catch, and the one it is easy to catch only half of. (defn nothing [] Node Node.Empty) (defn total [t Node] i64 (match t (Leaf n) n (Branch kids) (let [s (i64 0)] (dotimes [i (len kids)] (set s (+ s (total (at kids i))))) s) Empty (i64 0)))