Skip to content

Instantly share code, notes, and snippets.

@stianeikeland
Last active August 29, 2015 14:10
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save stianeikeland/a7a3f03950147e787aba to your computer and use it in GitHub Desktop.
variant core.typed
(ns variants-playground.core
(:require [clojure.core.typed :as t :refer [cf defalias ann U Value Str HVec HMap]]
[clojure.core.match :refer [match]]))
(defmacro Variant [& lst]
`(U ~@(for [[tag & items] lst]
`(HVec [(Value ~tag)
(HMap :mandatory ~@items)]))))
(println (macroexpand '(Variant [:foo {:bar Str}])))
;; => (clojure.core.typed/U (clojure.core.typed/HVec [(clojure.core.typed/Value :foo) (clojure.core.typed/HMap :mandatory {:bar Str})]))
(cf [:foo {:bar "FizzBuzz"}]
(Variant [:foo {:bar Str}]))
;; => Internal Error (:<NO LINE>) Incorrect function syntax: [:foo {:bar Str}]
(cf [:foo {:bar "FizzBuzz"}]
(clojure.core.typed/U
(clojure.core.typed/HVec
[(clojure.core.typed/Value :foo)
(clojure.core.typed/HMap :mandatory {:bar clojure.core.typed/Str})])))
;; .. but works just fine by pasting result from macroexpand.
;; => [(HVec [(t/Val :foo) (HMap :mandatory {:bar (t/Val FizzBuzz)} :complete? true)]) {:then tt, :else ff}]
@stianeikeland
Copy link
Author

Macro expansion seems fine, but fails on cf / defalias / etc.. :/

@jneen
Copy link

jneen commented Nov 24, 2014

I wonder if doing it with a regular function would work better?

(defn Variant [& clauses]
  (apply U (for [[tag & items] clauses]
             (HVec [(Value tag) & items]))))  

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment