diff options
Diffstat (limited to '')
-rw-r--r-- | stdlib/source/lux.lux | 260 |
1 files changed, 178 insertions, 82 deletions
diff --git a/stdlib/source/lux.lux b/stdlib/source/lux.lux index c5d363874..ac1289395 100644 --- a/stdlib/source/lux.lux +++ b/stdlib/source/lux.lux @@ -7,52 +7,88 @@ (_lux_def Bool (+12 ["lux" "Bool"] (+0 "java.lang.Boolean" (+0))) - (+1 [["lux" "type?"] (+0 true)] (+1 [["lux" "export?"] (+0 true)] (+0)))) + (+1 [["lux" "type?"] (+0 true)] + (+1 [["lux" "export?"] (+0 true)] + (+1 [["lux" "doc"] (+6 "Your standard, run-of-the-mill boolean values.")] + (+0))))) (_lux_def Nat (+12 ["lux" "Nat"] (+0 "#Nat" (+0))) - (+1 [["lux" "type?"] (+0 true)] (+1 [["lux" "export?"] (+0 true)] (+0)))) + (+1 [["lux" "type?"] (+0 true)] + (+1 [["lux" "export?"] (+0 true)] + (+1 [["lux" "doc"] (+6 "Unsigned integers, or natural numbers. + + They start at zero (+0) and extend in the positive direction.")] + (+0))))) (_lux_def Int (+12 ["lux" "Int"] (+0 "java.lang.Long" (+0))) - (+1 [["lux" "type?"] (+0 true)] (+1 [["lux" "export?"] (+0 true)] (+0)))) + (+1 [["lux" "type?"] (+0 true)] + (+1 [["lux" "export?"] (+0 true)] + (+1 [["lux" "doc"] (+6 "Your standard, run-of-the-mill integer numbers.")] + (+0))))) (_lux_def Real (+12 ["lux" "Real"] (+0 "java.lang.Double" (+0))) - (+1 [["lux" "type?"] (+0 true)] (+1 [["lux" "export?"] (+0 true)] (+0)))) + (+1 [["lux" "type?"] (+0 true)] + (+1 [["lux" "export?"] (+0 true)] + (+1 [["lux" "doc"] (+6 "Your standard, run-of-the-mill floating-point numbers.")] + (+0))))) (_lux_def Frac (+12 ["lux" "Frac"] (+0 "#Frac" (+0))) - (+1 [["lux" "type?"] (+0 true)] (+1 [["lux" "export?"] (+0 true)] (+0)))) + (+1 [["lux" "type?"] (+0 true)] + (+1 [["lux" "export?"] (+0 true)] + (+1 [["lux" "doc"] (+6 "Fractional numbers that live in the interval [0,1). + + Useful for probability, and other domains that work within that interval.")] + (+0))))) (_lux_def Char (+12 ["lux" "Char"] (+0 "java.lang.Character" (+0))) - (+1 [["lux" "type?"] (+0 true)] (+1 [["lux" "export?"] (+0 true)] (+0)))) + (+1 [["lux" "type?"] (+0 true)] + (+1 [["lux" "export?"] (+0 true)] + (+1 [["lux" "doc"] (+6 "Your standard, run-of-the-mill character values.")] + (+0))))) (_lux_def Text (+12 ["lux" "Text"] (+0 "java.lang.String" (+0))) - (+1 [["lux" "type?"] (+0 true)] (+1 [["lux" "export?"] (+0 true)] (+0)))) + (+1 [["lux" "type?"] (+0 true)] + (+1 [["lux" "export?"] (+0 true)] + (+1 [["lux" "doc"] (+6 "Your standard, run-of-the-mill string values.")] + (+0))))) (_lux_def Void (+12 ["lux" "Void"] (+1)) - (+1 [["lux" "type?"] (+0 true)] (+1 [["lux" "export?"] (+0 true)] (+0)))) + (+1 [["lux" "type?"] (+0 true)] + (+1 [["lux" "export?"] (+0 true)] + (+1 [["lux" "doc"] (+6 "An unusual type that possesses no value, and thus can't be instantiated.")] + (+0))))) (_lux_def Unit (+12 ["lux" "Unit"] (+2)) - (+1 [["lux" "type?"] (+0 true)] (+1 [["lux" "export?"] (+0 true)] (+0)))) + (+1 [["lux" "type?"] (+0 true)] + (+1 [["lux" "export?"] (+0 true)] + (+1 [["lux" "doc"] (+6 "An unusual type that only possesses a single value: []")] + (+0))))) (_lux_def Ident (+12 ["lux" "Ident"] (+4 Text Text)) - (+1 [["lux" "type?"] (+0 true)] (+1 [["lux" "export?"] (+0 true)] (+0)))) + (+1 [["lux" "type?"] (+0 true)] + (+1 [["lux" "export?"] (+0 true)] + (+1 [["lux" "doc"] (+6 "An identifier. + + It is used as part of Lux syntax to represent symbols and tags.")] + (+0))))) ## (type: (List a) ## #Nil @@ -69,7 +105,8 @@ (+1 [["lux" "export?"] (+0 true)] (+1 [["lux" "tags"] (+8 (+1 (+6 "Nil") (+1 (+6 "Cons") (+0))))] (+1 [["lux" "type-args"] (+8 (+1 (+6 "a") (+0)))] - (+0)))))) + (+1 [["lux" "doc"] (+6 "A potentially empty list of values.")] + (+0))))))) ## (type: (Maybe a) ## #None @@ -85,7 +122,8 @@ (#Cons [["lux" "export?"] (+0 true)] (#Cons [["lux" "tags"] (+8 (#Cons (+6 "None") (#Cons (+6 "Some") #Nil)))] (#Cons [["lux" "type-args"] (+8 (#Cons (+6 "a") #Nil))] - #Nil))))) + (#Cons [["lux" "doc"] (+6 "A potentially missing value.")] + #Nil)))))) ## (type: #rec Type ## (#HostT Text (List Type)) @@ -166,7 +204,8 @@ (#Cons [["lux" "type?"] (+0 true)] (#Cons [["lux" "export?"] (+0 true)] (#Cons [["lux" "doc"] (+6 "The type of things whose type doesn't matter. - It can be used to write functions or data-structures that can take, or return anything.")] + + It can be used to write functions or data-structures that can take, or return, anything.")] #Nil)))) ## (type: Bottom @@ -177,7 +216,8 @@ (#Cons [["lux" "type?"] (+0 true)] (#Cons [["lux" "export?"] (+0 true)] (#Cons [["lux" "doc"] (+6 "The type of things whose type is unknown or undefined. - Useful for expressions that cause errors or other \"extraordinary\" conditions.")] + + Useful for expressions that cause errors or other \"extraordinary\" conditions.")] #Nil)))) ## (type: #rec Ann-Value @@ -233,7 +273,8 @@ (#Cons (+6 "DictM") #Nil)))))))))))] (#Cons [["lux" "type-rec?"] (+0 true)] - #Nil))))) + (#Cons [["lux" "doc"] (+6 "The value of an individual annotation.")] + #Nil)))))) ## (type: Anns ## (List [Ident Ann-Value])) @@ -242,7 +283,8 @@ (#AppT List (#ProdT Ident Ann-Value))) (#Cons [["lux" "type?"] (#BoolM true)] (#Cons [["lux" "export?"] (#BoolM true)] - #Nil))) + (#Cons [["lux" "doc"] (#TextM "A set of annotations associated with a definition.")] + #Nil)))) (_lux_def default-def-meta-exported (_lux_: Anns @@ -258,11 +300,12 @@ #Nil) ## (type: Def -## [Type Anns Unit]) +## [Type Anns Void]) (_lux_def Def (#NamedT ["lux" "Def"] - (#ProdT Type (#ProdT Anns Unit))) - default-def-meta-exported) + (#ProdT Type (#ProdT Anns Void))) + (#Cons [["lux" "doc"] (#TextM "Represents all the data associated with a definition: its type, its annotations, and its value.")] + default-def-meta-exported)) ## (type: (Bindings k v) ## {#counter Nat @@ -435,7 +478,8 @@ (#Cons (#TextM "Right") #Nil)))] (#Cons [["lux" "type-args"] (#ListM (#Cons (#TextM "l") (#Cons (#TextM "r") #;Nil)))] - default-def-meta-exported))) + (#Cons [["lux" "doc"] (#TextM "A choice between two values of different types.")] + default-def-meta-exported)))) ## (type: Source ## (List (Meta Cursor Text))) @@ -490,15 +534,16 @@ (#Cons (#TextM "types") (#Cons (#TextM "module-anns") #Nil))))))))] - default-def-meta-exported)) + (#Cons [["lux" "doc"] (#TextM "All the information contained within a Lux module.")] + default-def-meta-exported))) -## (type: CompilerMode +## (type: Compiler-Mode ## #Release ## #Debug ## #Eval ## #REPL) -(_lux_def CompilerMode - (#NamedT ["lux" "CompilerMode"] +(_lux_def Compiler-Mode + (#NamedT ["lux" "Compiler-Mode"] (#SumT ## "lux;Release" #UnitT (#SumT ## "lux;Debug" @@ -512,28 +557,30 @@ (#Cons (#TextM "Eval") (#Cons (#TextM "REPL") #Nil)))))] - default-def-meta-exported)) + (#Cons [["lux" "doc"] (#TextM "A sign that shows the conditions under which the compiler is running.")] + default-def-meta-exported))) -## (type: CompilerInfo +## (type: Compiler-Info ## {#compiler-name Text ## #compiler-version Text -## #compiler-mode CompilerMode}) -(_lux_def CompilerInfo - (#NamedT ["lux" "CompilerInfo"] +## #compiler-mode Compiler-Mode}) +(_lux_def Compiler-Info + (#NamedT ["lux" "Compiler-Info"] (#ProdT ## "lux;compiler-name" Text (#ProdT ## "lux;compiler-version" Text ## "lux;compiler-mode" - CompilerMode))) + Compiler-Mode))) (#Cons [["lux" "tags"] (#ListM (#Cons (#TextM "compiler-name") (#Cons (#TextM "compiler-version") (#Cons (#TextM "compiler-mode") #Nil))))] - default-def-meta-exported)) + (#Cons [["lux" "doc"] (#TextM "Information about the current version and type of compiler that is running.")] + default-def-meta-exported))) ## (type: Compiler -## {#info CompilerInfo +## {#info Compiler-Info ## #source Source ## #cursor Cursor ## #modules (List [Text Module]) @@ -546,7 +593,7 @@ (_lux_def Compiler (#NamedT ["lux" "Compiler"] (#ProdT ## "lux;info" - CompilerInfo + Compiler-Info (#ProdT ## "lux;source" Source (#ProdT ## "lux;cursor" @@ -578,7 +625,8 @@ (#Cons (#TextM "host") #Nil)))))))))))] (#Cons [["lux" "doc"] (#TextM "Represents the state of the Lux compiler during a run. - It's provided to macros during their invocation, so they can access compiler data. + + It is provided to macros during their invocation, so they can access compiler data. Caveat emptor: Avoid fiddling with it, unless you know what you're doing.")] default-def-meta-exported))) @@ -601,7 +649,8 @@ (_lux_def Macro (#NamedT ["lux" "Macro"] (#LambdaT ASTList (#AppT Lux ASTList))) - default-def-meta-exported) + (#Cons [["lux" "doc"] (#TextM "Functions that run at compile-time and allow you to transform and extend the language in powerful ways.")] + default-def-meta-exported)) ## Base functions & macros ## (def: _cursor @@ -923,7 +972,7 @@ (macro:' #export (comment tokens) (#Cons [["lux" "doc"] (#TextM "## Throws away any code given to it. - ## Great for commenting out code, while retaining syntax high-lightning and formatting in your text editor. + ## Great for commenting-out code, while retaining syntax high-lighting and formatting in your text editor. (comment 1 2 3 4)")] #;Nil) (return #Nil)) @@ -1571,9 +1620,13 @@ ))) (macro:' #export (if tokens) - (list [["lux" "doc"] (#TextM "(if true + (list [["lux" "doc"] (#TextM "Picks which expression to evaluate based on a boolean test value. + + (if true \"Oh, yeah!\" - \"Aw hell naw!\")")]) + \"Aw hell naw!\") + + == \"Oh, yeah!\"")]) (_lux_case tokens (#Cons test (#Cons then (#Cons else #Nil))) (return (list (form$ (list (symbol$ ["" "_lux_case"]) test @@ -2142,7 +2195,11 @@ (i.= 0 (i.% div n))) (def:''' #export (not x) - #Nil + (list [["lux" "doc"] (#TextM "## Boolean negation. + + (not true) == false + + (not false) == true")]) (-> Bool Bool) (if x false true)) @@ -2664,7 +2721,7 @@ (macro:' #export (^ tokens) (list [["lux" "doc"] (#TextM "## Macro-expanding patterns. - ## It's a special macro meant to be used with case. + ## It's a special macro meant to be used with 'case'. (case (: (List Int) (list 1 2 3)) (^ (list x y z)) (#Some ($_ i.* x y z)) @@ -2687,15 +2744,15 @@ (macro:' #export (^or tokens) (list [["lux" "doc"] (#TextM "## Or-patterns. - ## It's a special macro meant to be used with case. + ## It's a special macro meant to be used with 'case'. (type: Weekday - (| #Monday - #Tuesday - #Wednesday - #Thursday - #Friday - #Saturday - #Sunday)) + #Monday + #Tuesday + #Wednesday + #Thursday + #Friday + #Saturday + #Sunday) (def: (weekend? day) (-> Weekday Bool) @@ -2913,7 +2970,10 @@ (#;Some (#;Right [])) (list (' #hidden)))) -(def:' #export (log! message) +(def:''' #export (log! message) + (list [["lux" "doc"] (#TextM "Logs message to standard output. + + Useful for debugging.")]) (-> Text Unit) (_lux_proc ["jvm" "invokevirtual:java.io.PrintStream:println:java.lang.String"] [(_lux_proc ["jvm" "getstatic:java.lang.System:out"] []) message])) @@ -3009,7 +3069,9 @@ base)) (macro:' #export (macro: tokens) - (list [["lux" "doc"] (#TextM "(macro: #export (ident-for tokens) + (list [["lux" "doc"] (#TextM "Macro-definition macro. + + (macro: #export (ident-for tokens) (case tokens (^template [<tag>] (^ (list [_ (<tag> [prefix name])])) @@ -3485,7 +3547,9 @@ (fail "Wrong syntax for struct:")))) (def: #export (id x) - {#;doc "Identity function. Does nothing to it's argument and just returns it."} + {#;doc "Identity function. + + Does nothing to it's argument and just returns it."} (All [a] (-> a a)) x) @@ -3502,8 +3566,8 @@ _ (fail <message>)))] - [and (if (~ pre) (~ post) false) "'and' requires >=1 clauses." "Short-circuiting \"and\"\n(and true false true) ## => false"] - [or (if (~ pre) true (~ post)) "'or' requires >=1 clauses." "Short-circuiting \"or\"\n(or true false true) ## => true"]) + [and (if (~ pre) (~ post) false) "'and' requires >=1 clauses." "Short-circuiting \"and\".\n(and true false true) ## => false"] + [or (if (~ pre) true (~ post)) "'or' requires >=1 clauses." "Short-circuiting \"or\".\n(or true false true) ## => true"]) (macro: #export (type: tokens) {#;doc "## The type-definition macro. @@ -3971,7 +4035,7 @@ (#Some def-type))))) (def: (find-def-value name state) - (-> Ident (Lux [Type Unit])) + (-> Ident (Lux [Type Void])) (let [[v-prefix v-name] name {#info info #source source #modules modules #scopes scopes #type-vars types #host host @@ -4136,8 +4200,8 @@ (macro: #export (cond tokens) {#;doc "## Branching structures with multiple test conditions. - (cond (even? num) \"even\" - (odd? num) \"odd\" + (cond (n.even? num) \"even\" + (n.odd? num) \"odd\" ## else-branch \"???\")"} (if (i.= 0 (i.% 2 (length tokens))) @@ -4289,7 +4353,7 @@ (macro: #export (default tokens state) {#;doc "## Allows you to provide a default value that will be used - ## if a (Maybe x) value turns out to be #;Some. + ## if a (Maybe x) value turns out to be #;None. (default 20 (#;Some 10)) => 10 (default 20 #;None) => 20"} @@ -4382,7 +4446,7 @@ (wrap (List/append defs openings)) )) -(macro: #export (refer tokens) +(macro: #hidden (refer tokens) (case tokens (^ (list& [_ (#TextS module-name)] options)) (do Monad<Lux> @@ -4417,7 +4481,11 @@ (~' #open) ((~@ =opens)))))) (macro: #export (module: tokens) - {#;doc "## Examples + {#;doc "Module-definition macro. + + Can take optional annotations and allows the specification of modules to import. + + ## Examples (;module: {#;doc \"Some documentation...\"} lux (lux (control (monad #as M #refer #all)) @@ -4668,9 +4736,6 @@ (#;BoundT idx) (default type (list;at idx env)) - (#;NamedT name type) - (beta-reduce env type) - _ type ))"} @@ -4774,15 +4839,17 @@ )] ($_ Text/append "\"" escaped "\""))) -(do-template [<name> <op> <one> <type>] +(do-template [<name> <op> <one> <type> <doc>] [(def: #export (<name> value) + {#;doc <doc>} (-> <type> <type>) (<op> <one> value))] - [i.inc i.+ 1 Int] - [i.dec i.- 1 Int] - [n.inc n.+ +1 Nat] - [n.dec n.- +1 Nat]) + [i.inc i.+ 1 Int "Increment function."] + [i.dec i.- 1 Int "Decrement function."] + [n.inc n.+ +1 Nat "Increment function."] + [n.dec n.- +1 Nat "Decrement function."] + ) (def: tag->Text (-> Ident Text) @@ -4879,17 +4946,16 @@ (Text/append text "\n\n")))) (macro: #export (doc tokens) - {#;doc "Creates code documentation, embedding text as comments and properly formatting the forms it's being given. + {#;doc "## Creates code documentation, embedding text as comments and properly formatting the forms it's being given. ## For Example: - (doc - \"Allows arbitrary looping, using the \\\"recur\\\" form to re-start the loop. - Can be used in monadic code to create monadic loops.\" - (loop [count 0 - x init] - (if (< 10 count) - (recur (i.inc count) (f x)) - x)))"} + (doc \"Allows arbitrary looping, using the \\\"recur\\\" form to re-start the loop. + Can be used in monadic code to create monadic loops.\" + (loop [count 0 + x init] + (if (< 10 count) + (recur (i.inc count) (f x)) + x)))"} (return (list (` (#;TextM (~ (|> tokens (map (. doc-fragment->Text identify-doc-fragment)) Text/join @@ -5258,7 +5324,7 @@ "Useful in situations where the result of a branch depends on further refinements on the values being matched." "For example:" (case (split (size static) uri) - (^=> (#;Some [chunk uri']) {(Text/= static chunk) true}) + (^=> (#;Some [chunk uri']) [(Text/= static chunk) true]) (match-uri endpoint? parts' uri') _ @@ -5344,6 +5410,14 @@ (list-at (n.dec idx) xs')))) (macro: #export ($ tokens) + {#;doc (doc "Allows you to refer to the type-variables in a polymorphic function's type, by their index." + "In the example below, +0 corresponds to the 'a' variable." + (def: #export (from-list list) + (All [a] (-> (List a) (Vector a))) + (List/fold add + (: (Vector ($ +0)) + empty) + list)))} (case tokens (^ (list [_ (#NatS idx)])) (do Monad<Lux> @@ -5371,10 +5445,10 @@ (macro: #export (^@ tokens) {#;doc (doc "Allows you to simultaneously bind and de-structure a value." - (def: (hash (^@ set [a/Hash _])) - (List/fold (lambda [elem acc] (i.+ (:: a/Hash hash elem) acc)) - 0 - (->List set))))} + (def: (hash (^@ set [Hash<a> _])) + (List/fold (lambda [elem acc] (n.+ (:: Hash<a> hash elem) acc)) + +0 + (to-list set))))} (case tokens (^ (list& [_meta (#;FormS (list [_ (#;SymbolS ["" name])] pattern))] body branches)) (let [g!whole (symbol$ ["" name])] @@ -5386,6 +5460,10 @@ (fail "Wrong syntax for ^@"))) (macro: #export (^|> tokens) + {#;doc (doc "Pipes the value being pattern-matched against prior to binding it to a variable." + (case input + (^|> value [n.inc (n.% +10) (n.max +1)]) + (foo value)))} (case tokens (^ (list& [_meta (#;FormS (list [_ (#;SymbolS ["" name])] [_ (#;TupleS steps)]))] body branches)) (let [g!name (symbol$ ["" name])] @@ -5447,9 +5525,11 @@ (macro: #export (undefined tokens) {#;doc (doc "Meant to be used as a stand-in for functions with undefined implementations." + "Undefined expressions will type-check against everything, so they make good dummy implementations." (def: (square x) (-> Int Int) - (undefined)))} + (undefined)) + "If an undefined expression is ever evaluated, it will raise an error.")} (case tokens #;Nil (return (list (` (error! (with-cursor "Undefined behavior."))))) @@ -5458,6 +5538,11 @@ (fail "Wrong syntax for undefined"))) (macro: #export (@pre tokens) + {#;doc (doc "Pre-conditions." + "Given a test and an expression to run, only runs the expression if the test passes." + "Otherwise, an error is raised." + (@pre (i.= 4 (i.+ 2 2)) + (foo 123 456 789)))} (case tokens (^ (list test expr)) (return (list (` (if (~ test) @@ -5468,6 +5553,12 @@ (fail "Wrong syntax for @pre"))) (macro: #export (@post tokens) + {#;doc (doc "Post-conditions." + "Given a predicate and an expression to run, evaluates the expression and then tests the output with the predicate." + "If the predicate returns true, returns the value of the expression." + "Otherwise, an error is raised." + (@post i.even? + (i.+ 2 2)))} (case tokens (^ (list test expr)) (do Monad<Lux> @@ -5493,6 +5584,11 @@ ) (macro: #export (type-of tokens) + {#;doc (doc "Generates the type corresponding to a given definition or variable." + (let [my-num (: Int 123)] + (type-of my-num)) + "==" + Int)} (case tokens (^ (list [_ (#;SymbolS var-name)])) (do Monad<Lux> |