flan/test/programs/pkgs/tree/tree.flan
Joseph Ferano ca031d6b38 Every tracked Flan file is what the indenter would write, and a with- head indents its body like a definer
clojure-mode decided each shape. A with- head, and a def or with- head behind a namespace, indents as a body; a qualified head finds its unqualified spec. The rest was hand formatting: cond and match results under their tests, ordinary call arguments under the first one, and lone ; continuation comments rewritten as ;; lines above the code.
2026-09-25 10:19:22 +07:00

33 lines
1.2 KiB
Plaintext

;;;; 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 (length kids)]
(set s (+ s (total (at kids i)))))
s)
Empty (i64 0)))