~subsetpark/fugue

9ace4f7ab28f7bf91b0931fe7fd760e8fbf8b947 — Zach Smith 13 days ago 3cf67c4 multi-types
[wip] type narrowing in multimethods
1 files changed, 14 insertions(+), 12 deletions(-)

M fugue.janet
M fugue.janet => fugue.janet +14 -12
@@ 1,3 1,4 @@
(import /multi-types)
#
# Bootstrapping
#


@@ 386,21 387,22 @@
#
# Multimethod Helpers
#
(defn types-or-names
  [types-or-objs]
  (freeze (map (fn [type-or-obj]
                 (match type-or-obj
                   {:_name name} name
                   type type))
               types-or-objs)))

(defn- get-cases
  [name store]
  (as-> name .
        (store .)
        (pairs .)
        # Total hack: rely on the fact that `nil` is the smallest
        # value. Thus, when sorted, cases should always have the base
        # case last for any positional argument.
        #
        # ie: [:string :string]
        #     [:string :_]
        #     [:_ :number]
        #     [:_ :_]
        (sort . >)))
  (let [type-cases (-> name (store) (pairs))
        sorted (multi-types/sort-types type-cases)]
    (unless (deep= sorted (-> type-cases (reverse) (multi-types/sort-types)))
      (let [types-only (->> type-cases (map 0) (map types-or-names))]
           (errorf "multi-type ambiguity: %q" types-only)))
    sorted))

(defn- replace-placeholder-symbols
  [types]