(.module: [lux #* ["." debug] [control ["." try (#+ Try)] ["." exception (#+ exception:)]] [data [text ["%" format (#+ format)]]] [macro (#+ with-gensyms) ["." syntax (#+ syntax:)]] ["." type abstract]]) (exception: #export (wrong-type {expected Type} {actual Type}) (exception.report ["Expected" (%.type expected)] ["Actual" (%.type actual)])) (abstract: #export Dynamic {#.doc "A value coupled with its type, so it can be checked later."} [Type Any] (def: dynamic-abstraction (-> [Type Any] Dynamic) (|>> :abstraction)) (def: dynamic-representation (-> Dynamic [Type Any]) (|>> :representation)) (syntax: #export (:dynamic value) {#.doc (doc (: Dynamic (:dynamic 123)))} (with-gensyms [g!value] (wrap (list (` (let [(~ g!value) (~ value)] ((~! ..dynamic-abstraction) [(:of (~ g!value)) (~ g!value)]))))))) (syntax: #export (:check type value) {#.doc (doc (: (try.Try Nat) (:check Nat (:dynamic 123))))} (with-gensyms [g!type g!value] (wrap (list (` (let [[(~ g!type) (~ g!value)] ((~! ..dynamic-representation) (~ value))] (: ((~! try.Try) (~ type)) (if (:: (~! type.equivalence) (~' =) (.type (~ type)) (~ g!type)) (#try.Success (:coerce (~ type) (~ g!value))) ((~! exception.throw) ..wrong-type [(.type (~ type)) (~ g!type)]))))))))) (def: #export (print value) (-> Dynamic (Try Text)) (let [[type value] (:representation value)] (debug.represent type value))) )