aboutsummaryrefslogtreecommitdiff
path: root/stdlib
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--stdlib/source/lux/control/parser/type.lux348
-rw-r--r--stdlib/source/lux/macro/poly.lux376
-rw-r--r--stdlib/source/lux/macro/poly/equivalence.lux57
-rw-r--r--stdlib/source/lux/macro/poly/functor.lux49
-rw-r--r--stdlib/source/lux/macro/poly/json.lux115
-rw-r--r--stdlib/source/test/lux.lux7
6 files changed, 487 insertions, 465 deletions
diff --git a/stdlib/source/lux/control/parser/type.lux b/stdlib/source/lux/control/parser/type.lux
new file mode 100644
index 000000000..56942e5c4
--- /dev/null
+++ b/stdlib/source/lux/control/parser/type.lux
@@ -0,0 +1,348 @@
+(.module:
+ [lux (#- function log!)
+ [abstract
+ ["." monad (#+ do)]]
+ [control
+ ["." exception (#+ exception:)]
+ ["." function]]
+ [data
+ ["." name ("#@." codec)]
+ ["." error (#+ Error)]
+ [number
+ ["." nat ("#@." decimal)]]
+ ["." text ("#@." monoid)
+ format]
+ [collection
+ ["." list ("#@." functor)]
+ ["." dictionary (#+ Dictionary)]]]
+ [macro
+ ["." code]]
+ ["." type ("#@." equivalence)
+ ["." check]]]
+ ["." // (#+ Parser)])
+
+(template [<name>]
+ [(exception: #export (<name> {type Type})
+ (exception.report
+ ["Type" (%type type)]))]
+
+ [not-existential]
+ [not-recursive]
+ [not-named]
+ [not-parameter]
+ [unknown-parameter]
+ [not-function]
+ [not-application]
+ [not-polymorphic]
+ [not-variant]
+ [not-tuple]
+ )
+
+(template [<name>]
+ [(exception: #export (<name> {expected Type} {actual Type})
+ (exception.report
+ ["Expected" (%type expected)]
+ ["Actual" (%type actual)]))]
+
+ [types-do-not-match]
+ [wrong-parameter]
+ )
+
+(exception: #export (unconsumed {remaining (List Type)})
+ (exception.report
+ ["Types" (|> remaining
+ (list@map (|>> %type (format text.new-line "* ")))
+ (text.join-with ""))]))
+
+(type: #export Env
+ (Dictionary Nat [Type Code]))
+
+(type: #export (Poly a)
+ (Parser [Env (List Type)] a))
+
+(def: #export fresh Env (dictionary.new nat.hash))
+
+(def: (run' env types poly)
+ (All [a] (-> Env (List Type) (Poly a) (Error a)))
+ (case (//.run [env types] poly)
+ (#error.Failure error)
+ (#error.Failure error)
+
+ (#error.Success [[env' remaining] output])
+ (case remaining
+ #.Nil
+ (#error.Success output)
+
+ _
+ (exception.throw unconsumed remaining))))
+
+(def: #export (run type poly)
+ (All [a] (-> Type (Poly a) (Error a)))
+ (run' fresh (list type) poly))
+
+(def: #export env
+ (Poly Env)
+ (.function (_ [env inputs])
+ (#error.Success [[env inputs] env])))
+
+(def: (with-env temp poly)
+ (All [a] (-> Env (Poly a) (Poly a)))
+ (.function (_ [env inputs])
+ (case (//.run [temp inputs] poly)
+ (#error.Failure error)
+ (#error.Failure error)
+
+ (#error.Success [[_ remaining] output])
+ (#error.Success [[env remaining] output]))))
+
+(def: #export peek
+ (Poly Type)
+ (.function (_ [env inputs])
+ (case inputs
+ #.Nil
+ (#error.Failure "Empty stream of types.")
+
+ (#.Cons headT tail)
+ (#error.Success [[env inputs] headT]))))
+
+(def: #export any
+ (Poly Type)
+ (.function (_ [env inputs])
+ (case inputs
+ #.Nil
+ (#error.Failure "Empty stream of types.")
+
+ (#.Cons headT tail)
+ (#error.Success [[env tail] headT]))))
+
+(def: #export (local types poly)
+ (All [a] (-> (List Type) (Poly a) (Poly a)))
+ (.function (_ [env pass-through])
+ (case (run' env types poly)
+ (#error.Failure error)
+ (#error.Failure error)
+
+ (#error.Success output)
+ (#error.Success [[env pass-through] output]))))
+
+(def: (label idx)
+ (-> Nat Code)
+ (code.local-identifier ($_ text@compose "label" text.tab (nat@encode idx))))
+
+(def: #export (with-extension type poly)
+ (All [a] (-> Type (Poly a) (Poly [Code a])))
+ (.function (_ [env inputs])
+ (let [current-id (dictionary.size env)
+ g!var (label current-id)]
+ (case (//.run [(dictionary.put current-id [type g!var] env)
+ inputs]
+ poly)
+ (#error.Failure error)
+ (#error.Failure error)
+
+ (#error.Success [[_ inputs'] output])
+ (#error.Success [[env inputs'] [g!var output]])))))
+
+(template [<name> <flattener> <tag> <exception>]
+ [(def: #export (<name> poly)
+ (All [a] (-> (Poly a) (Poly a)))
+ (do //.monad
+ [headT any]
+ (let [members (<flattener> (type.un-name headT))]
+ (if (n/> 1 (list.size members))
+ (local members poly)
+ (//.fail (exception.construct <exception> headT))))))]
+
+ [variant type.flatten-variant #.Sum not-variant]
+ [tuple type.flatten-tuple #.Product not-tuple]
+ )
+
+(def: polymorphic'
+ (Poly [Nat Type])
+ (do //.monad
+ [headT any
+ #let [[num-arg bodyT] (type.flatten-univ-q (type.un-name headT))]]
+ (if (n/= 0 num-arg)
+ (//.fail (exception.construct not-polymorphic headT))
+ (wrap [num-arg bodyT]))))
+
+(def: #export (polymorphic poly)
+ (All [a] (-> (Poly a) (Poly [Code (List Code) a])))
+ (do //.monad
+ [headT any
+ funcI (:: @ map dictionary.size ..env)
+ [num-args non-poly] (local (list headT) polymorphic')
+ env ..env
+ #let [funcL (label funcI)
+ [all-varsL env'] (loop [current-arg 0
+ env' env
+ all-varsL (: (List Code) (list))]
+ (if (n/< num-args current-arg)
+ (if (n/= 0 current-arg)
+ (let [varL (label (inc funcI))]
+ (recur (inc current-arg)
+ (|> env'
+ (dictionary.put funcI [headT funcL])
+ (dictionary.put (inc funcI) [(#.Parameter (inc funcI)) varL]))
+ (#.Cons varL all-varsL)))
+ (let [partialI (|> current-arg (n/* 2) (n/+ funcI))
+ partial-varI (inc partialI)
+ partial-varL (label partial-varI)
+ partialC (` ((~ funcL) (~+ (|> (list.indices num-args)
+ (list@map (|>> (n/* 2) inc (n/+ funcI) label))
+ list.reverse))))]
+ (recur (inc current-arg)
+ (|> env'
+ (dictionary.put partialI [.Nothing partialC])
+ (dictionary.put partial-varI [(#.Parameter partial-varI) partial-varL]))
+ (#.Cons partial-varL all-varsL))))
+ [all-varsL env']))]]
+ (|> (do @
+ [output poly]
+ (wrap [funcL all-varsL output]))
+ (local (list non-poly))
+ (with-env env'))))
+
+(def: #export (function in-poly out-poly)
+ (All [i o] (-> (Poly i) (Poly o) (Poly [i o])))
+ (do //.monad
+ [headT any
+ #let [[inputsT outputT] (type.flatten-function (type.un-name headT))]]
+ (if (n/> 0 (list.size inputsT))
+ (//.and (local inputsT in-poly)
+ (local (list outputT) out-poly))
+ (//.fail (exception.construct not-function headT)))))
+
+(def: #export (apply poly)
+ (All [a] (-> (Poly a) (Poly a)))
+ (do //.monad
+ [headT any
+ #let [[funcT paramsT] (type.flatten-application (type.un-name headT))]]
+ (if (n/= 0 (list.size paramsT))
+ (//.fail (exception.construct not-application headT))
+ (local (#.Cons funcT paramsT) poly))))
+
+(template [<name> <test>]
+ [(def: #export (<name> expected)
+ (-> Type (Poly Any))
+ (do //.monad
+ [actual any]
+ (if (<test> expected actual)
+ (wrap [])
+ (//.fail (exception.construct types-do-not-match [expected actual])))))]
+
+ [exactly type@=]
+ [sub check.checks?]
+ [super (function.flip check.checks?)]
+ )
+
+(def: #export (adjusted-idx env idx)
+ (-> Env Nat Nat)
+ (let [env-level (n// 2 (dictionary.size env))
+ parameter-level (n// 2 idx)
+ parameter-idx (n/% 2 idx)]
+ (|> env-level dec (n/- parameter-level) (n/* 2) (n/+ parameter-idx))))
+
+(def: #export parameter
+ (Poly Code)
+ (do //.monad
+ [env ..env
+ headT any]
+ (case headT
+ (#.Parameter idx)
+ (case (dictionary.get (adjusted-idx env idx) env)
+ (#.Some [poly-type poly-code])
+ (wrap poly-code)
+
+ #.None
+ (//.fail (exception.construct unknown-parameter headT)))
+
+ _
+ (//.fail (exception.construct not-parameter headT)))))
+
+(def: #export (parameter! id)
+ (-> Nat (Poly Any))
+ (do //.monad
+ [env ..env
+ headT any]
+ (case headT
+ (#.Parameter idx)
+ (if (n/= id (adjusted-idx env idx))
+ (wrap [])
+ (//.fail (exception.construct wrong-parameter [(#.Parameter id) headT])))
+
+ _
+ (//.fail (exception.construct not-parameter headT)))))
+
+(def: #export existential
+ (Poly Nat)
+ (do //.monad
+ [headT any]
+ (case headT
+ (#.Ex ex-id)
+ (wrap ex-id)
+
+ _
+ (//.fail (exception.construct not-existential headT)))))
+
+(def: #export named
+ (Poly [Name Type])
+ (do //.monad
+ [inputT any]
+ (case inputT
+ (#.Named name anonymousT)
+ (wrap [name anonymousT])
+
+ _
+ (//.fail (exception.construct not-named inputT)))))
+
+(def: #export (recursive poly)
+ (All [a] (-> (Poly a) (Poly [Code a])))
+ (do //.monad
+ [headT any]
+ (case (type.un-name headT)
+ (#.Apply (#.Named ["lux" "Nothing"] _) (#.UnivQ _ headT'))
+ (do @
+ [[recT _ output] (|> poly
+ (with-extension .Nothing)
+ (with-extension headT)
+ (local (list headT')))]
+ (wrap [recT output]))
+
+ _
+ (//.fail (exception.construct not-recursive headT)))))
+
+(def: #export recursive-self
+ (Poly Code)
+ (do //.monad
+ [env ..env
+ headT any]
+ (case (type.un-name headT)
+ (^multi (#.Apply (#.Named ["lux" "Nothing"] _) (#.Parameter funcT-idx))
+ (n/= 0 (adjusted-idx env funcT-idx))
+ [(dictionary.get 0 env) (#.Some [self-type self-call])])
+ (wrap self-call)
+
+ _
+ (//.fail (exception.construct not-recursive headT)))))
+
+(def: #export recursive-call
+ (Poly Code)
+ (do //.monad
+ [env ..env
+ [funcT argsT] (apply (//.and any (//.many any)))
+ _ (local (list funcT) (..parameter! 0))
+ allC (let [allT (list& funcT argsT)]
+ (|> allT
+ (monad.map @ (function.constant ..parameter))
+ (local allT)))]
+ (wrap (` ((~+ allC))))))
+
+(def: #export log!
+ (All [a] (Poly a))
+ (do //.monad
+ [current any
+ #let [_ (.log! ($_ text@compose
+ "{" (name@encode (name-of ..log)) "} "
+ (%type current)))]]
+ (//.fail "LOGGING")))
diff --git a/stdlib/source/lux/macro/poly.lux b/stdlib/source/lux/macro/poly.lux
index a3d78177a..695284e0a 100644
--- a/stdlib/source/lux/macro/poly.lux
+++ b/stdlib/source/lux/macro/poly.lux
@@ -1,356 +1,24 @@
(.module:
- [lux (#- function)
+ [lux #*
[abstract
- ["." monad (#+ Monad do)]
- [equivalence]]
+ ["." monad (#+ do)]]
[control
- ["p" parser]
- ["ex" exception (#+ exception:)]
- ["." function]]
+ ["p" parser
+ ["<.>" type (#+ Env)]]]
[data
["." product]
- ["." bit]
["." maybe]
- ["." name ("#;." codec)]
- ["." error (#+ Error)]
- ["." number (#+ hex)
- ["." nat ("#;." decimal)]]
- ["." text ("#;." monoid)
- format]
+ ["." text]
[collection
- ["." list ("#;." fold monad monoid)]
- ["dict" dictionary (#+ Dictionary)]]]
+ ["." list ("#@." fold functor)]
+ ["." dictionary]]]
["." macro (#+ with-gensyms)
["." code]
- ["s" syntax (#+ Syntax syntax:)]
- [syntax
- ["cs" common
+ ["s" syntax (#+ syntax:)
+ [common
["csr" reader]
["csw" writer]]]]
- ["." type ("#;." equivalence)
- ["." check]]])
-
-(template [<name>]
- [(exception: #export (<name> {type Type})
- (%type type))]
-
- [not-existential]
- [not-recursive]
- [not-named]
- [not-parameter]
- [unknown-parameter]
- [not-function]
- [not-application]
- [not-polymorphic]
- [not-variant]
- [not-tuple]
- )
-
-(template [<name>]
- [(exception: #export (<name> {expected Type} {actual Type})
- (ex.report ["Expected" (%type expected)]
- ["Actual" (%type actual)]))]
-
- [types-do-not-match]
- [wrong-parameter]
- )
-
-(exception: #export (unconsumed {remaining (List Type)})
- (ex.report ["Types" (|> remaining
- (list;map (|>> %type (format text.new-line "* ")))
- (text.join-with ""))]))
-
-(type: #export Env (Dictionary Nat [Type Code]))
-
-(type: #export (Poly a)
- (p.Parser [Env (List Type)] a))
-
-(def: #export fresh Env (dict.new nat.hash))
-
-(def: (run' env types poly)
- (All [a] (-> Env (List Type) (Poly a) (Error a)))
- (case (p.run [env types] poly)
- (#error.Failure error)
- (#error.Failure error)
-
- (#error.Success [[env' remaining] output])
- (case remaining
- #.Nil
- (#error.Success output)
-
- _
- (ex.throw unconsumed remaining))))
-
-(def: #export (run type poly)
- (All [a] (-> Type (Poly a) (Error a)))
- (run' fresh (list type) poly))
-
-(def: #export env
- (Poly Env)
- (.function (_ [env inputs])
- (#error.Success [[env inputs] env])))
-
-(def: (with-env temp poly)
- (All [a] (-> Env (Poly a) (Poly a)))
- (.function (_ [env inputs])
- (case (p.run [temp inputs] poly)
- (#error.Failure error)
- (#error.Failure error)
-
- (#error.Success [[_ remaining] output])
- (#error.Success [[env remaining] output]))))
-
-(def: #export peek
- (Poly Type)
- (.function (_ [env inputs])
- (case inputs
- #.Nil
- (#error.Failure "Empty stream of types.")
-
- (#.Cons headT tail)
- (#error.Success [[env inputs] headT]))))
-
-(def: #export any
- (Poly Type)
- (.function (_ [env inputs])
- (case inputs
- #.Nil
- (#error.Failure "Empty stream of types.")
-
- (#.Cons headT tail)
- (#error.Success [[env tail] headT]))))
-
-(def: #export (local types poly)
- (All [a] (-> (List Type) (Poly a) (Poly a)))
- (.function (_ [env pass-through])
- (case (run' env types poly)
- (#error.Failure error)
- (#error.Failure error)
-
- (#error.Success output)
- (#error.Success [[env pass-through] output]))))
-
-(def: (label idx)
- (-> Nat Code)
- (code.local-identifier ($_ text;compose "label" text.tab (nat;encode idx))))
-
-(def: #export (with-extension type poly)
- (All [a] (-> Type (Poly a) (Poly [Code a])))
- (.function (_ [env inputs])
- (let [current-id (dict.size env)
- g!var (label current-id)]
- (case (p.run [(dict.put current-id [type g!var] env)
- inputs]
- poly)
- (#error.Failure error)
- (#error.Failure error)
-
- (#error.Success [[_ inputs'] output])
- (#error.Success [[env inputs'] [g!var output]])))))
-
-(template [<name> <flattener> <tag> <exception>]
- [(def: #export (<name> poly)
- (All [a] (-> (Poly a) (Poly a)))
- (do p.monad
- [headT any]
- (let [members (<flattener> (type.un-name headT))]
- (if (n/> 1 (list.size members))
- (local members poly)
- (p.fail (ex.construct <exception> headT))))))]
-
- [variant type.flatten-variant #.Sum not-variant]
- [tuple type.flatten-tuple #.Product not-tuple]
- )
-
-(def: polymorphic'
- (Poly [Nat Type])
- (do p.monad
- [headT any
- #let [[num-arg bodyT] (type.flatten-univ-q (type.un-name headT))]]
- (if (n/= 0 num-arg)
- (p.fail (ex.construct not-polymorphic headT))
- (wrap [num-arg bodyT]))))
-
-(def: #export (polymorphic poly)
- (All [a] (-> (Poly a) (Poly [Code (List Code) a])))
- (do p.monad
- [headT any
- funcI (:: @ map dict.size ..env)
- [num-args non-poly] (local (list headT) polymorphic')
- env ..env
- #let [funcL (label funcI)
- [all-varsL env'] (loop [current-arg 0
- env' env
- all-varsL (: (List Code) (list))]
- (if (n/< num-args current-arg)
- (if (n/= 0 current-arg)
- (let [varL (label (inc funcI))]
- (recur (inc current-arg)
- (|> env'
- (dict.put funcI [headT funcL])
- (dict.put (inc funcI) [(#.Parameter (inc funcI)) varL]))
- (#.Cons varL all-varsL)))
- (let [partialI (|> current-arg (n/* 2) (n/+ funcI))
- partial-varI (inc partialI)
- partial-varL (label partial-varI)
- partialC (` ((~ funcL) (~+ (|> (list.indices num-args)
- (list;map (|>> (n/* 2) inc (n/+ funcI) label))
- list.reverse))))]
- (recur (inc current-arg)
- (|> env'
- (dict.put partialI [.Nothing partialC])
- (dict.put partial-varI [(#.Parameter partial-varI) partial-varL]))
- (#.Cons partial-varL all-varsL))))
- [all-varsL env']))]]
- (|> (do @
- [output poly]
- (wrap [funcL all-varsL output]))
- (local (list non-poly))
- (with-env env'))))
-
-(def: #export (function in-poly out-poly)
- (All [i o] (-> (Poly i) (Poly o) (Poly [i o])))
- (do p.monad
- [headT any
- #let [[inputsT outputT] (type.flatten-function (type.un-name headT))]]
- (if (n/> 0 (list.size inputsT))
- (p.and (local inputsT in-poly)
- (local (list outputT) out-poly))
- (p.fail (ex.construct not-function headT)))))
-
-(def: #export (apply poly)
- (All [a] (-> (Poly a) (Poly a)))
- (do p.monad
- [headT any
- #let [[funcT paramsT] (type.flatten-application (type.un-name headT))]]
- (if (n/= 0 (list.size paramsT))
- (p.fail (ex.construct not-application headT))
- (local (#.Cons funcT paramsT) poly))))
-
-(template [<name> <test>]
- [(def: #export (<name> expected)
- (-> Type (Poly Any))
- (do p.monad
- [actual any]
- (if (<test> expected actual)
- (wrap [])
- (p.fail (ex.construct types-do-not-match [expected actual])))))]
-
- [exactly type;=]
- [sub check.checks?]
- [super (function.flip check.checks?)]
- )
-
-(def: (adjusted-idx env idx)
- (-> Env Nat Nat)
- (let [env-level (n// 2 (dict.size env))
- parameter-level (n// 2 idx)
- parameter-idx (n/% 2 idx)]
- (|> env-level dec (n/- parameter-level) (n/* 2) (n/+ parameter-idx))))
-
-(def: #export parameter
- (Poly Code)
- (do p.monad
- [env ..env
- headT any]
- (case headT
- (#.Parameter idx)
- (case (dict.get (adjusted-idx env idx) env)
- (#.Some [poly-type poly-code])
- (wrap poly-code)
-
- #.None
- (p.fail (ex.construct unknown-parameter headT)))
-
- _
- (p.fail (ex.construct not-parameter headT)))))
-
-(def: #export (parameter! id)
- (-> Nat (Poly Any))
- (do p.monad
- [env ..env
- headT any]
- (case headT
- (#.Parameter idx)
- (if (n/= id (adjusted-idx env idx))
- (wrap [])
- (p.fail (ex.construct wrong-parameter [(#.Parameter id) headT])))
-
- _
- (p.fail (ex.construct not-parameter headT)))))
-
-(def: #export existential
- (Poly Nat)
- (do p.monad
- [headT any]
- (case headT
- (#.Ex ex-id)
- (wrap ex-id)
-
- _
- (p.fail (ex.construct not-existential headT)))))
-
-(def: #export named
- (Poly [Name Type])
- (do p.monad
- [inputT any]
- (case inputT
- (#.Named name anonymousT)
- (wrap [name anonymousT])
-
- _
- (p.fail (ex.construct not-named inputT)))))
-
-(def: #export (recursive poly)
- (All [a] (-> (Poly a) (Poly [Code a])))
- (do p.monad
- [headT any]
- (case (type.un-name headT)
- (#.Apply (#.Named ["lux" "Nothing"] _) (#.UnivQ _ headT'))
- (do @
- [[recT _ output] (|> poly
- (with-extension .Nothing)
- (with-extension headT)
- (local (list headT')))]
- (wrap [recT output]))
-
- _
- (p.fail (ex.construct not-recursive headT)))))
-
-(def: #export recursive-self
- (Poly Code)
- (do p.monad
- [env ..env
- headT any]
- (case (type.un-name headT)
- (^multi (#.Apply (#.Named ["lux" "Nothing"] _) (#.Parameter funcT-idx))
- (n/= 0 (adjusted-idx env funcT-idx))
- [(dict.get 0 env) (#.Some [self-type self-call])])
- (wrap self-call)
-
- _
- (p.fail (ex.construct not-recursive headT)))))
-
-(def: #export recursive-call
- (Poly Code)
- (do p.monad
- [env ..env
- [funcT argsT] (apply (p.and any (p.many any)))
- _ (local (list funcT) (..parameter! 0))
- allC (let [allT (list& funcT argsT)]
- (|> allT
- (monad.map @ (function.constant ..parameter))
- (local allT)))]
- (wrap (` ((~+ allC))))))
-
-(def: #export log
- (All [a] (Poly a))
- (do p.monad
- [current any
- #let [_ (log! ($_ text;compose
- "{" (name;encode (name-of ..log)) "} "
- (%type current)))]]
- (p.fail "LOGGING")))
+ ["." type]])
(syntax: #export (poly: {export csr.export}
{name s.local-identifier}
@@ -361,10 +29,10 @@
(do macro.monad
[(~ g!type) (macro.find-type-def (~ g!type))]
(case (|> (~ body)
- (.function ((~ g!_) (~ g!name)))
+ (function ((~ g!_) (~ g!name)))
p.rec
(do p.monad [])
- (..run (~ g!type))
+ ((~! <type>.run) (~ g!type))
(: (.Either .Text .Code)))
(#.Left (~ g!output))
(macro.fail (~ g!output))
@@ -379,7 +47,7 @@
(def: (derivation-name poly args)
(-> Text (List Text) (Maybe Text))
(if (common-poly-name? poly)
- (#.Some (list;fold (text.replace-once "?") poly args))
+ (#.Some (list@fold (text.replace-once "?") poly args))
#.None))
(syntax: #export (derived: {export csr.export}
@@ -393,7 +61,7 @@
(wrap name)
(^multi #.None
- [(derivation-name (product.right poly-func) (list;map product.right poly-args))
+ [(derivation-name (product.right poly-func) (list@map product.right poly-args))
(#.Some derived-name)])
(wrap derived-name)
@@ -404,7 +72,7 @@
custom-impl
#.None
- (` ((~ (code.identifier poly-func)) (~+ (list;map code.identifier poly-args)))))]]
+ (` ((~ (code.identifier poly-func)) (~+ (list@map code.identifier poly-args)))))]]
(wrap (.list (` (def: (~+ (csw.export export))
(~ (code.identifier ["" name]))
{#.struct? #1}
@@ -415,7 +83,7 @@
(case type
(#.Primitive name params)
(` (#.Primitive (~ (code.text name))
- (list (~+ (list;map (to-code env) params)))))
+ (list (~+ (list@map (to-code env) params)))))
(^template [<tag>]
(<tag> idx)
@@ -423,15 +91,15 @@
([#.Var] [#.Ex])
(#.Parameter idx)
- (let [idx (adjusted-idx env idx)]
+ (let [idx (<type>.adjusted-idx env idx)]
(if (n/= 0 idx)
- (|> (dict.get idx env) maybe.assume product.left (to-code env))
+ (|> (dictionary.get idx env) maybe.assume product.left (to-code env))
(` (.$ (~ (code.nat (dec idx)))))))
(#.Apply (#.Named ["lux" "Nothing"] _) (#.Parameter idx))
- (let [idx (adjusted-idx env idx)]
+ (let [idx (<type>.adjusted-idx env idx)]
(if (n/= 0 idx)
- (|> (dict.get idx env) maybe.assume product.left (to-code env))
+ (|> (dictionary.get idx env) maybe.assume product.left (to-code env))
(undefined)))
(^template [<tag>]
@@ -442,7 +110,7 @@
(^template [<tag> <macro> <flattener>]
(<tag> left right)
- (` (<macro> (~+ (list;map (to-code env) (<flattener> type))))))
+ (` (<macro> (~+ (list@map (to-code env) (<flattener> type))))))
([#.Sum | type.flatten-variant]
[#.Product & type.flatten-tuple])
@@ -451,7 +119,7 @@
(^template [<tag>]
(<tag> scope body)
- (` (<tag> (list (~+ (list;map (to-code env) scope)))
+ (` (<tag> (list (~+ (list@map (to-code env) scope)))
(~ (to-code env body)))))
([#.UnivQ] [#.ExQ])
))
diff --git a/stdlib/source/lux/macro/poly/equivalence.lux b/stdlib/source/lux/macro/poly/equivalence.lux
index c39ad9412..50dabcd16 100644
--- a/stdlib/source/lux/macro/poly/equivalence.lux
+++ b/stdlib/source/lux/macro/poly/equivalence.lux
@@ -4,7 +4,8 @@
[monad (#+ Monad do)]
["/" equivalence]]
[control
- ["p" parser]]
+ ["p" parser
+ ["<.>" type]]]
[data
["." product]
["." bit]
@@ -42,8 +43,8 @@
(poly: #export equivalence
(`` (do @
[#let [g!_ (code.local-identifier "_____________")]
- *env* poly.env
- inputT poly.peek
+ *env* <type>.env
+ inputT <type>.peek
#let [@Equivalence (: (-> Type Code)
(function (_ type)
(` ((~! /.Equivalence) (~ (poly.to-code *env* type))))))]]
@@ -55,18 +56,18 @@
(wrap (` (: (~ (@Equivalence inputT))
<eq>))))]
- [(poly.exactly Any) (function ((~ g!_) (~ g!_) (~ g!_)) #1)]
- [(poly.sub Bit) (~! bit.equivalence)]
- [(poly.sub Nat) (~! nat.equivalence)]
- [(poly.sub Int) (~! int.equivalence)]
- [(poly.sub Rev) (~! rev.equivalence)]
- [(poly.sub Frac) (~! frac.equivalence)]
- [(poly.sub Text) (~! text.equivalence)]))
+ [(<type>.exactly Any) (function ((~ g!_) (~ g!_) (~ g!_)) #1)]
+ [(<type>.sub Bit) (~! bit.equivalence)]
+ [(<type>.sub Nat) (~! nat.equivalence)]
+ [(<type>.sub Int) (~! int.equivalence)]
+ [(<type>.sub Rev) (~! rev.equivalence)]
+ [(<type>.sub Frac) (~! frac.equivalence)]
+ [(<type>.sub Text) (~! text.equivalence)]))
## Composite types
(~~ (template [<name> <eq>]
[(do @
- [[_ argC] (poly.apply (p.and (poly.exactly <name>)
- equivalence))]
+ [[_ argC] (<type>.apply (p.and (<type>.exactly <name>)
+ equivalence))]
(wrap (` (: (~ (@Equivalence inputT))
(<eq> (~ argC))))))]
@@ -79,16 +80,16 @@
[rose.Tree (~! rose.equivalence)]
))
(do @
- [[_ _ valC] (poly.apply ($_ p.and
- (poly.exactly dictionary.Dictionary)
- poly.any
- equivalence))]
+ [[_ _ valC] (<type>.apply ($_ p.and
+ (<type>.exactly dictionary.Dictionary)
+ <type>.any
+ equivalence))]
(wrap (` (: (~ (@Equivalence inputT))
((~! dictionary.equivalence) (~ valC))))))
## Models
(~~ (template [<type> <eq>]
[(do @
- [_ (poly.exactly <type>)]
+ [_ (<type>.exactly <type>)]
(wrap (` (: (~ (@Equivalence inputT))
<eq>))))]
@@ -99,13 +100,13 @@
[month.Month month.equivalence]
))
(do @
- [_ (poly.apply (p.and (poly.exactly unit.Qty)
- poly.any))]
+ [_ (<type>.apply (p.and (<type>.exactly unit.Qty)
+ <type>.any))]
(wrap (` (: (~ (@Equivalence inputT))
unit.equivalence))))
## Variants
(do @
- [members (poly.variant (p.many equivalence))
+ [members (<type>.variant (p.many equivalence))
#let [g!_ (code.local-identifier "_____________")
g!left (code.local-identifier "_____________left")
g!right (code.local-identifier "_____________right")]]
@@ -121,7 +122,7 @@
#0))))))
## Tuples
(do @
- [g!eqs (poly.tuple (p.many equivalence))
+ [g!eqs (<type>.tuple (p.many equivalence))
#let [g!_ (code.local-identifier "_____________")
indices (list.indices (list.size g!eqs))
g!lefts (list@map (|>> nat@encode (text@compose "left") code.local-identifier) indices)
@@ -133,29 +134,29 @@
(` ((~ g!eq) (~ g!left) (~ g!right)))))))))))))
## Type recursion
(do @
- [[g!self bodyC] (poly.recursive equivalence)
+ [[g!self bodyC] (<type>.recursive equivalence)
#let [g!_ (code.local-identifier "_____________")]]
(wrap (` (: (~ (@Equivalence inputT))
((~! /.rec) (.function ((~ g!_) (~ g!self))
(~ bodyC)))))))
- poly.recursive-self
+ <type>.recursive-self
## Type applications
(do @
- [[funcC argsC] (poly.apply (p.and equivalence (p.many equivalence)))]
+ [[funcC argsC] (<type>.apply (p.and equivalence (p.many equivalence)))]
(wrap (` ((~ funcC) (~+ argsC)))))
## Parameters
- poly.parameter
+ <type>.parameter
## Polymorphism
(do @
- [[funcC varsC bodyC] (poly.polymorphic equivalence)]
+ [[funcC varsC bodyC] (<type>.polymorphic equivalence)]
(wrap (` (: (All [(~+ varsC)]
(-> (~+ (list@map (|>> (~) ((~! /.Equivalence)) (`)) varsC))
((~! /.Equivalence) ((~ (poly.to-code *env* inputT)) (~+ varsC)))))
(function ((~ funcC) (~+ varsC))
(~ bodyC))))))
- poly.recursive-call
+ <type>.recursive-call
## If all else fails...
- (|> poly.any
+ (|> <type>.any
(:: @ map (|>> %type (format "Cannot create Equivalence for: ") p.fail))
(:: @ join))
))))
diff --git a/stdlib/source/lux/macro/poly/functor.lux b/stdlib/source/lux/macro/poly/functor.lux
index 947f08ac8..4a2d44e38 100644
--- a/stdlib/source/lux/macro/poly/functor.lux
+++ b/stdlib/source/lux/macro/poly/functor.lux
@@ -4,7 +4,8 @@
[monad (#+ Monad do)]
["." functor]]
[control
- ["p" parser]]
+ ["p" parser
+ ["<.>" type]]]
[data
["." product]
["." text
@@ -23,10 +24,10 @@
[#let [type-funcC (code.local-identifier "____________type-funcC")
funcC (code.local-identifier "____________funcC")
inputC (code.local-identifier "____________inputC")]
- *env* poly.env
- inputT poly.peek
- [polyC varsC non-functorT] (poly.local (list inputT)
- (poly.polymorphic poly.any))
+ *env* <type>.env
+ inputT <type>.peek
+ [polyC varsC non-functorT] (<type>.local (list inputT)
+ (<type>.polymorphic <type>.any))
#let [num-vars (list.size varsC)]
#let [@Functor (: (-> Type Code)
(function (_ unwrappedT)
@@ -35,18 +36,18 @@
(let [paramsC (|> num-vars dec list.indices (list;map (|>> %n code.local-identifier)))]
(` (All [(~+ paramsC)]
((~! functor.Functor) ((~ (poly.to-code *env* unwrappedT)) (~+ paramsC)))))))))
- Arg<?> (: (-> Code (poly.Poly Code))
+ Arg<?> (: (-> Code (<type>.Poly Code))
(function (Arg<?> valueC)
($_ p.either
## Type-var
(do p.monad
[#let [varI (|> num-vars (n/* 2) dec)]
- _ (poly.parameter! varI)]
+ _ (<type>.parameter! varI)]
(wrap (` ((~ funcC) (~ valueC)))))
## Variants
(do @
[_ (wrap [])
- membersC (poly.variant (p.many (Arg<?> valueC)))]
+ membersC (<type>.variant (p.many (Arg<?> valueC)))]
(wrap (` (case (~ valueC)
(~+ (list;join (list;map (function (_ [tag memberC])
(list (` ((~ (code.nat tag)) (~ valueC)))
@@ -54,17 +55,17 @@
(list.enumerate membersC))))))))
## Tuples
(do p.monad
- [pairsCC (: (poly.Poly (List [Code Code]))
- (poly.tuple (loop [idx 0
- pairsCC (: (List [Code Code])
- (list))]
- (p.either (let [slotC (|> idx %n (format "____________slot") code.local-identifier)]
- (do @
- [_ (wrap [])
- memberC (Arg<?> slotC)]
- (recur (inc idx)
- (list;compose pairsCC (list [slotC memberC])))))
- (wrap pairsCC)))))]
+ [pairsCC (: (<type>.Poly (List [Code Code]))
+ (<type>.tuple (loop [idx 0
+ pairsCC (: (List [Code Code])
+ (list))]
+ (p.either (let [slotC (|> idx %n (format "____________slot") code.local-identifier)]
+ (do @
+ [_ (wrap [])
+ memberC (Arg<?> slotC)]
+ (recur (inc idx)
+ (list;compose pairsCC (list [slotC memberC])))))
+ (wrap pairsCC)))))]
(wrap (` (case (~ valueC)
[(~+ (list;map product.left pairsCC))]
[(~+ (list;map product.right pairsCC))]))))
@@ -73,7 +74,7 @@
[_ (wrap [])
#let [g! (code.local-identifier "____________")
outL (code.local-identifier "____________outL")]
- [inT+ outC] (poly.function (p.many poly.any)
+ [inT+ outC] (<type>.function (p.many <type>.any)
(Arg<?> outL))
#let [inC+ (|> (list.size inT+)
list.indices
@@ -83,15 +84,15 @@
(~ outC))))))
## Recursion
(do p.monad
- [_ poly.recursive-call]
+ [_ <type>.recursive-call]
(wrap (` ((~' map) (~ funcC) (~ valueC)))))
## Parameters
(do p.monad
- [_ poly.any]
+ [_ <type>.any]
(wrap valueC))
)))]
- [_ _ outputC] (: (poly.Poly [Code (List Code) Code])
- (p.either (poly.polymorphic
+ [_ _ outputC] (: (<type>.Poly [Code (List Code) Code])
+ (p.either (<type>.polymorphic
(Arg<?> inputC))
(p.fail (format "Cannot create Functor for: " (%type inputT)))))]
(wrap (` (: (~ (@Functor inputT))
diff --git a/stdlib/source/lux/macro/poly/json.lux b/stdlib/source/lux/macro/poly/json.lux
index f397de2a2..e0e122eb1 100644
--- a/stdlib/source/lux/macro/poly/json.lux
+++ b/stdlib/source/lux/macro/poly/json.lux
@@ -5,7 +5,8 @@
[equivalence (#+ Equivalence)]
["." codec]]
[control
- ["p" parser]]
+ ["p" parser
+ ["<.>" type]]]
[data
["." bit]
maybe
@@ -97,15 +98,15 @@
(wrap (` (: (~ (@JSON//encode inputT))
<encoder>))))]
- [(poly.exactly Any) (function ((~ g!_) (~ (code.identifier ["" "0"]))) #/.Null)]
- [(poly.sub Bit) (|>> #/.Boolean)]
- [(poly.sub Nat) (:: (~! ..nat-codec) (~' encode))]
- [(poly.sub Int) (:: (~! ..int-codec) (~' encode))]
- [(poly.sub Frac) (|>> #/.Number)]
- [(poly.sub Text) (|>> #/.String)])
+ [(<type>.exactly Any) (function ((~ g!_) (~ (code.identifier ["" "0"]))) #/.Null)]
+ [(<type>.sub Bit) (|>> #/.Boolean)]
+ [(<type>.sub Nat) (:: (~! ..nat-codec) (~' encode))]
+ [(<type>.sub Int) (:: (~! ..int-codec) (~' encode))]
+ [(<type>.sub Frac) (|>> #/.Number)]
+ [(<type>.sub Text) (|>> #/.String)])
<time> (template [<type> <codec>]
[(do @
- [_ (poly.exactly <type>)]
+ [_ (<type>.exactly <type>)]
(wrap (` (: (~ (@JSON//encode inputT))
(|>> (:: (~! <codec>) (~' encode)) #/.String)))))]
@@ -115,27 +116,27 @@
[day.Day day.codec]
[month.Month month.codec])]
(do @
- [*env* poly.env
+ [*env* <type>.env
#let [@JSON//encode (: (-> Type Code)
(function (_ type)
(` (-> (~ (poly.to-code *env* type)) /.JSON))))]
- inputT poly.peek]
+ inputT <type>.peek]
($_ p.either
<basic>
<time>
(do @
- [unitT (poly.apply (p.after (poly.exactly unit.Qty)
- poly.any))]
+ [unitT (<type>.apply (p.after (<type>.exactly unit.Qty)
+ <type>.any))]
(wrap (` (: (~ (@JSON//encode inputT))
(:: (~! qty-codec) (~' encode))))))
(do @
[#let [g!_ (code.local-identifier "_______")
g!key (code.local-identifier "_______key")
g!val (code.local-identifier "_______val")]
- [_ _ =val=] (poly.apply ($_ p.and
- (poly.exactly d.Dictionary)
- (poly.exactly .Text)
- codec//encode))]
+ [_ _ =val=] (<type>.apply ($_ p.and
+ (<type>.exactly d.Dictionary)
+ (<type>.exactly .Text)
+ codec//encode))]
(wrap (` (: (~ (@JSON//encode inputT))
(|>> ((~! d.entries))
((~! list@map) (function ((~ g!_) [(~ g!key) (~ g!val)])
@@ -143,21 +144,21 @@
((~! d.from-list) (~! text.hash))
#/.Object)))))
(do @
- [[_ =sub=] (poly.apply ($_ p.and
- (poly.exactly .Maybe)
- codec//encode))]
+ [[_ =sub=] (<type>.apply ($_ p.and
+ (<type>.exactly .Maybe)
+ codec//encode))]
(wrap (` (: (~ (@JSON//encode inputT))
((~! ..nullable) (~ =sub=))))))
(do @
- [[_ =sub=] (poly.apply ($_ p.and
- (poly.exactly .List)
- codec//encode))]
+ [[_ =sub=] (<type>.apply ($_ p.and
+ (<type>.exactly .List)
+ codec//encode))]
(wrap (` (: (~ (@JSON//encode inputT))
(|>> ((~! list@map) (~ =sub=)) ((~! row.from-list)) #/.Array)))))
(do @
[#let [g!_ (code.local-identifier "_______")
g!input (code.local-identifier "_______input")]
- members (poly.variant (p.many codec//encode))]
+ members (<type>.variant (p.many codec//encode))]
(wrap (` (: (~ (@JSON//encode inputT))
(function ((~ g!_) (~ g!input))
(case (~ g!input)
@@ -167,7 +168,7 @@
((~ g!encode) (~ g!input))]))))
(list.enumerate members))))))))))
(do @
- [g!encoders (poly.tuple (p.many codec//encode))
+ [g!encoders (<type>.tuple (p.many codec//encode))
#let [g!_ (code.local-identifier "_______")
g!members (|> (list.size g!encoders)
list.indices
@@ -179,19 +180,19 @@
(list.zip2 g!members g!encoders)))]))))))
## Type recursion
(do @
- [[selfC non-recC] (poly.recursive codec//encode)
+ [[selfC non-recC] (<type>.recursive codec//encode)
#let [g! (code.local-identifier "____________")]]
(wrap (` (: (~ (@JSON//encode inputT))
((~! ..rec-encode) (.function ((~ g!) (~ selfC))
(~ non-recC)))))))
- poly.recursive-self
+ <type>.recursive-self
## Type applications
(do @
- [partsC (poly.apply (p.many codec//encode))]
+ [partsC (<type>.apply (p.many codec//encode))]
(wrap (` ((~+ partsC)))))
## Polymorphism
(do @
- [[funcC varsC bodyC] (poly.polymorphic codec//encode)]
+ [[funcC varsC bodyC] (<type>.polymorphic codec//encode)]
(wrap (` (: (All [(~+ varsC)]
(-> (~+ (list@map (function (_ varC) (` (-> (~ varC) /.JSON)))
varsC))
@@ -199,8 +200,8 @@
/.JSON)))
(function ((~ funcC) (~+ varsC))
(~ bodyC))))))
- poly.parameter
- poly.recursive-call
+ <type>.parameter
+ <type>.recursive-call
## If all else fails...
(p.fail (format "Cannot create JSON encoder for: " (type.to-text inputT)))
))))
@@ -213,15 +214,15 @@
(wrap (` (: (~ (@JSON//decode inputT))
(~! <decoder>)))))]
- [(poly.exactly Any) /.null]
- [(poly.sub Bit) /.boolean]
- [(poly.sub Nat) (p.codec ..nat-codec /.any)]
- [(poly.sub Int) (p.codec ..int-codec /.any)]
- [(poly.sub Frac) /.number]
- [(poly.sub Text) /.string])
+ [(<type>.exactly Any) /.null]
+ [(<type>.sub Bit) /.boolean]
+ [(<type>.sub Nat) (p.codec ..nat-codec /.any)]
+ [(<type>.sub Int) (p.codec ..int-codec /.any)]
+ [(<type>.sub Frac) /.number]
+ [(<type>.sub Text) /.string])
<time> (template [<type> <codec>]
[(do @
- [_ (poly.exactly <type>)]
+ [_ (<type>.exactly <type>)]
(wrap (` (: (~ (@JSON//decode inputT))
((~! p.codec) (~! <codec>) (~! /.string))))))]
@@ -232,38 +233,38 @@
[month.Month month.codec])
]
(do @
- [*env* poly.env
+ [*env* <type>.env
#let [@JSON//decode (: (-> Type Code)
(function (_ type)
(` (/.Reader (~ (poly.to-code *env* type))))))]
- inputT poly.peek]
+ inputT <type>.peek]
($_ p.either
<basic>
<time>
(do @
- [unitT (poly.apply (p.after (poly.exactly unit.Qty)
- poly.any))]
+ [unitT (<type>.apply (p.after (<type>.exactly unit.Qty)
+ <type>.any))]
(wrap (` (: (~ (@JSON//decode inputT))
((~! p.codec) (~! qty-codec) (~! /.any))))))
(do @
- [[_ _ valC] (poly.apply ($_ p.and
- (poly.exactly d.Dictionary)
- (poly.exactly .Text)
- codec//decode))]
+ [[_ _ valC] (<type>.apply ($_ p.and
+ (<type>.exactly d.Dictionary)
+ (<type>.exactly .Text)
+ codec//decode))]
(wrap (` (: (~ (@JSON//decode inputT))
((~! /.dictionary) (~ valC))))))
(do @
- [[_ subC] (poly.apply (p.and (poly.exactly .Maybe)
- codec//decode))]
+ [[_ subC] (<type>.apply (p.and (<type>.exactly .Maybe)
+ codec//decode))]
(wrap (` (: (~ (@JSON//decode inputT))
((~! /.nullable) (~ subC))))))
(do @
- [[_ subC] (poly.apply (p.and (poly.exactly .List)
- codec//decode))]
+ [[_ subC] (<type>.apply (p.and (<type>.exactly .List)
+ codec//decode))]
(wrap (` (: (~ (@JSON//decode inputT))
((~! /.array) ((~! p.some) (~ subC)))))))
(do @
- [members (poly.variant (p.many codec//decode))]
+ [members (<type>.variant (p.many codec//decode))]
(wrap (` (: (~ (@JSON//decode inputT))
($_ ((~! p.or))
(~+ (list@map (function (_ [tag memberC])
@@ -272,31 +273,31 @@
((~! /.array)))))
(list.enumerate members))))))))
(do @
- [g!decoders (poly.tuple (p.many codec//decode))]
+ [g!decoders (<type>.tuple (p.many codec//decode))]
(wrap (` (: (~ (@JSON//decode inputT))
((~! /.array) ($_ ((~! p.and)) (~+ g!decoders)))))))
## Type recursion
(do @
- [[selfC bodyC] (poly.recursive codec//decode)
+ [[selfC bodyC] (<type>.recursive codec//decode)
#let [g! (code.local-identifier "____________")]]
(wrap (` (: (~ (@JSON//decode inputT))
((~! p.rec) (.function ((~ g!) (~ selfC))
(~ bodyC)))))))
- poly.recursive-self
+ <type>.recursive-self
## Type applications
(do @
- [[funcC argsC] (poly.apply (p.and codec//decode (p.many codec//decode)))]
+ [[funcC argsC] (<type>.apply (p.and codec//decode (p.many codec//decode)))]
(wrap (` ((~ funcC) (~+ argsC)))))
## Polymorphism
(do @
- [[funcC varsC bodyC] (poly.polymorphic codec//decode)]
+ [[funcC varsC bodyC] (<type>.polymorphic codec//decode)]
(wrap (` (: (All [(~+ varsC)]
(-> (~+ (list@map (|>> (~) /.Reader (`)) varsC))
(/.Reader ((~ (poly.to-code *env* inputT)) (~+ varsC)))))
(function ((~ funcC) (~+ varsC))
(~ bodyC))))))
- poly.parameter
- poly.recursive-call
+ <type>.parameter
+ <type>.recursive-call
## If all else fails...
(p.fail (format "Cannot create JSON decoder for: " (type.to-text inputT)))
))))
diff --git a/stdlib/source/test/lux.lux b/stdlib/source/test/lux.lux
index 08bc451b1..ab5d2e1d4 100644
--- a/stdlib/source/test/lux.lux
+++ b/stdlib/source/test/lux.lux
@@ -59,7 +59,9 @@
## ["._" concatenative]
## ["._" predicate]
## [monad
- ## ["._" free]]]
+ ## ["._" free]]
+ ## [parser
+ ## [type (#+)]]]
## [data
## ["._" env]
## ["._" trace]
@@ -345,5 +347,6 @@
(program: args
(<| io
_.run!
- (_.times 100)
+ ## (_.times 100)
+ (_.seed 8070500311708372420)
..test))