aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/documentation/lux/control
diff options
context:
space:
mode:
Diffstat (limited to 'stdlib/source/documentation/lux/control')
-rw-r--r--stdlib/source/documentation/lux/control/concatenative.lux288
-rw-r--r--stdlib/source/documentation/lux/control/concurrency.lux28
-rw-r--r--stdlib/source/documentation/lux/control/concurrency/actor.lux131
-rw-r--r--stdlib/source/documentation/lux/control/concurrency/async.lux96
-rw-r--r--stdlib/source/documentation/lux/control/concurrency/atom.lux39
-rw-r--r--stdlib/source/documentation/lux/control/concurrency/frp.lux66
-rw-r--r--stdlib/source/documentation/lux/control/concurrency/semaphore.lux69
-rw-r--r--stdlib/source/documentation/lux/control/concurrency/stm.lux52
-rw-r--r--stdlib/source/documentation/lux/control/concurrency/thread.lux26
-rw-r--r--stdlib/source/documentation/lux/control/continuation.lux53
-rw-r--r--stdlib/source/documentation/lux/control/exception.lux78
-rw-r--r--stdlib/source/documentation/lux/control/function.lux48
-rw-r--r--stdlib/source/documentation/lux/control/io.lux36
-rw-r--r--stdlib/source/documentation/lux/control/lazy.lux32
-rw-r--r--stdlib/source/documentation/lux/control/maybe.lux57
15 files changed, 1099 insertions, 0 deletions
diff --git a/stdlib/source/documentation/lux/control/concatenative.lux b/stdlib/source/documentation/lux/control/concatenative.lux
new file mode 100644
index 000000000..495bc5512
--- /dev/null
+++ b/stdlib/source/documentation/lux/control/concatenative.lux
@@ -0,0 +1,288 @@
+(.module:
+ [library
+ [lux (#- if loop)
+ ["$" documentation (#+ documentation:)]
+ [data
+ [text (#+ \n)
+ ["%" format (#+ format)]]
+ [collection
+ ["." list ("#\." monad)]]]
+ [macro
+ ["." template]]
+ [math
+ [number
+ ["n" nat]
+ ["i" int]
+ ["r" rev]
+ ["f" frac]]]]]
+ [\\library
+ ["." /]])
+
+(documentation: /.=>
+ "Concatenative function types."
+ [(=> [Nat] [Nat])]
+ [(All [a]
+ (-> a (=> [] [a])))]
+ [(All [t]
+ (=> [t] []))]
+ [(All [a b c]
+ (=> [a b c] [b c a]))]
+ [(All [___a ___z]
+ (=> {then (=> ___a ___z)
+ else (=> ___a ___z)}
+ ___a [Bit then else] ___z))])
+
+(documentation: /.||>
+ "A self-contained sequence of concatenative instructions."
+ [(same? value
+ (||> (push sample)))]
+ [(||> (push 123)
+ dup
+ n/=)])
+
+(documentation: /.word:
+ "A named concatenative function."
+ [(word: square
+ (=> [Nat] [Nat])
+
+ dup
+ (apply/2 n.*))])
+
+(documentation: /.apply
+ "A generator for functions that turn arity N functions into arity N concatenative functions."
+ [(: (=> [Nat] [Nat])
+ ((apply 1) inc))])
+
+(template [<arity>]
+ [(with_expansions [<name> (template.identifier [/._] ["apply/" <arity>])
+ <doc> (template.text ["Lift a function of arity " <arity>
+ " into a concatenative function of arity " <arity> "."])
+ <function_of_arity> (template.identifier ["function_of_arity_" <arity>])]
+ (documentation: <name>
+ <doc>
+ [(<arity> <function_of_arity>)]))]
+
+ [1] [2] [3] [4]
+ [5] [6] [7] [8]
+ )
+
+(documentation: /.push
+ "Push a value onto the stack.")
+
+(documentation: /.drop
+ "Drop/pop a value from the top of the stack.")
+
+(documentation: /.nip
+ "Drop the second-to-last value from the top of the stack.")
+
+(documentation: /.dup
+ "Duplicate the top of the stack.")
+
+(documentation: /.swap
+ "Swaps the 2 topmost stack values.")
+
+(documentation: /.rotL
+ "Rotes the 3 topmost stack values to the left.")
+
+(documentation: /.rotR
+ "Rotes the 3 topmost stack values to the right.")
+
+(documentation: /.&&
+ "Groups the 2 topmost stack values as a 2-tuple.")
+
+(documentation: /.||L
+ "Left-injects the top into sum.")
+
+(documentation: /.||R
+ "Right-injects the top into sum.")
+
+(template [<input> <word> <func>]
+ [(`` (documentation: (~~ (template.identifier [/._] [<word>]))
+ (~~ (template.text [<func> " for " <input> " arithmetic."]))))]
+
+ [Nat n/+ n.+]
+ [Nat n/- n.-]
+ [Nat n/* n.*]
+ [Nat n// n./]
+ [Nat n/% n.%]
+ [Nat n/= n.=]
+ [Nat n/< n.<]
+ [Nat n/<= n.<=]
+ [Nat n/> n.>]
+ [Nat n/>= n.>=]
+
+ [Int i/+ i.+]
+ [Int i/- i.-]
+ [Int i/* i.*]
+ [Int i// i./]
+ [Int i/% i.%]
+ [Int i/= i.=]
+ [Int i/< i.<]
+ [Int i/<= i.<=]
+ [Int i/> i.>]
+ [Int i/>= i.>=]
+
+ [Rev r/+ r.+]
+ [Rev r/- r.-]
+ [Rev r/* r.*]
+ [Rev r// r./]
+ [Rev r/% r.%]
+ [Rev r/= r.=]
+ [Rev r/< r.<]
+ [Rev r/<= r.<=]
+ [Rev r/> r.>]
+ [Rev r/>= r.>=]
+
+ [Frac f/+ f.+]
+ [Frac f/- f.-]
+ [Frac f/* f.*]
+ [Frac f// f./]
+ [Frac f/% f.%]
+ [Frac f/= f.=]
+ [Frac f/< f.<]
+ [Frac f/<= f.<=]
+ [Frac f/> f.>]
+ [Frac f/>= f.>=]
+ )
+
+(documentation: /.if
+ "If expression."
+ [(same? "then"
+ (||> (push true)
+ (push "then")
+ (push "else")
+ if))])
+
+(documentation: /.call
+ "Executes an anonymous block on the stack.")
+
+(documentation: /.loop
+ "Executes a block as a loop until it yields #0 to stop.")
+
+(documentation: /.dip
+ "Executes a block on the stack, save for the topmost value.")
+
+(documentation: /.dip/2
+ "Executes a block on the stack, save for the 2 topmost values.")
+
+(documentation: /.do
+ "Do-while loop expression."
+ [(n.= (inc sample)
+ (||> (push sample)
+ (push (push false))
+ (push (|>> (push 1) n/+))
+ do while))])
+
+(documentation: /.while
+ "While loop expression."
+ [(n.= (n.+ distance start)
+ (||> (push start)
+ (push (|>> dup
+ (push start) n/-
+ (push distance) n/<))
+ (push (|>> (push 1) n/+))
+ while))])
+
+(documentation: /.compose
+ "Function composition."
+ [(n.= (n.+ 2 sample)
+ (||> (push sample)
+ (push (|>> (push 1) n/+))
+ (push (|>> (push 1) n/+))
+ compose
+ call))])
+
+(documentation: /.partial
+ "Partial application."
+ [(n.= (n.+ sample sample)
+ (||> (push sample)
+ (push sample)
+ (push n/+)
+ partial
+ call))])
+
+(documentation: /.when
+ "Only execute the block when #1.")
+
+(documentation: /.?
+ "Choose the top value when #0 and the second-to-top when #1.")
+
+(.def: .public documentation
+ (.List $.Module)
+ ($.module /._
+ ""
+ [..=>
+ ..||>
+ ..word:
+ ..apply
+ ..apply/1
+ ..apply/2
+ ..apply/3
+ ..apply/4
+ ..apply/5
+ ..apply/6
+ ..apply/7
+ ..apply/8
+ ..push
+ ..drop
+ ..nip
+ ..dup
+ ..swap
+ ..rotL
+ ..rotR
+ ..&&
+ ..||L
+ ..||R
+ ..if
+ ..call
+ ..loop
+ ..dip
+ ..dip/2
+ ..do
+ ..while
+ ..compose
+ ..partial
+ ..when
+ ..?
+
+ ..n/+
+ ..n/-
+ ..n/*
+ ..n//
+ ..n/%
+ ..n/=
+ ..n/<
+ ..n/<=
+ ..n/>
+ ..n/>=
+ ..i/+
+ ..i/-
+ ..i/*
+ ..i//
+ ..i/%
+ ..i/=
+ ..i/<
+ ..i/<=
+ ..i/>
+ ..i/>=
+ ..r/+
+ ..r/-
+ ..r/*
+ ..r//
+ ..r/%
+ ..r/=
+ ..r/<
+ ..r/<=
+ ..r/>
+ ..r/>=
+ ..f/+
+ ..f/-
+ ..f/*
+ ..f//
+ ..f/%
+ ..f/=
+ ..f/<
+ ..f/<=
+ ..f/>
+ ..f/>=]
+ []))
diff --git a/stdlib/source/documentation/lux/control/concurrency.lux b/stdlib/source/documentation/lux/control/concurrency.lux
new file mode 100644
index 000000000..f9b751494
--- /dev/null
+++ b/stdlib/source/documentation/lux/control/concurrency.lux
@@ -0,0 +1,28 @@
+(.module:
+ [library
+ [lux #*
+ ["$" documentation (#+ documentation:)]
+ [data
+ [text (#+ \n)
+ ["%" format (#+ format)]]
+ [collection
+ ["." list]]]]]
+ ["." / #_
+ ["#." actor]
+ ["#." async]
+ ["#." atom]
+ ["#." frp]
+ ["#." semaphore]
+ ["#." stm]
+ ["#." thread]])
+
+(.def: .public documentation
+ (.List $.Module)
+ (list.joined
+ (list /actor.documentation
+ /async.documentation
+ /atom.documentation
+ /frp.documentation
+ /semaphore.documentation
+ /stm.documentation
+ /thread.documentation)))
diff --git a/stdlib/source/documentation/lux/control/concurrency/actor.lux b/stdlib/source/documentation/lux/control/concurrency/actor.lux
new file mode 100644
index 000000000..29513888c
--- /dev/null
+++ b/stdlib/source/documentation/lux/control/concurrency/actor.lux
@@ -0,0 +1,131 @@
+(.module:
+ [library
+ [lux (#- if loop)
+ ["$" documentation (#+ documentation:)]
+ [data
+ [text (#+ \n)
+ ["%" format (#+ format)]]
+ [collection
+ ["." list ("#\." monad)]]]
+ [macro
+ ["." template]]]]
+ [\\library
+ ["." /]])
+
+(documentation: /.Actor
+ "An entity that can react to messages (mail) sent to it concurrently.")
+
+(documentation: /.Mail
+ "A one-way message sent to an actor, without expecting a reply.")
+
+(documentation: /.Obituary
+ "Details on the death of an actor.")
+
+(documentation: /.Behavior
+ "An actor's behavior when mail is received and when a fatal error occurs.")
+
+(documentation: /.spawn!
+ "Given a behavior and initial state, spawns an actor and returns it.")
+
+(documentation: /.obituary
+ "Await for an actor to stop working.")
+
+(documentation: /.mail!
+ "Send mail to an actor.")
+
+(documentation: /.Message
+ "A two-way message sent to an actor, expecting a reply.")
+
+(documentation: /.tell!
+ "Communicate with an actor through message-passing.")
+
+(documentation: /.default
+ "Default actor behavior.")
+
+(documentation: /.poison!
+ (format "Kills the actor by sending mail that will kill it upon processing,"
+ \n "but allows the actor to handle previous mail."))
+
+(with_expansions [<examples> (as_is (actor: .public (stack a)
+ {}
+
+ (List a)
+
+ ((on_mail mail state self)
+ (do (try.with async.monad)
+ [.let [_ (debug.log! "BEFORE")]
+ output (mail state self)
+ .let [_ (debug.log! "AFTER")]]
+ (in output)))
+
+ (message: .public (push {value a} state self)
+ (List a)
+ (let [state' (#.Item value state)]
+ (async.resolved (#try.Success [state' state'])))))
+
+ (actor: .public counter
+ {}
+
+ Nat
+
+ (message: .public (count! {increment Nat} state self)
+ Any
+ (let [state' (n.+ increment state)]
+ (async.resolved (#try.Success [state' state']))))
+
+ (message: .public (read! state self)
+ Nat
+ (async.resolved (#try.Success [state state])))))]
+ (documentation: /.actor:
+ (format "Defines a named actor, with its behavior and internal state."
+ \n "Messages for the actor must be defined after the on_mail handler.")
+ [<examples>])
+
+ (documentation: /.actor
+ (format "Defines an anonymous actor, with its behavior and internal state."
+ \n "Messages for the actor must be defined after the on_mail handler.")
+ [(actor {Nat
+ 123}
+ ((on_mail message state self)
+ (message (inc state) self)))])
+
+ (documentation: /.message:
+ (format "A message can access the actor's state through the state parameter."
+ \n "A message can also access the actor itself through the self parameter."
+ \n "A message's output must be an async containing a 2-tuple with the updated state and a return value."
+ \n "A message may succeed or fail (in case of failure, the actor dies).")
+ [<examples>]))
+
+(documentation: /.Stop
+ "A signal to stop an actor from observing a channel.")
+
+(documentation: /.observe!
+ (format "Use an actor to observe a channel by transforming each datum"
+ \n "flowing through the channel into mail the actor can process."
+ \n "Can stop observing the channel by executing the Stop value."))
+
+(.def: .public documentation
+ (.List $.Module)
+ ($.module /._
+ "The actor model of concurrency."
+ [..Actor
+ ..Mail
+ ..Obituary
+ ..Behavior
+ ..spawn!
+ ..obituary
+ ..mail!
+ ..Message
+ ..tell!
+ ..default
+ ..poison!
+ ..actor:
+ ..actor
+ ..message:
+ ..Stop
+ ..observe!
+ ($.default /.poisoned)
+ ($.default /.dead)
+ ($.default /.alive?)
+ ($.default /.obituary')]
+ []))
diff --git a/stdlib/source/documentation/lux/control/concurrency/async.lux b/stdlib/source/documentation/lux/control/concurrency/async.lux
new file mode 100644
index 000000000..2842ed06b
--- /dev/null
+++ b/stdlib/source/documentation/lux/control/concurrency/async.lux
@@ -0,0 +1,96 @@
+(.module:
+ [library
+ [lux (#- or and)
+ ["$" documentation (#+ documentation:)]
+ [data
+ [text (#+ \n)
+ ["%" format (#+ format)]]]
+ [macro
+ ["." template]]]]
+ [\\library
+ ["." /]])
+
+(documentation: /.Async
+ "Represents values produced by asynchronous computations (unlike IO, which is synchronous).")
+
+(documentation: /.Resolver
+ (format "The function used to give a value to an async."
+ \n "Will signal 'true' if the async has been resolved for the 1st time, 'false' otherwise."))
+
+(documentation: /.resolved
+ "Produces an async that has already been resolved to the given value."
+ [(resolved value)])
+
+(documentation: /.async
+ "Creates a fresh async that has not been resolved yet."
+ [(async _)])
+
+(documentation: /.value
+ "Polls an async for its value.")
+
+(documentation: /.upon!
+ "Executes the given function as soon as the async has been resolved."
+ [(upon! function async)])
+
+(documentation: /.resolved?
+ "Checks whether an async's value has already been resolved.")
+
+(documentation: /.and
+ "Combines the results of both asyncs, in-order."
+ [(and left right)])
+
+(documentation: /.or
+ (format "Yields the results of whichever async gets resolved first."
+ \n "You can tell which one was resolved first through pattern-matching.")
+ [(or left right)])
+
+(documentation: /.either
+ (format "Yields the results of whichever async gets resolved first."
+ \n "You cannot tell which one was resolved first.")
+ [(either left right)])
+
+(documentation: /.schedule!
+ (format "Runs an I/O computation on its own thread (after a specified delay)."
+ \n "Returns an async that will eventually host its result.")
+ [(schedule! milli_seconds computation)])
+
+(documentation: /.future
+ (format "Runs an I/O computation on its own thread."
+ \n "Returns an async that will eventually host its result.")
+ [(future computation)])
+
+(documentation: /.delayed
+ "Delivers a value after a certain period has passed."
+ [(delayed milli_seconds value)])
+
+(documentation: /.delay
+ "An async that will be resolved after the specified amount of milli-seconds."
+ [(delay milli_seconds)])
+
+(documentation: /.time_out
+ "Wait for an async to be resolved within the specified amount of milli-seconds."
+ [(time_out milli_seconds async)])
+
+(.def: .public documentation
+ (.List $.Module)
+ ($.module /._
+ ""
+ [..Async
+ ..Resolver
+ ..resolved
+ ..async
+ ..value
+ ..upon!
+ ..resolved?
+ ..and
+ ..or
+ ..either
+ ..schedule!
+ ..future
+ ..delayed
+ ..delay
+ ..time_out
+ ($.default /.functor)
+ ($.default /.apply)
+ ($.default /.monad)]
+ []))
diff --git a/stdlib/source/documentation/lux/control/concurrency/atom.lux b/stdlib/source/documentation/lux/control/concurrency/atom.lux
new file mode 100644
index 000000000..8b35c1c7e
--- /dev/null
+++ b/stdlib/source/documentation/lux/control/concurrency/atom.lux
@@ -0,0 +1,39 @@
+(.module:
+ [library
+ [lux (#- if loop)
+ ["$" documentation (#+ documentation:)]
+ [data
+ [text (#+ \n)
+ ["%" format (#+ format)]]]
+ [macro
+ ["." template]]]]
+ [\\library
+ ["." /]])
+
+(documentation: /.Atom
+ "Atomic references that are safe to mutate concurrently.")
+
+(documentation: /.compare_and_swap!
+ (format "Only mutates an atom if you can present its current value."
+ \n "That guarantees that atom was not updated since you last read from it."))
+
+(documentation: /.update!
+ (format "Updates an atom by applying a function to its current value."
+ \n "If it fails to update it (because some other process wrote to it first), it will retry until it succeeds."
+ \n "The retries will be done with the new values of the atom, as they show up."))
+
+(documentation: /.write!
+ (format "Writes the given value to an atom."
+ \n "If it fails to write it (because some other process wrote to it first), it will retry until it succeeds."))
+
+(.def: .public documentation
+ (.List $.Module)
+ ($.module /._
+ ""
+ [..Atom
+ ..compare_and_swap!
+ ..update!
+ ..write!
+ ($.default /.atom)
+ ($.default /.read!)]
+ []))
diff --git a/stdlib/source/documentation/lux/control/concurrency/frp.lux b/stdlib/source/documentation/lux/control/concurrency/frp.lux
new file mode 100644
index 000000000..71f740782
--- /dev/null
+++ b/stdlib/source/documentation/lux/control/concurrency/frp.lux
@@ -0,0 +1,66 @@
+(.module:
+ [library
+ [lux (#- if loop)
+ ["$" documentation (#+ documentation:)]
+ [data
+ [text (#+ \n)
+ ["%" format (#+ format)]]]
+ [macro
+ ["." template]]]]
+ [\\library
+ ["." /]])
+
+(documentation: /.Channel
+ "An asynchronous channel to distribute values.")
+
+(documentation: /.Sink
+ "The tail-end of a channel, which can be written-to to fee the channel.")
+
+(documentation: /.channel
+ "Creates a brand-new channel and hands it over, along with the sink to write to it."
+ [(channel _)])
+
+(documentation: /.Subscriber
+ "A function that can receive every value fed into a channel.")
+
+(documentation: /.only
+ (format "Produces a new channel based on the old one, only with values"
+ \n "that pass the test.")
+ [(only pass? channel)])
+
+(documentation: /.of_async
+ "A one-element channel containing the output from an async."
+ [(of_async async)])
+
+(documentation: /.fold
+ "Asynchronous fold over channels."
+ [(fold f init channel)])
+
+(documentation: /.sequential
+ "Transforms the given list into a channel with the same elements."
+ [(sequential milli_seconds values)])
+
+(.def: .public documentation
+ (.List $.Module)
+ ($.module /._
+ ""
+ [..Channel
+ ..Sink
+ ..channel
+ ..Subscriber
+ ..only
+ ..of_async
+ ..fold
+ ..sequential
+ ($.default /.channel_is_already_closed)
+ ($.default /.functor)
+ ($.default /.apply)
+ ($.default /.monad)
+ ($.default /.subscribe!)
+ ($.default /.folds)
+ ($.default /.poll)
+ ($.default /.periodic)
+ ($.default /.iterations)
+ ($.default /.distinct)
+ ($.default /.list)]
+ []))
diff --git a/stdlib/source/documentation/lux/control/concurrency/semaphore.lux b/stdlib/source/documentation/lux/control/concurrency/semaphore.lux
new file mode 100644
index 000000000..4530b5455
--- /dev/null
+++ b/stdlib/source/documentation/lux/control/concurrency/semaphore.lux
@@ -0,0 +1,69 @@
+(.module:
+ [library
+ [lux (#- if loop)
+ ["$" documentation (#+ documentation:)]
+ [data
+ [text (#+ \n)
+ ["%" format (#+ format)]]]
+ [macro
+ ["." template]]]]
+ [\\library
+ ["." /]])
+
+(documentation: /.Semaphore
+ "A tool for controlling access to resources by multiple concurrent processes.")
+
+(documentation: /.semaphore
+ ""
+ [(semaphore initial_open_positions)])
+
+(documentation: /.wait!
+ (format "Wait on a semaphore until there are open positions."
+ \n "After finishing your work, you must 'signal' to the semaphore that you're done.")
+ [(wait! semaphore)])
+
+(documentation: /.signal!
+ "Signal to a semaphore that you're done with your work, and that there is a new open position."
+ [(signal! semaphore)])
+
+(documentation: /.Mutex
+ "A mutual-exclusion lock that can only be acquired by one process at a time.")
+
+(documentation: /.mutex
+ "Creates a brand-new mutex."
+ [(mutex _)])
+
+(documentation: /.synchronize!
+ "Runs the procedure with exclusive control of the mutex."
+ [(synchronize! mutex procedure)])
+
+(documentation: /.limit
+ "Produce a limit for a barrier.")
+
+(documentation: /.Limit
+ "A limit for barriers.")
+
+(documentation: /.Barrier
+ "A barrier that blocks all processes from proceeding until a given number of processes are parked at the barrier.")
+
+(documentation: /.block!
+ "Wait on a barrier until all processes have arrived and met the barrier's limit.")
+
+(.def: .public documentation
+ (.List $.Module)
+ ($.module /._
+ ""
+ [..Semaphore
+ ..semaphore
+ ..wait!
+ ..signal!
+ ..Mutex
+ ..mutex
+ ..synchronize!
+ ..limit
+ ..Limit
+ ..Barrier
+ ..block!
+ ($.default /.semaphore_is_maxed_out)
+ ($.default /.barrier)]
+ []))
diff --git a/stdlib/source/documentation/lux/control/concurrency/stm.lux b/stdlib/source/documentation/lux/control/concurrency/stm.lux
new file mode 100644
index 000000000..ebb46e87a
--- /dev/null
+++ b/stdlib/source/documentation/lux/control/concurrency/stm.lux
@@ -0,0 +1,52 @@
+(.module:
+ [library
+ [lux (#- if loop)
+ ["$" documentation (#+ documentation:)]
+ [data
+ [text (#+ \n)
+ ["%" format (#+ format)]]]
+ [macro
+ ["." template]]]]
+ [\\library
+ ["." /]])
+
+(documentation: /.Var
+ "A mutable cell containing a value, and observers that will be alerted of any change to it.")
+
+(documentation: /.var
+ "Creates a new STM var, with a default value."
+ [(var value)])
+
+(documentation: /.follow!
+ "Creates a channel that will receive all changes to the value of the given var."
+ [(follow! target)])
+
+(documentation: /.STM
+ "A computation which updates a transaction and produces a value.")
+
+(documentation: /.update
+ "Update a var's value, and return a tuple with the old and the new values."
+ [(update function var)])
+
+(documentation: /.commit!
+ (format "Commits a transaction and returns its result (asynchronously)."
+ \n "Note that a transaction may be re-run an indeterminate number of times if other transactions involving the same variables successfully commit first."
+ \n "For this reason, it's important to note that transactions must be free from side-effects, such as I/O.")
+ [(commit! procedure)])
+
+(.def: .public documentation
+ (.List $.Module)
+ ($.module /._
+ ""
+ [..Var
+ ..var
+ ..follow!
+ ..STM
+ ..update
+ ..commit!
+ ($.default /.read)
+ ($.default /.write)
+ ($.default /.functor)
+ ($.default /.apply)
+ ($.default /.monad)]
+ []))
diff --git a/stdlib/source/documentation/lux/control/concurrency/thread.lux b/stdlib/source/documentation/lux/control/concurrency/thread.lux
new file mode 100644
index 000000000..6de9b7fb7
--- /dev/null
+++ b/stdlib/source/documentation/lux/control/concurrency/thread.lux
@@ -0,0 +1,26 @@
+(.module:
+ [library
+ [lux (#- if loop)
+ ["$" documentation (#+ documentation:)]
+ [data
+ [text (#+ \n)
+ ["%" format (#+ format)]]]
+ [macro
+ ["." template]]]]
+ [\\library
+ ["." /]])
+
+(documentation: /.parallelism
+ "How many processes can run in parallel.")
+
+(documentation: /.schedule!
+ "Executes an I/O procedure after some milli-seconds."
+ [(schedule! milli_seconds action)])
+
+(.def: .public documentation
+ (.List $.Module)
+ ($.module /._
+ ""
+ [..parallelism
+ ..schedule!]
+ []))
diff --git a/stdlib/source/documentation/lux/control/continuation.lux b/stdlib/source/documentation/lux/control/continuation.lux
new file mode 100644
index 000000000..ebb778373
--- /dev/null
+++ b/stdlib/source/documentation/lux/control/continuation.lux
@@ -0,0 +1,53 @@
+(.module:
+ [library
+ [lux (#- if loop)
+ ["$" documentation (#+ documentation:)]
+ [data
+ [text (#+ \n)
+ ["%" format (#+ format)]]]
+ [macro
+ ["." template]]]]
+ [\\library
+ ["." /]])
+
+(documentation: /.Cont
+ "Continuations.")
+
+(documentation: /.continued
+ "Continues a continuation thunk."
+ [(continued next cont)])
+
+(documentation: /.result
+ "Forces a continuation thunk to be evaluated."
+ [(result cont)])
+
+(documentation: /.with_current
+ "Call with current continuation."
+ [(with_current
+ (function (_ go)
+ (do /.monad
+ [.let [nexus (function (nexus val)
+ (go [nexus val]))]
+ _ (go [nexus init])]
+ (in (undefined)))))])
+
+(documentation: /.pending
+ "Turns any expression into a function that is pending a continuation."
+ [(pending (some_function some_input))])
+
+(.def: .public documentation
+ (.List $.Module)
+ ($.module /._
+ ""
+ [..Cont
+ ..continued
+ ..result
+ ..with_current
+ ..pending
+ ($.default /.reset)
+ ($.default /.shift)
+ ($.default /.functor)
+ ($.default /.apply)
+ ($.default /.monad)
+ ($.default /.portal)]
+ []))
diff --git a/stdlib/source/documentation/lux/control/exception.lux b/stdlib/source/documentation/lux/control/exception.lux
new file mode 100644
index 000000000..ec225630a
--- /dev/null
+++ b/stdlib/source/documentation/lux/control/exception.lux
@@ -0,0 +1,78 @@
+(.module:
+ [library
+ [lux (#- if loop)
+ ["$" documentation (#+ documentation:)]
+ [data
+ [text (#+ \n)
+ ["%" format (#+ format)]]]
+ [macro
+ ["." template]]]]
+ [\\library
+ ["." /]])
+
+(documentation: /.Exception
+ "An exception provides a way to decorate error messages.")
+
+(documentation: /.match?
+ "Is this exception the cause of the error message?"
+ [(match? exception error)])
+
+(documentation: /.when
+ (format "If a particular exception is detected on a possibly-erroneous value, handle it."
+ \n "If no exception was detected, or a different one from the one being checked, then pass along the original value.")
+ [(when exception then try)])
+
+(documentation: /.otherwise
+ "If no handler could be found to catch the exception, then run a function as a last-resort measure."
+ [(otherwise else try)])
+
+(documentation: /.error
+ "Constructs an error message from an exception."
+ [(error exception message)])
+
+(documentation: /.except
+ "Decorate an error message with an Exception and lift it into the error-handling context."
+ [(except exception message)])
+
+(documentation: /.exception:
+ (format "Define a new exception type."
+ \n "It mostly just serves as a way to tag error messages for later catching.")
+ ["Simple case:"
+ (exception: .public some_exception)]
+ ["Complex case:"
+ (exception: .public [arbitrary type variables] (some_exception {optional Text} {arguments Int})
+ optional_body)])
+
+(documentation: /.report
+ "An error report."
+ [(: Text
+ (report ["Row 0" value/0]
+ ["Row 1" value/1]
+ ,,,
+ ["Row N" value/N]))])
+
+(documentation: /.listing
+ (format "A numbered report of the entries on a list."
+ \n "NOTE: 0-based numbering.")
+ [(listing format entries)])
+
+(documentation: /.with
+ "If a computation fails, prepends the exception to the error."
+ [(with exception message computation)])
+
+(.def: .public documentation
+ (.List $.Module)
+ ($.module /._
+ ""
+ [..Exception
+ ..match?
+ ..when
+ ..otherwise
+ ..error
+ ..except
+ ..exception:
+ ..report
+ ..listing
+ ..with
+ ($.default /.assertion)]
+ []))
diff --git a/stdlib/source/documentation/lux/control/function.lux b/stdlib/source/documentation/lux/control/function.lux
new file mode 100644
index 000000000..889cc8655
--- /dev/null
+++ b/stdlib/source/documentation/lux/control/function.lux
@@ -0,0 +1,48 @@
+(.module:
+ [library
+ [lux (#- if loop)
+ ["$" documentation (#+ documentation:)]
+ [data
+ [text (#+ \n)
+ ["%" format (#+ format)]]]
+ [macro
+ ["." template]]]]
+ [\\library
+ ["." /]])
+
+(documentation: /.identity
+ (format "Identity function."
+ \n "Does nothing to its argument and just returns it.")
+ [(same? (identity value)
+ value)])
+
+(documentation: /.composite
+ "Function composition."
+ [(= ((composite f g) "foo")
+ (f (g "foo")))])
+
+(documentation: /.constant
+ "Create constant functions."
+ [(= ((constant "foo") "bar")
+ "foo")])
+
+(documentation: /.flipped
+ "Flips the order of the arguments of a function."
+ [(= ((flipped f) "foo" "bar")
+ (f "bar" "foo"))])
+
+(documentation: /.apply
+ "Simple 1-argument function application."
+ [(apply input function)])
+
+(.def: .public documentation
+ (.List $.Module)
+ ($.module /._
+ ""
+ [..identity
+ ..composite
+ ..constant
+ ..flipped
+ ..apply
+ ($.default /.monoid)]
+ []))
diff --git a/stdlib/source/documentation/lux/control/io.lux b/stdlib/source/documentation/lux/control/io.lux
new file mode 100644
index 000000000..81cf08740
--- /dev/null
+++ b/stdlib/source/documentation/lux/control/io.lux
@@ -0,0 +1,36 @@
+(.module:
+ [library
+ [lux (#- if loop)
+ ["$" documentation (#+ documentation:)]
+ [data
+ [text (#+ \n)
+ ["%" format (#+ format)]]]
+ [macro
+ ["." template]]]]
+ [\\library
+ ["." /]])
+
+(documentation: /.IO
+ "A type that represents synchronous, effectful computations that may interact with the outside world.")
+
+(documentation: /.io
+ (format "Delays the evaluation of an expression, by wrapping it in an IO 'thunk'."
+ \n "Great for wrapping effectful computations (which will not be performed until the IO is 'run!').")
+ [(io (exec
+ (log! msg)
+ "Some value..."))])
+
+(documentation: /.run!
+ "A way to execute IO computations and perform their side-effects.")
+
+(.def: .public documentation
+ (.List $.Module)
+ ($.module /._
+ ""
+ [..IO
+ ..io
+ ..run!
+ ($.default /.functor)
+ ($.default /.apply)
+ ($.default /.monad)]
+ []))
diff --git a/stdlib/source/documentation/lux/control/lazy.lux b/stdlib/source/documentation/lux/control/lazy.lux
new file mode 100644
index 000000000..7a5b3217d
--- /dev/null
+++ b/stdlib/source/documentation/lux/control/lazy.lux
@@ -0,0 +1,32 @@
+(.module:
+ [library
+ [lux (#- if loop)
+ ["$" documentation (#+ documentation:)]
+ [data
+ [text (#+ \n)
+ ["%" format (#+ format)]]]
+ [macro
+ ["." template]]]]
+ [\\library
+ ["." /]])
+
+(documentation: /.Lazy
+ (format "A value specified by an expression that is calculated only at the last moment possible."
+ \n "Afterwards, the value is cached for future reference."))
+
+(documentation: /.lazy
+ "Specifies a lazy value by providing the expression that computes it."
+ [(lazy eager_computation)])
+
+(.def: .public documentation
+ (.List $.Module)
+ ($.module /._
+ ""
+ [..Lazy
+ ..lazy
+ ($.default /.value)
+ ($.default /.equivalence)
+ ($.default /.functor)
+ ($.default /.apply)
+ ($.default /.monad)]
+ []))
diff --git a/stdlib/source/documentation/lux/control/maybe.lux b/stdlib/source/documentation/lux/control/maybe.lux
new file mode 100644
index 000000000..dabdcde5e
--- /dev/null
+++ b/stdlib/source/documentation/lux/control/maybe.lux
@@ -0,0 +1,57 @@
+(.module:
+ [library
+ [lux (#- if loop)
+ ["$" documentation (#+ documentation:)]
+ [data
+ [text (#+ \n)
+ ["%" format (#+ format)]]]
+ [macro
+ ["." template]]]]
+ [\\library
+ ["." /]])
+
+(documentation: /.lifted
+ "Wraps a monadic value with Maybe machinery."
+ [(lifted monad)])
+
+(documentation: /.else
+ (format "Allows you to provide a default value that will be used"
+ \n "if a (Maybe x) value turns out to be #.None."
+ \n "Note: the expression for the default value will not be computed if the base computation succeeds.")
+ [(else +20 (#.Some +10))
+ "=>"
+ +10]
+ [(else +20 #.None)
+ "=>"
+ +20])
+
+(documentation: /.trusted
+ (format "Assumes that a Maybe value is a #.Some and yields its value."
+ \n "Raises/throws a runtime error otherwise."
+ \n "WARNING: Use with caution.")
+ [(trusted trusted_computation)])
+
+(documentation: /.when
+ "Can be used as a guard in (co)monadic be/do expressions."
+ [(do monad
+ [value (do_something 1 2 3)
+ /.when (passes_test? value)]
+ (do_something_else 4 5 6))])
+
+(.def: .public documentation
+ (.List $.Module)
+ ($.module /._
+ ""
+ [..lifted
+ ..else
+ ..trusted
+ ..when
+ ($.default /.monoid)
+ ($.default /.functor)
+ ($.default /.apply)
+ ($.default /.monad)
+ ($.default /.equivalence)
+ ($.default /.hash)
+ ($.default /.with)
+ ($.default /.list)]
+ []))