From e814f667aed509a70bd386dcd54628929134def4 Mon Sep 17 00:00:00 2001
From: Eduardo Julian
Date: Thu, 26 Aug 2021 02:34:05 -0400
Subject: "Interface" instead of "interface:", and "Rec" can be used in type
 definition.

---
 .../the_lux_programming_language/appendix_e.md     | 131 ++++++++
 lux-mode/lux-mode.el                               |   3 +-
 stdlib/source/documentation/lux.lux                |  32 +-
 .../documentation/lux/control/security/policy.lux  |  11 +-
 .../documentation/lux/data/collection/array.lux    |   2 +-
 .../documentation/lux/data/collection/list.lux     |   2 +-
 stdlib/source/documentation/lux/ffi.lux            |   2 +-
 .../documentation/lux/macro/syntax/definition.lux  |   3 +-
 stdlib/source/documentation/lux/math.lux           |   2 +
 .../source/documentation/lux/math/number/frac.lux  |   2 +-
 .../source/documentation/lux/meta/annotation.lux   |   1 -
 stdlib/source/documentation/lux/type/poly.lux      |   9 +-
 stdlib/source/documentation/lux/type/unit.lux      |  28 +-
 stdlib/source/library/lux.lux                      | 351 +++++----------------
 stdlib/source/library/lux/abstract/apply.lux       |  13 +-
 stdlib/source/library/lux/abstract/codec.lux       |  11 +-
 stdlib/source/library/lux/abstract/comonad.lux     |  19 +-
 stdlib/source/library/lux/abstract/enum.lux        |   9 +-
 stdlib/source/library/lux/abstract/equivalence.lux |   7 +-
 stdlib/source/library/lux/abstract/functor.lux     |  11 +-
 .../library/lux/abstract/functor/contravariant.lux |  11 +-
 stdlib/source/library/lux/abstract/hash.lux        |  11 +-
 stdlib/source/library/lux/abstract/interval.lux    |  15 +-
 stdlib/source/library/lux/abstract/mix.lux         |   9 +-
 stdlib/source/library/lux/abstract/monad.lux       |  19 +-
 .../source/library/lux/abstract/monad/indexed.lux  |  19 +-
 stdlib/source/library/lux/abstract/monoid.lux      |  11 +-
 stdlib/source/library/lux/abstract/order.lux       |  12 +-
 .../source/library/lux/control/concurrency/frp.lux |  11 +-
 .../source/library/lux/data/collection/array.lux   |   2 +-
 stdlib/source/library/lux/data/collection/list.lux |   2 +-
 stdlib/source/library/lux/data/collection/tree.lux |   5 +-
 .../library/lux/data/collection/tree/finger.lux    |  19 +-
 stdlib/source/library/lux/data/format/json.lux     |  17 +-
 stdlib/source/library/lux/data/format/xml.lux      |   9 +-
 stdlib/source/library/lux/documentation.lux        |   4 +-
 stdlib/source/library/lux/ffi.jvm.lux              |   2 +-
 stdlib/source/library/lux/ffi.old.lux              |  15 +-
 stdlib/source/library/lux/math/infix.lux           |  13 +-
 stdlib/source/library/lux/math/number/i64.lux      |  19 +-
 stdlib/source/library/lux/math/number/rev.lux      |   5 +-
 stdlib/source/library/lux/math/random.lux          |   5 +-
 stdlib/source/library/lux/meta/annotation.lux      |  11 +-
 stdlib/source/library/lux/target/jvm/attribute.lux |   9 +-
 stdlib/source/library/lux/target/jvm/class.lux     |  27 +-
 stdlib/source/library/lux/target/jvm/field.lux     |  13 +-
 stdlib/source/library/lux/target/jvm/method.lux    |  13 +-
 .../lux/tool/compiler/language/lux/analysis.lux    |  30 +-
 .../lux/tool/compiler/language/lux/generation.lux  |  29 +-
 .../language/lux/phase/analysis/case/coverage.lux  |  17 +-
 .../language/lux/phase/generation/reference.lux    |  11 +-
 .../lux/tool/compiler/language/lux/synthesis.lux   |  15 +-
 stdlib/source/library/lux/type/implicit.lux        |   9 +-
 stdlib/source/library/lux/type/poly.lux            |  10 +-
 stdlib/source/library/lux/type/unit.lux            |  28 +-
 stdlib/source/library/lux/world/console.lux        |  38 +--
 stdlib/source/library/lux/world/db/jdbc.lux        |  19 +-
 stdlib/source/library/lux/world/file.lux           |  78 ++---
 stdlib/source/library/lux/world/file/watch.lux     |  19 +-
 .../source/library/lux/world/net/http/client.lux   |   9 +-
 stdlib/source/library/lux/world/program.lux        |  23 +-
 stdlib/source/library/lux/world/shell.lux          |  68 ++--
 stdlib/source/poly/lux/data/format/json.lux        |  18 --
 stdlib/source/program/aedifex/repository.lux       |  30 +-
 stdlib/source/test/lux.lux                         |  20 +-
 .../source/test/lux/control/function/contract.lux  |  17 +-
 stdlib/source/test/lux/control/security/policy.lux |  15 +-
 stdlib/source/test/lux/math/number/frac.lux        |  18 +-
 stdlib/source/test/lux/math/number/rev.lux         |   1 +
 stdlib/source/test/lux/meta/annotation.lux         |  25 +-
 stdlib/source/test/lux/type/poly/equivalence.lux   |  11 +-
 stdlib/source/test/lux/type/poly/json.lux          |   9 +-
 72 files changed, 774 insertions(+), 750 deletions(-)
 create mode 100644 documentation/book/the_lux_programming_language/appendix_e.md

diff --git a/documentation/book/the_lux_programming_language/appendix_e.md b/documentation/book/the_lux_programming_language/appendix_e.md
new file mode 100644
index 000000000..b7740abf2
--- /dev/null
+++ b/documentation/book/the_lux_programming_language/appendix_e.md
@@ -0,0 +1,131 @@
+# Appendix E: Lux implementation details
+
+If you read [Chapter 6](chapter_6.md), you encountered Lux's funny way of encoding variants, tuples and functions.
+
+You may be wondering: _how can this possibly have good performance?_
+
+And: _what benefit can this possible have?_
+
+I'll tackle those questions one at a time.
+
+## How can this possibly have good performance?
+
+First, let me explain how things get compiled down in the JVM.
+
+Tuples are compiled as object arrays.
+That means an n-tuple is (_roughly_) an n-array.
+
+	The reason why I say _"roughly"_ will be explained shortly.
+
+Variants, on the other hand, are 3-arrays.
+The first element is the int value of its associated tag.
+The second element is a kind of boolean flag used internally by the Lux run-time infrastructure.
+The third element contains the variant's value.
+
+Finally, functions produce custom classes, and function values are just objects of those classes.
+
+These classes contain everything the function needs:
+
+* its compiled code.
+* its environment/closure.
+* any partially-applied arguments it may have.
+
+How, then, can all of this be made efficient?
+
+Does applying a function `f` to arguments `a`, `b` and `c` create intermediate function values because you can only apply it one argument at a time?
+
+Do tuples consume a lot of memory because everything gets nested?
+
+**Not really.**
+
+With regards to tuples, remember what I said: _an n-tuple is (roughly) an n-array_.
+
+If you write `[#0 12 -34 +56.78 "nine"]`, Lux will actually compile it down as a 5-array, instead of a series of nested 2-arrays.
+
+However, if you have a variable `foo` which contains the last two arguments, and you build your tuple like `[#0 12 -34 foo]`, Lux will compile it as a 4-array, with the last element pointing to the `[+56.78 "nine"]` sub-tuple.
+
+But, as I said in [Chapter 6](chapter_6.md), Lux treats both the same.
+
+_How does that work?_
+
+Well, Lux knows how to work with both flat and nested tuples and it can do so efficiently; so ultimately it doesn't matter.
+It will all be transparent to you.
+
+When it comes to variants, the situation is similar in some ways, but different in others.
+
+Regardless, Lux also knows how to work with the different cases efficiently (which is important for pattern-matching, not just for variant/tuple construction).
+
+Finally, we have to consider functions.
+
+Merging nested functions into a single one that can work like all the nested versions turns out to be pretty easy.
+
+Just allocate enough space for all the (potentially) partially-applied arguments, plus space for the environment/closure.
+
+If you invoke the function with all the arguments, you just run it.
+
+If you invoke it with less than needed, you just use the space you have to store the partial arguments and generate a single new instance with the extra data (instead of generating a new function object for every argument you apply).
+
+And if you're invoking a partially applied function, then you run it with the partial arguments and the new arguments.
+
+Piece of cake.
+
+## What benefit can this possible have?
+
+I already explained in [Chapter 6](chapter_6.md) how the nested nature of Lux functions enables partial application (a useful day-to-day feature that saves you from writing a lot of boilerplate).
+
+What about variants and tuples?
+
+Well, the cool thing is that this makes your data-structures composable, a property that enables you to implement many really cool features.
+
+One that I really like and has turned out to be very useful to me, is that you can use _combinators_ for various data-types that produce single bits of data, and you can fuse them to generate composite data-types, with minimal plumbing.
+
+	You can see _combinators_ as functions that allow you to provide an extra layer of functionality on top of other components, or that allow you to fuse components to get more complex ones.
+
+Here are some examples from the `library/lux/ffi` module, where I have some types and code-parsers for the many macros implemented there:
+
+```
+(type: .public Privacy
+  (Variant
+   #PublicP
+   #PrivateP
+   #ProtectedP
+   #DefaultP))
+
+(def: privacy_modifier^
+  (Parser Privacy)
+  (let [(^open ".") <>.monad]
+    ($_ <>.or
+        (<code>.this! (' #public))
+        (<code>.this! (' #private))
+        (<code>.this! (' #protected))
+        (in []))))
+```
+
+Here, I have a variant type, and I'm creating a code-parser that produces instances of it by simply combining smaller parsers (that just produce unit values, if they succeed) through the `<>.or` combinator.
+
+	These code-parsers and combinators are defined in the `library/lux/control/parser/code` module, and the `library/lux/control/parser` module.
+
+`<>.or` is a combinator for generating variant types.
+
+Its tuple counterpart is called `<>.and` (also, remember that records are tuples, so you'd use the same function).
+
+This wouldn't be possible if variant types weren't nested/composable; forcing me to write custom ad-hoc code instead of taking advantage of common, reusable infrastructure.
+
+Here's an example of `<>.and` in action:
+
+```
+... From library/lux/target/jvm/type
+(type: .public Argument
+  [Text (Type Value)])
+
+... From library/lux/ffi
+(def: (argument^ type_vars)
+  (-> (List (Type Var)) (Parser Argument))
+  (<code>.record (<>.and <code>.local_identifier
+                         (..type^ type_vars))))
+```
+
+The cool thing is that these combinators show up not just in syntax parsers, but also in command-line argument parsing, lexing, concurrency/asynchrony operations, error-handling and in many other contexts.
+
+The nested/composable semantics of Lux entities provide a flexibility that enables powerful features (such as this) to be built on top.
+
diff --git a/lux-mode/lux-mode.el b/lux-mode/lux-mode.el
index 36899dd73..ca19d3758 100644
--- a/lux-mode/lux-mode.el
+++ b/lux-mode/lux-mode.el
@@ -373,6 +373,7 @@ Called by `imenu--generic-function'."
 												 "Rec"
 												 "primitive" "->"
 												 "All" "Ex"
+												 "Interface"
 												 "type"))
 							(type//checking (altRE ":" ":as" ":let" ":~" ":expected" ":of" ":sharing" ":by_example" ":hole"))
 							(type//abstract (altRE "abstract:" ":abstraction" ":representation" ":transmutation" "\\^:representation"))
@@ -399,7 +400,7 @@ Called by `imenu--generic-function'."
 							(remember (altRE "remember" "to_do" "fix_me"))
 							(definition (altRE "\\.module:"
 											   "def:" "type:" "program:"
-											   "interface:" "implementation:"
+											   "implementation:"
 											   "macro:" "syntax:"
 											   "exception:"
 											   "word:"
diff --git a/stdlib/source/documentation/lux.lux b/stdlib/source/documentation/lux.lux
index a046d1fdc..b1d7ae466 100644
--- a/stdlib/source/documentation/lux.lux
+++ b/stdlib/source/documentation/lux.lux
@@ -322,7 +322,22 @@
   ["A name has to be given to the whole type, to use it within its body."
    (Rec Int_List
      (Or Any
-         [Int Int_List]))])
+         [Int Int_List]))]
+  ["Can also be used with type: and labelled-type definitions."
+   (type: Type
+     (Rec @
+       (Variant
+        (#Primitive Text (List @))
+        (#Sum @ @)
+        (#Product @ @)
+        (#Function @ @)
+        (#Parameter Nat)
+        (#Var Nat)
+        (#Ex Nat)
+        (#UnivQ (List @) @)
+        (#ExQ (List @) @)
+        (#Apply @ @)
+        (#Named Name @))))])
 
 (documentation: /.exec
   "Sequential execution of expressions (great for side-effects)."
@@ -491,13 +506,14 @@
      #End
      (#Item a (List a)))])
 
-(documentation: /.interface:
+(documentation: /.Interface
   "Interface definition."
-  [(interface: .public (Order a)
-     (: (Equivalence a)
-        &equivalence)
-     (: (-> a a Bit)
-        <))])
+  [(type: .public (Order a)
+     (Interface
+      (: (Equivalence a)
+         &equivalence)
+      (: (-> a a Bit)
+         <)))])
 
 (.template [<name>]
   [(documentation: <name>
@@ -962,7 +978,7 @@
              ..Variant
              ..Record
              ..type:
-             ..interface:
+             ..Interface
              ..i64
              ..nat
              ..int
diff --git a/stdlib/source/documentation/lux/control/security/policy.lux b/stdlib/source/documentation/lux/control/security/policy.lux
index 9d9cb655d..8f7b100b7 100644
--- a/stdlib/source/documentation/lux/control/security/policy.lux
+++ b/stdlib/source/documentation/lux/control/security/policy.lux
@@ -37,11 +37,12 @@
   [(type: Password
      (Private Text))
 
-   (interface: (Policy %)
-     (: (-> Text (Password %))
-        password)
-     (: (-> (Password %) Text)
-        unsafe))
+   (type: (Policy %)
+     (Interface
+      (: (-> Text (Password %))
+         password)
+      (: (-> (Password %) Text)
+         unsafe)))
 
    (def: (policy _)
      (Ex [%] (-> Any (Policy %)))
diff --git a/stdlib/source/documentation/lux/data/collection/array.lux b/stdlib/source/documentation/lux/data/collection/array.lux
index ce1d461c5..504d646cc 100644
--- a/stdlib/source/documentation/lux/data/collection/array.lux
+++ b/stdlib/source/documentation/lux/data/collection/array.lux
@@ -1,6 +1,6 @@
 (.module:
   [library
-   [lux (#- example list)
+   [lux (#- list)
     ["$" documentation (#+ documentation:)]
     [control
      ["<>" parser
diff --git a/stdlib/source/documentation/lux/data/collection/list.lux b/stdlib/source/documentation/lux/data/collection/list.lux
index 87cf01da1..f5dda38bc 100644
--- a/stdlib/source/documentation/lux/data/collection/list.lux
+++ b/stdlib/source/documentation/lux/data/collection/list.lux
@@ -1,6 +1,6 @@
 (.module:
   [library
-   [lux (#- example)
+   [lux #*
     ["$" documentation (#+ documentation:)]
     [control
      ["<>" parser
diff --git a/stdlib/source/documentation/lux/ffi.lux b/stdlib/source/documentation/lux/ffi.lux
index 89829884b..a781e10ff 100644
--- a/stdlib/source/documentation/lux/ffi.lux
+++ b/stdlib/source/documentation/lux/ffi.lux
@@ -1,6 +1,6 @@
 (.module:
   [library
-   [lux (#- int char interface: type :as)
+   [lux (#- int char type :as)
     ["$" documentation (#+ documentation:)]
     [data
      ["." text (#+ \n)
diff --git a/stdlib/source/documentation/lux/macro/syntax/definition.lux b/stdlib/source/documentation/lux/macro/syntax/definition.lux
index 21befadc2..3a97fc37d 100644
--- a/stdlib/source/documentation/lux/macro/syntax/definition.lux
+++ b/stdlib/source/documentation/lux/macro/syntax/definition.lux
@@ -29,5 +29,6 @@
              ..parser
              ..typed
              ($.default /.equivalence)
-             ($.default /.lacks_type)]
+             ($.default /.lacks_type)
+             ($.default /.format)]
             []))
diff --git a/stdlib/source/documentation/lux/math.lux b/stdlib/source/documentation/lux/math.lux
index 57b56dec2..a8249a394 100644
--- a/stdlib/source/documentation/lux/math.lux
+++ b/stdlib/source/documentation/lux/math.lux
@@ -64,7 +64,9 @@
              ($.default /.factorial)
              ($.default /.hypotenuse)
              ($.default /.sinh)
+             ($.default /.csch)
              ($.default /.cosh)
+             ($.default /.sech)
              ($.default /.tanh)
              ($.default /.coth)
              ($.default /.asinh)
diff --git a/stdlib/source/documentation/lux/math/number/frac.lux b/stdlib/source/documentation/lux/math/number/frac.lux
index a161327fa..e78852864 100644
--- a/stdlib/source/documentation/lux/math/number/frac.lux
+++ b/stdlib/source/documentation/lux/math/number/frac.lux
@@ -113,7 +113,7 @@
              ($.default /.smallest)
              ($.default /.biggest)
              ($.default /.addition)
-             ($.default /.addition)
+             ($.default /.multiplication)
              ($.default /.minimum)
              ($.default /.maximum)
              ($.default /.number?)
diff --git a/stdlib/source/documentation/lux/meta/annotation.lux b/stdlib/source/documentation/lux/meta/annotation.lux
index ba739e129..c46961d3a 100644
--- a/stdlib/source/documentation/lux/meta/annotation.lux
+++ b/stdlib/source/documentation/lux/meta/annotation.lux
@@ -49,7 +49,6 @@
              ($.default /.documentation)
              ($.default /.flagged?)
              ($.default /.implementation?)
-             ($.default /.recursive_type?)
              ($.default /.function_arguments)
              ($.default /.type_arguments)]
             []))
diff --git a/stdlib/source/documentation/lux/type/poly.lux b/stdlib/source/documentation/lux/type/poly.lux
index 47ea08837..bbdbfd0d0 100644
--- a/stdlib/source/documentation/lux/type/poly.lux
+++ b/stdlib/source/documentation/lux/type/poly.lux
@@ -25,10 +25,11 @@
       (#Text Text)
       (#Frac Frac)))
 
-   (type: #rec Recursive
-     (.Variant
-      (#Number Frac)
-      (#Addition Frac Recursive)))
+   (type: Recursive
+     (Rec Recursive
+       (.Variant
+        (#Number Frac)
+        (#Addition Frac Recursive))))
 
    (type: Record
      (.Record
diff --git a/stdlib/source/documentation/lux/type/unit.lux b/stdlib/source/documentation/lux/type/unit.lux
index b33a797c6..08cd1a6d4 100644
--- a/stdlib/source/documentation/lux/type/unit.lux
+++ b/stdlib/source/documentation/lux/type/unit.lux
@@ -57,7 +57,7 @@
   [(`` (documentation: <scale>
          (let [numerator (value@ [#/.ratio #ratio.numerator] <scale>)
                denominator (value@ [#/.ratio #ratio.denominator] <scale>)]
-           (format "'" (~~ (template.text [<type>])) "' scale from " (%.nat numerator) " to " (%.nat denominator) "."))))]
+           (format "The '" (~~ (template.text [<scale>])) "' scale, from " (%.nat numerator) " to " (%.nat denominator) "."))))]
 
   [/.Kilo /.kilo]
   [/.Mega /.mega]
@@ -68,14 +68,14 @@
   [/.Nano /.nano]
   )
 
-(template [<type>]
-  [(`` (documentation: <type>
-         (format "'" (~~ (template.text [<type>])) "' unit of meaurement.")))]
+(template [<unit>]
+  [(`` (documentation: <unit>
+         (format "The '" (~~ (template.text [<unit>])) "' unit of meaurement.")))]
 
-  [/.Gram]
-  [/.Meter]
-  [/.Litre]
-  [/.Second]
+  [/.gram]
+  [/.meter]
+  [/.litre]
+  [/.second]
   )
 
 (.def: .public documentation
@@ -99,10 +99,14 @@
              ..milli
              ..micro
              ..nano
-             ..Gram
-             ..Meter
-             ..Litre
-             ..Second
+             ..gram
+             ..meter
+             ..litre
+             ..second
+             ($.default /.Gram)
+             ($.default /.Meter)
+             ($.default /.Litre)
+             ($.default /.Second)
              ($.default /.pure)
              ($.default /.number)
              ($.default /.equivalence)
diff --git a/stdlib/source/library/lux.lux b/stdlib/source/library/lux.lux
index 389635abc..c87b674f0 100644
--- a/stdlib/source/library/lux.lux
+++ b/stdlib/source/library/lux.lux
@@ -138,19 +138,20 @@
  ["None" "Some"]
  #1)
 
-... (type: .public #rec Type
-...   (#Primitive Text (List Type))
-...   (#Sum Type Type)
-...   (#Product Type Type)
-...   (#Function Type Type)
-...   (#Parameter Nat)
-...   (#Var Nat)
-...   (#Ex Nat)
-...   (#UnivQ (List Type) Type)
-...   (#ExQ (List Type) Type)
-...   (#Apply Type Type)
-...   (#Named Name Type)
-...   )
+... (type: .public Type
+...   (Rec Type
+...     (Variant
+...      (#Primitive Text (List Type))
+...      (#Sum Type Type)
+...      (#Product Type Type)
+...      (#Function Type Type)
+...      (#Parameter Nat)
+...      (#Var Nat)
+...      (#Ex Nat)
+...      (#UnivQ (List Type) Type)
+...      (#ExQ (List Type) Type)
+...      (#Apply Type Type)
+...      (#Named Name Type))))
 ("lux def type tagged" Type
  (9 #1 ["library/lux" "Type"]
     ({Type
@@ -194,9 +195,7 @@
        ("lux type check type" (9 #0 Type List)))}
      ("lux type check type" (9 #0 (4 #0 1) (4 #0 0)))))
  [dummy_location
-  (9 #1 (#Item [[dummy_location (7 #0 ["library/lux" "type_rec?"])]
-                [dummy_location (0 #0 #1)]]
-               #End))]
+  (9 #1 #End)]
  ["Primitive" "Sum" "Product" "Function" "Parameter" "Var" "Ex" "UnivQ" "ExQ" "Apply" "Named"]
  #1)
 
@@ -1399,11 +1398,12 @@
            (failure "Wrong syntax for $_")}
           tokens))
 
-... (interface: (Monad m)
-...   (: (All [a] (-> a (m a)))
-...      in)
-...   (: (All [a b] (-> (-> a (m b)) (m a) (m b)))
-...      then))
+... (type: (Monad m)
+...   (Interface
+...    (: (All [a] (-> a (m a)))
+...       in)
+...    (: (All [a b] (-> (-> a (m b)) (m a) (m b)))
+...       then)))
 ("lux def type tagged" Monad
  (#Named ["library/lux" "Monad"]
          (All [m]
@@ -2404,17 +2404,6 @@
                    (local_identifier$ ($_ text\composite "__gensym__" prefix (nat\encoded seed))))}
           state))
 
-(macro:' .public (Rec tokens)
-         ({(#Item [_ (#Identifier "" name)] (#Item body #End))
-           (let' [body' (|> body
-                            nested_quantification
-                            (with_replacements (list [name (` (#.Apply (~ (type_parameter 1)) (~ (type_parameter 0))))])))]
-                 (in_meta (list (` (#.Apply .Nothing (#.UnivQ #.End (~ body')))))))
-           
-           _
-           (failure "Wrong syntax for Rec")}
-          tokens))
-
 (macro:' .public (exec tokens)
          (list)
          ({(#Item value actions)
@@ -3367,7 +3356,7 @@
     (#Some [tokens' [slot type]])
 
     _
-    #.None))
+    #None))
 
 (def: un_paired
   (-> (List [Code Code]) (List Code))
@@ -3395,21 +3384,11 @@
     _
     (failure "Wrong syntax for Record")))
 
-(def: (recP tokens)
-  (-> (List Code) [(List Code) Bit])
-  (case tokens
-    (^ (list& [_ (#Tag ["" "rec"])] tokens'))
-    [tokens' #1]
-
-    _
-    [tokens #0]))
-
 (def: (typeP tokens)
-  (-> (List Code) (Maybe [Code Bit Text (List Text) (List [Code Code]) Code]))
+  (-> (List Code) (Maybe [Code Text (List Text) (List [Code Code]) Code]))
   (|> (do maybe_monad
         [% (anyP tokens)
          .let' [[tokens export_policy] %]
-         .let' [[tokens rec?] (recP tokens)]
          % (local_declarationP tokens)
          .let' [[tokens [name parameters]] %]
          % (annotationsP tokens)
@@ -3417,42 +3396,35 @@
          % (anyP tokens)
          .let' [[tokens definition] %]
          _ (endP tokens)]
-        (in [export_policy rec? name parameters annotations definition]))
-      ... (^ (list _export_policy _rec _declaration _annotations _body))
+        (in [export_policy name parameters annotations definition]))
       ... (^ (list _export_policy _declaration _annotations _body))
       (maybe\else' (do maybe_monad
-                     [.let' [[tokens rec?] (recP tokens)]
-                      % (local_declarationP tokens)
+                     [% (local_declarationP tokens)
                       .let' [[tokens [name parameters]] %]
                       % (annotationsP tokens)
                       .let' [[tokens annotations] %]
                       % (anyP tokens)
                       .let' [[tokens definition] %]
                       _ (endP tokens)]
-                     (in [(` ..private) rec? name parameters annotations definition])))
-      ... (^ (list _rec _declaration _annotations _body))
+                     (in [(` ..private) name parameters annotations definition])))
       ... (^ (list _declaration _annotations _body))
       (maybe\else' (do maybe_monad
-                     [.let' [[tokens rec?] (recP tokens)]
-                      % (local_declarationP tokens)
+                     [% (local_declarationP tokens)
                       .let' [[tokens [name parameters]] %]
                       % (anyP tokens)
                       .let' [[tokens definition] %]
                       _ (endP tokens)]
-                     (in [(` ..private) rec? name parameters #End definition])))
-      ... (^ (list _rec _declaration _body))
+                     (in [(` ..private) name parameters #End definition])))
       ... (^ (list _declaration _body))
       (maybe\else' (do maybe_monad
                      [% (anyP tokens)
                       .let' [[tokens export_policy] %]
-                      .let' [[tokens rec?] (recP tokens)]
                       % (local_declarationP tokens)
                       .let' [[tokens [name parameters]] %]
                       % (anyP tokens)
                       .let' [[tokens definition] %]
                       _ (endP tokens)]
-                     (in [export_policy rec? name parameters #End definition])))
-      ... (^ (list _export_policy _rec _declaration _body))
+                     (in [export_policy name parameters #End definition])))
       ... (^ (list _export_policy _declaration _body))
       ))
 
@@ -3491,32 +3463,20 @@
 
 (macro: .public (type: tokens)
   (case (typeP tokens)
-    (#Some [export_policy rec? name args meta type_codes])
+    (#Some [export_policy name args meta type_codes])
     (do meta_monad
       [type+tags?? (..type_declaration type_codes)
        module_name current_module_name
        .let' [type_name (local_identifier$ name)
               [type tags??] type+tags??
               type' (: (Maybe Code)
-                       (if rec?
-                         (if (empty? args)
-                           (let [g!param (local_identifier$ "")
-                                 prime_name (local_identifier$ name)
-                                 type+ (with_replacements (list [name (` ((~ prime_name) .Nothing))])
-                                         type)]
-                             (#Some (` ((All (~ prime_name) [(~ g!param)] (~ type+))
-                                        .Nothing))))
-                           #None)
-                         (case args
-                           #End
-                           (#Some type)
+                       (case args
+                         #End
+                         (#Some type)
 
-                           _
-                           (#Some (` (.All (~ type_name) [(~+ (list\each local_identifier$ args))] (~ type)))))))
-              total_meta (let [meta (definition_annotations meta)
-                               meta (if rec?
-                                      (` (#.Item (~ (flag_meta "type_rec?")) (~ meta)))
-                                      meta)]
+                         _
+                         (#Some (` (.All (~ type_name) [(~+ (list\each local_identifier$ args))] (~ type))))))
+              total_meta (let [meta (definition_annotations meta)]
                            (` [(~ location_code)
                                (#.Record (~ meta))]))]]
       (case type'
@@ -3545,64 +3505,6 @@
     #None
     (failure "Wrong syntax for type:")))
 
-(def:' .private (interfaceP tokens)
-       (-> (List Code) (Maybe [Code Text (List Text) (List [Code Code]) (List Code)]))
-       (|> (do maybe_monad
-             [% (declarationP tokens)
-              .let' [[tokens [export_policy name parameters]] %]
-              % (annotationsP tokens)
-              .let' [[tokens annotations] %]]
-             (in [export_policy name parameters annotations tokens]))
-           ... (^ (list _export_policy _declaration _annotations _body))
-           ... (^ (list _declaration _annotations _body))
-           (maybe\else' (do maybe_monad
-                          [% (local_declarationP tokens)
-                           .let' [[tokens [name parameters]] %]]
-                          (in [(` ..private) name parameters #End tokens])))
-           ... (^ (list _declaration _body))
-           (maybe\else' (do maybe_monad
-                          [% (declarationP tokens)
-                           .let' [[tokens [export_policy name parameters]] %]]
-                          (in [export_policy name parameters #End tokens])))
-           ... (^ (list _export_policy _declaration _body))
-           ))
-
-(macro: .public (interface: tokens)
-  (case (interfaceP tokens)
-    (#Some [export_policy name args annotations methods])
-    (do meta_monad
-      [methods' (monad\each meta_monad expansion methods)
-       members (: (Meta (List [Text Code]))
-                  (monad\each meta_monad
-                              (: (-> Code (Meta [Text Code]))
-                                 (function (_ token)
-                                   (case token
-                                     (^ [_ (#Form (list [_ (#Text "lux type check")] type [_ (#Identifier ["" name])]))])
-                                     (in [name type])
-
-                                     _
-                                     (failure "Interfaces require typed members!"))))
-                              (list\conjoint methods')))
-       .let [def_name (local_identifier$ name)
-             interface_type (` (..Record
-                                (~ (record$ (list\each (: (-> [Text Code] [Code Code])
-                                                          (function (_ [module_name m_type])
-                                                            [(local_tag$ module_name) m_type]))
-                                                       members)))))
-             usage (case args
-                     #End
-                     def_name
-
-                     _
-                     (` ((~ def_name) (~+ (list\each local_identifier$ args)))))]]
-      (in_meta (list (` (..type: (~ export_policy)
-                          (~ usage)
-                          (~ (record$ annotations))
-                          (~ interface_type))))))
-
-    #None
-    (failure "Wrong syntax for interface:")))
-
 (template [<name> <to>]
   [(def: .public (<name> value)
      (-> (I64 Any) <to>)
@@ -3926,7 +3828,7 @@
                                                             code\encoded))))
     ))
 
-(def: (only p xs)
+(def: (list\only p xs)
   (All [a] (-> (-> a Bit) (List a) (List a)))
   (case xs
     #End
@@ -3934,8 +3836,8 @@
 
     (#Item x xs')
     (if (p x)
-      (#Item x (only p xs'))
-      (only p xs'))))
+      (#Item x (list\only p xs'))
+      (list\only p xs'))))
 
 (def: (is_member? cases name)
   (-> (List Text) Text Bit)
@@ -4377,7 +4279,7 @@
              (do meta_monad
                [*defs (exported_definitions module_name)
                 _ (test_referrals module_name *defs _defs)]
-               (in (..only (|>> (is_member? _defs) not) *defs)))
+               (in (..list\only (|>> (is_member? _defs) not) *defs)))
 
              #Ignore
              (in (list))
@@ -4643,47 +4545,6 @@
     _
     (failure "Wrong syntax for ^template")))
 
-(def: (baseline_column code)
-  (-> Code Nat)
-  (case code
-    (^template [<tag>]
-      [[[_ _ column] (<tag> _)]
-       column])
-    ([#Bit]
-     [#Nat]
-     [#Int]
-     [#Rev]
-     [#Frac]
-     [#Text]
-     [#Identifier]
-     [#Tag])
-
-    (^template [<tag>]
-      [[[_ _ column] (<tag> parts)]
-       (list\mix n/min column (list\each baseline_column parts))])
-    ([#Form]
-     [#Tuple])
-
-    [[_ _ column] (#Record pairs)]
-    (list\mix n/min column
-              (list\composite (list\each (|>> product\left baseline_column) pairs)
-                              (list\each (|>> product\right baseline_column) pairs)))
-    ))
-
-(type: Documentation_Fragment
-  (Variant
-   (#Documentation_Comment Text)
-   (#Documentation_Example Code)))
-
-(def: (documentation_fragment code)
-  (-> Code Documentation_Fragment)
-  (case code
-    [_ (#Text comment)]
-    (#Documentation_Comment comment)
-
-    _
-    (#Documentation_Example code)))
-
 (template [<name> <extension>]
   [(def: .public <name>
      (All [s] (-> (I64 s) (I64 s)))
@@ -4693,92 +4554,6 @@
   [-- "lux i64 -"]
   )
 
-(def: tag\encoded
-  (-> Name Text)
-  (|>> name\encoded
-       (text\composite "#")))
-
-(def: (repeated n x)
-  (All [a] (-> Int a (List a)))
-  (if ("lux i64 <" n +0)
-    (#Item x (repeated ("lux i64 +" -1 n) x))
-    #End))
-
-(def: (location_padding baseline [_ old_line old_column] [_ new_line new_column])
-  (-> Nat Location Location Text)
-  (if ("lux i64 =" old_line new_line)
-    (text\interposed "" (repeated (.int ("lux i64 -" old_column new_column)) " "))
-    (let [extra_lines (text\interposed "" (repeated (.int ("lux i64 -" old_line new_line)) ..\n))
-          space_padding (text\interposed "" (repeated (.int ("lux i64 -" baseline new_column)) " "))]
-      (text\composite extra_lines space_padding))))
-
-(def: (text\size x)
-  (-> Text Nat)
-  ("lux text size" x))
-
-(def: (updated_location [file line column] code_text)
-  (-> Location Text Location)
-  [file line ("lux i64 +" column (text\size code_text))])
-
-(def: (example_documentation prev_location baseline example)
-  (-> Location Nat Code [Location Text])
-  (case example
-    (^template [<tag> <encoded>]
-      [[new_location (<tag> value)]
-       (let [as_text (<encoded> value)]
-         [(updated_location new_location as_text)
-          (text\composite (location_padding baseline prev_location new_location)
-                          as_text)])])
-    ([#Bit        bit\encoded]
-     [#Nat        nat\encoded]
-     [#Int        int\encoded]
-     [#Frac       frac\encoded]
-     [#Text       text\encoded]
-     [#Identifier name\encoded]
-     [#Tag        tag\encoded])
-
-    (^template [<tag> <open> <close> <prep>]
-      [[group_location (<tag> parts)]
-       (let [[group_location' parts_text] (list\mix (function (_ part [last_location text_accum])
-                                                      (let [[part_location part_text] (example_documentation last_location baseline part)]
-                                                        [part_location (text\composite text_accum part_text)]))
-                                                    [(revised@ #column ++ group_location) ""]
-                                                    (<prep> parts))]
-         [(revised@ #column ++ group_location')
-          ($_ text\composite (location_padding baseline prev_location group_location)
-              <open>
-              parts_text
-              <close>)])])
-    ([#Form   "(" ")" |>]
-     [#Tuple  "[" "]" |>]
-     [#Record "{" "}" ..un_paired])
-
-    [new_location (#Rev value)]
-    ("lux io error" "@example_documentation Undefined behavior.")
-    ))
-
-(def: (fragment_documentation fragment)
-  (-> Documentation_Fragment Text)
-  (case fragment
-    (#Documentation_Comment comment)
-    (|> comment
-        (text\all_split_by ..\n)
-        (list\each (function (_ line) ($_ text\composite "... " line ..\n)))
-        (text\interposed ""))
-
-    (#Documentation_Example example)
-    (let [baseline (baseline_column example)
-          [location _] example
-          [_ text] (..example_documentation (with@ #column baseline location) baseline example)]
-      (text\composite text "\n\n"))))
-
-(macro: .public (example tokens)
-  (in_meta (list (` [(~ location_code)
-                     (#.Text (~ (|> tokens
-                                    (list\each (|>> ..documentation_fragment ..fragment_documentation))
-                                    (text\interposed "")
-                                    text$)))]))))
-
 (def: (interleaved xs ys)
   (All [a] (-> (List a) (List a) (List a)))
   (case xs
@@ -5557,3 +5332,49 @@
 
     _
     (..failure (..wrong_syntax_error (name_of ..try)))))
+
+(def: (methodP tokens)
+  (-> (List Code) (Maybe [(List Code) [Text Code]]))
+  (case tokens
+    (^ (list& [_ (#Form (list [_ (#Text "lux type check")] type [_ (#Identifier ["" name])]))]
+              tokens'))
+    (#Some [tokens' [name type]])
+
+    _
+    #None))
+
+(macro: .public (Interface tokens)
+  (do meta_monad
+    [methods' (monad\each meta_monad expansion tokens)]
+    (case (everyP methodP (list\conjoint methods'))
+      (#Some methods)
+      (in (list (` (..Tuple (~+ (list\each product\right methods))))
+                (tuple$ (list\each (|>> product\left text$) methods))))
+      
+      #None
+      (failure "Wrong syntax for Interface"))))
+
+(def: (recursive_type name body)
+  (-> Text Code Code)
+  (let [body' (|> body
+                  nested_quantification
+                  (with_replacements (list [name (` (#.Apply .Nothing (~ (type_parameter 0))))])))]
+    (` (#.Apply .Nothing (#.UnivQ #.End (~ body'))))))
+
+(macro: .public (Rec tokens)
+  (case tokens
+    (^ (list [_ (#Identifier "" name)] body))
+    (do meta_monad
+      [body' (expansion body)]
+      (case body'
+        (^ (list body' labels))
+        (in (list (..recursive_type name body') labels))
+
+        (^ (list body'))
+        (in (list (..recursive_type name body')))
+
+        _
+        (failure "Wrong syntax for Rec")))
+
+    _
+    (failure "Wrong syntax for Rec")))
diff --git a/stdlib/source/library/lux/abstract/apply.lux b/stdlib/source/library/lux/abstract/apply.lux
index 1831db134..c47951e89 100644
--- a/stdlib/source/library/lux/abstract/apply.lux
+++ b/stdlib/source/library/lux/abstract/apply.lux
@@ -6,12 +6,13 @@
    [monad (#+ Monad)]
    ["." functor (#+ Functor)]])
 
-(interface: .public (Apply f)
-  (: (Functor f)
-     &functor)
-  (: (All [a b]
-       (-> (f a) (f (-> a b)) (f b)))
-     on))
+(type: .public (Apply f)
+  (Interface
+   (: (Functor f)
+      &functor)
+   (: (All [a b]
+        (-> (f a) (f (-> a b)) (f b)))
+      on)))
 
 (implementation: .public (composite f_monad f_apply g_apply)
   (All [F G]
diff --git a/stdlib/source/library/lux/abstract/codec.lux b/stdlib/source/library/lux/abstract/codec.lux
index 82b4ad194..0a1f8b2ba 100644
--- a/stdlib/source/library/lux/abstract/codec.lux
+++ b/stdlib/source/library/lux/abstract/codec.lux
@@ -7,11 +7,12 @@
    [monad (#+ do)]
    ["." functor]])
 
-(interface: .public (Codec m a)
-  (: (-> a m)
-     encoded)
-  (: (-> m (Try a))
-     decoded))
+(type: .public (Codec m a)
+  (Interface
+   (: (-> a m)
+      encoded)
+   (: (-> m (Try a))
+      decoded)))
 
 (implementation: .public (composite cb_codec ba_codec)
   (All [a b c]
diff --git a/stdlib/source/library/lux/abstract/comonad.lux b/stdlib/source/library/lux/abstract/comonad.lux
index 6de1b97d0..3e0422762 100644
--- a/stdlib/source/library/lux/abstract/comonad.lux
+++ b/stdlib/source/library/lux/abstract/comonad.lux
@@ -12,15 +12,16 @@
   [//
    [functor (#+ Functor)]])
 
-(interface: .public (CoMonad w)
-  (: (Functor w)
-     &functor)
-  (: (All [a]
-       (-> (w a) a))
-     out)
-  (: (All [a]
-       (-> (w a) (w (w a))))
-     disjoint))
+(type: .public (CoMonad w)
+  (Interface
+   (: (Functor w)
+      &functor)
+   (: (All [a]
+        (-> (w a) a))
+      out)
+   (: (All [a]
+        (-> (w a) (w (w a))))
+      disjoint)))
 
 (macro: .public (be tokens state)
   (case (: (Maybe [(Maybe Text) Code (List Code) Code])
diff --git a/stdlib/source/library/lux/abstract/enum.lux b/stdlib/source/library/lux/abstract/enum.lux
index 5a43d91cd..fd987f070 100644
--- a/stdlib/source/library/lux/abstract/enum.lux
+++ b/stdlib/source/library/lux/abstract/enum.lux
@@ -4,10 +4,11 @@
   [//
    ["." order (#+ Order)]])
 
-(interface: .public (Enum e)
-  (: (Order e) &order)
-  (: (-> e e) succ)
-  (: (-> e e) pred))
+(type: .public (Enum e)
+  (Interface
+   (: (Order e) &order)
+   (: (-> e e) succ)
+   (: (-> e e) pred)))
 
 (def: .public (range enum from to)
   (All [a] (-> (Enum a) a a (List a)))
diff --git a/stdlib/source/library/lux/abstract/equivalence.lux b/stdlib/source/library/lux/abstract/equivalence.lux
index 69f90bb06..bfbe87a2d 100644
--- a/stdlib/source/library/lux/abstract/equivalence.lux
+++ b/stdlib/source/library/lux/abstract/equivalence.lux
@@ -5,9 +5,10 @@
    [functor
     ["." contravariant]]])
 
-(interface: .public (Equivalence a)
-  (: (-> a a Bit)
-     =))
+(type: .public (Equivalence a)
+  (Interface
+   (: (-> a a Bit)
+      =)))
 
 (def: .public (rec sub)
   (All [a] (-> (-> (Equivalence a) (Equivalence a)) (Equivalence a)))
diff --git a/stdlib/source/library/lux/abstract/functor.lux b/stdlib/source/library/lux/abstract/functor.lux
index 28e90dbb0..78b647a59 100644
--- a/stdlib/source/library/lux/abstract/functor.lux
+++ b/stdlib/source/library/lux/abstract/functor.lux
@@ -2,11 +2,12 @@
   [library
    [lux (#- Or And)]])
 
-(interface: .public (Functor f)
-  (: (All [a b]
-       (-> (-> a b)
-           (-> (f a) (f b))))
-     each))
+(type: .public (Functor f)
+  (Interface
+   (: (All [a b]
+        (-> (-> a b)
+            (-> (f a) (f b))))
+      each)))
 
 (type: .public (Fix f)
   (f (Fix f)))
diff --git a/stdlib/source/library/lux/abstract/functor/contravariant.lux b/stdlib/source/library/lux/abstract/functor/contravariant.lux
index ac35b9360..374cb9a80 100644
--- a/stdlib/source/library/lux/abstract/functor/contravariant.lux
+++ b/stdlib/source/library/lux/abstract/functor/contravariant.lux
@@ -2,8 +2,9 @@
   [library
    [lux #*]])
 
-(interface: .public (Functor f)
-  (: (All [a b]
-       (-> (-> b a)
-           (-> (f a) (f b))))
-     each))
+(type: .public (Functor f)
+  (Interface
+   (: (All [a b]
+        (-> (-> b a)
+            (-> (f a) (f b))))
+      each)))
diff --git a/stdlib/source/library/lux/abstract/hash.lux b/stdlib/source/library/lux/abstract/hash.lux
index 48816744a..9b8a599ec 100644
--- a/stdlib/source/library/lux/abstract/hash.lux
+++ b/stdlib/source/library/lux/abstract/hash.lux
@@ -6,11 +6,12 @@
    [functor
     ["." contravariant]]])
 
-(interface: .public (Hash a)
-  (: (Equivalence a)
-     &equivalence)
-  (: (-> a Nat)
-     hash))
+(type: .public (Hash a)
+  (Interface
+   (: (Equivalence a)
+      &equivalence)
+   (: (-> a Nat)
+      hash)))
 
 (implementation: .public functor
   (contravariant.Functor Hash)
diff --git a/stdlib/source/library/lux/abstract/interval.lux b/stdlib/source/library/lux/abstract/interval.lux
index 4c6060d4d..d97e9fcbb 100644
--- a/stdlib/source/library/lux/abstract/interval.lux
+++ b/stdlib/source/library/lux/abstract/interval.lux
@@ -7,15 +7,16 @@
    ["." order]
    [enum (#+ Enum)]])
 
-(interface: .public (Interval a)
-  (: (Enum a)
-     &enum)
+(type: .public (Interval a)
+  (Interface
+   (: (Enum a)
+      &enum)
 
-  (: a
-     bottom)
+   (: a
+      bottom)
 
-  (: a
-     top))
+   (: a
+      top)))
 
 (def: .public (between enum bottom top)
   (All [a] (-> (Enum a) a a (Interval a)))
diff --git a/stdlib/source/library/lux/abstract/mix.lux b/stdlib/source/library/lux/abstract/mix.lux
index 07bddfec0..9733066df 100644
--- a/stdlib/source/library/lux/abstract/mix.lux
+++ b/stdlib/source/library/lux/abstract/mix.lux
@@ -4,10 +4,11 @@
   [//
    [monoid (#+ Monoid)]])
 
-(interface: .public (Mix F)
-  (: (All [a b]
-       (-> (-> b a a) a (F b) a))
-     mix))
+(type: .public (Mix F)
+  (Interface
+   (: (All [a b]
+        (-> (-> b a a) a (F b) a))
+      mix)))
 
 (def: .public (with_monoid monoid mix value)
   (All [F a]
diff --git a/stdlib/source/library/lux/abstract/monad.lux b/stdlib/source/library/lux/abstract/monad.lux
index 4a1abdc82..ab03e9a18 100644
--- a/stdlib/source/library/lux/abstract/monad.lux
+++ b/stdlib/source/library/lux/abstract/monad.lux
@@ -43,15 +43,16 @@
     _
     #.End))
 
-(interface: .public (Monad m)
-  (: (Functor m)
-     &functor)
-  (: (All [a]
-       (-> a (m a)))
-     in)
-  (: (All [a]
-       (-> (m (m a)) (m a)))
-     conjoint))
+(type: .public (Monad m)
+  (Interface
+   (: (Functor m)
+      &functor)
+   (: (All [a]
+        (-> a (m a)))
+      in)
+   (: (All [a]
+        (-> (m (m a)) (m a)))
+      conjoint)))
 
 (macro: .public (do tokens state)
   (case (: (Maybe [(Maybe Text) Code (List Code) Code])
diff --git a/stdlib/source/library/lux/abstract/monad/indexed.lux b/stdlib/source/library/lux/abstract/monad/indexed.lux
index ad06165f3..98acab0e1 100644
--- a/stdlib/source/library/lux/abstract/monad/indexed.lux
+++ b/stdlib/source/library/lux/abstract/monad/indexed.lux
@@ -12,16 +12,17 @@
      ["." code]]]]
   ["." //])
 
-(interface: .public (IxMonad m)
-  (: (All [p a]
-       (-> a (m p p a)))
-     in)
+(type: .public (IxMonad m)
+  (Interface
+   (: (All [p a]
+        (-> a (m p p a)))
+      in)
 
-  (: (All [ii it io vi vo]
-       (-> (-> vi (m it io vo))
-           (m ii it vi)
-           (m ii io vo)))
-     then))
+   (: (All [ii it io vi vo]
+        (-> (-> vi (m it io vo))
+            (m ii it vi)
+            (m ii io vo)))
+      then)))
 
 (type: Binding
   [Code Code])
diff --git a/stdlib/source/library/lux/abstract/monoid.lux b/stdlib/source/library/lux/abstract/monoid.lux
index 6e8aff164..3012bd4bd 100644
--- a/stdlib/source/library/lux/abstract/monoid.lux
+++ b/stdlib/source/library/lux/abstract/monoid.lux
@@ -2,11 +2,12 @@
   [library
    [lux (#- and)]])
 
-(interface: .public (Monoid a)
-  (: a
-     identity)
-  (: (-> a a a)
-     composite))
+(type: .public (Monoid a)
+  (Interface
+   (: a
+      identity)
+   (: (-> a a a)
+      composite)))
 
 (def: .public (and left right)
   (All [l r] (-> (Monoid l) (Monoid r) (Monoid [l r])))
diff --git a/stdlib/source/library/lux/abstract/order.lux b/stdlib/source/library/lux/abstract/order.lux
index 7f055199a..6da64656d 100644
--- a/stdlib/source/library/lux/abstract/order.lux
+++ b/stdlib/source/library/lux/abstract/order.lux
@@ -8,13 +8,13 @@
    [functor
     ["." contravariant]]])
 
-(interface: .public (Order a)
-  (: (Equivalence a)
-     &equivalence)
+(type: .public (Order a)
+  (Interface
+   (: (Equivalence a)
+      &equivalence)
 
-  (: (-> a a Bit)
-     <)
-  )
+   (: (-> a a Bit)
+      <)))
 
 (type: .public (Comparison a)
   (-> (Order a) a a Bit))
diff --git a/stdlib/source/library/lux/control/concurrency/frp.lux b/stdlib/source/library/lux/control/concurrency/frp.lux
index df0ef8160..c31908da3 100644
--- a/stdlib/source/library/lux/control/concurrency/frp.lux
+++ b/stdlib/source/library/lux/control/concurrency/frp.lux
@@ -22,11 +22,12 @@
 
 (exception: .public channel_is_already_closed)
 
-(interface: .public (Sink a)
-  (: (IO (Try Any))
-     close)
-  (: (-> a (IO (Try Any)))
-     feed))
+(type: .public (Sink a)
+  (Interface
+   (: (IO (Try Any))
+      close)
+   (: (-> a (IO (Try Any)))
+      feed)))
 
 (def: (sink resolve)
   (All [a]
diff --git a/stdlib/source/library/lux/data/collection/array.lux b/stdlib/source/library/lux/data/collection/array.lux
index 1549bae80..73e8a209b 100644
--- a/stdlib/source/library/lux/data/collection/array.lux
+++ b/stdlib/source/library/lux/data/collection/array.lux
@@ -1,6 +1,6 @@
 (.module:
   [library
-   [lux (#- list example)
+   [lux (#- list)
     ["@" target]
     [abstract
      [monoid (#+ Monoid)]
diff --git a/stdlib/source/library/lux/data/collection/list.lux b/stdlib/source/library/lux/data/collection/list.lux
index b40e94669..9ea9c3132 100644
--- a/stdlib/source/library/lux/data/collection/list.lux
+++ b/stdlib/source/library/lux/data/collection/list.lux
@@ -1,6 +1,6 @@
 (.module:
   [library
-   [lux (#- example)
+   [lux #*
     ["@" target]
     [abstract
      [monoid (#+ Monoid)]
diff --git a/stdlib/source/library/lux/data/collection/tree.lux b/stdlib/source/library/lux/data/collection/tree.lux
index d3222b959..47a4c8957 100644
--- a/stdlib/source/library/lux/data/collection/tree.lux
+++ b/stdlib/source/library/lux/data/collection/tree.lux
@@ -39,8 +39,9 @@
   {#value value
    #children children})
 
-(type: #rec Tree_Code
-  [Code (List Tree_Code)])
+(type: Tree_Code
+  (Rec Tree_Code
+    [Code (List Tree_Code)]))
 
 (def: tree^
   (Parser Tree_Code)
diff --git a/stdlib/source/library/lux/data/collection/tree/finger.lux b/stdlib/source/library/lux/data/collection/tree/finger.lux
index b0dcece05..3f807f49f 100644
--- a/stdlib/source/library/lux/data/collection/tree/finger.lux
+++ b/stdlib/source/library/lux/data/collection/tree/finger.lux
@@ -20,15 +20,16 @@
     #root (Or v
               [(Tree @ t v) (Tree @ t v)])})
 
-  (interface: .public (Builder @ t)
-    (: (All [v]
-         (-> t v (Tree @ t v)))
-       leaf)
-    (: (All [v]
-         (-> (Tree @ t v)
-             (Tree @ t v)
-             (Tree @ t v)))
-       branch))
+  (type: .public (Builder @ t)
+    (Interface
+     (: (All [v]
+          (-> t v (Tree @ t v)))
+        leaf)
+     (: (All [v]
+          (-> (Tree @ t v)
+              (Tree @ t v)
+              (Tree @ t v)))
+        branch)))
 
   (template [<name> <tag> <output>]
     [(def: .public <name>
diff --git a/stdlib/source/library/lux/data/format/json.lux b/stdlib/source/library/lux/data/format/json.lux
index 6582b7402..6aec38ce5 100644
--- a/stdlib/source/library/lux/data/format/json.lux
+++ b/stdlib/source/library/lux/data/format/json.lux
@@ -40,14 +40,15 @@
   [String  Text]
   )
 
-(type: .public #rec JSON
-  (Variant
-   (#Null    Null)
-   (#Boolean Boolean)
-   (#Number  Number)
-   (#String  String)
-   (#Array   (Row JSON))
-   (#Object  (Dictionary String JSON))))
+(type: .public JSON
+  (Rec JSON
+    (Variant
+     (#Null    Null)
+     (#Boolean Boolean)
+     (#Number  Number)
+     (#String  String)
+     (#Array   (Row JSON))
+     (#Object  (Dictionary String JSON)))))
 
 (template [<name> <type>]
   [(type: .public <name>
diff --git a/stdlib/source/library/lux/data/format/xml.lux b/stdlib/source/library/lux/data/format/xml.lux
index ef2c8e19a..9c29b086a 100644
--- a/stdlib/source/library/lux/data/format/xml.lux
+++ b/stdlib/source/library/lux/data/format/xml.lux
@@ -34,10 +34,11 @@
   Attrs
   (dictionary.empty name.hash))
 
-(type: .public #rec XML
-  (Variant
-   (#Text Text)
-   (#Node Tag Attrs (List XML))))
+(type: .public XML
+  (Rec XML
+    (Variant
+     (#Text Text)
+     (#Node Tag Attrs (List XML)))))
 
 (def: namespace_separator
   ":")
diff --git a/stdlib/source/library/lux/documentation.lux b/stdlib/source/library/lux/documentation.lux
index 05610b52f..937401d5d 100644
--- a/stdlib/source/library/lux/documentation.lux
+++ b/stdlib/source/library/lux/documentation.lux
@@ -1,6 +1,6 @@
 (.module:
   [library
-   [lux (#- Definition Module example type)
+   [lux (#- Definition Module type)
     ["." meta]
     ["." type ("#\." equivalence)]
     [abstract
@@ -252,7 +252,7 @@
    {#definition Text
     #documentation (Markdown Block)}))
 
-(type: .public #rec Module
+(type: .public Module
   (Record
    {#module Text
     #description Text
diff --git a/stdlib/source/library/lux/ffi.jvm.lux b/stdlib/source/library/lux/ffi.jvm.lux
index f7b94e8df..363effd18 100644
--- a/stdlib/source/library/lux/ffi.jvm.lux
+++ b/stdlib/source/library/lux/ffi.jvm.lux
@@ -1,6 +1,6 @@
 (.module:
   [library
-   ["." lux (#- Type type int char interface: :as)
+   ["." lux (#- Type type int char :as)
     ["#_." type ("#\." equivalence)]
     [abstract
      ["." monad (#+ Monad do)]
diff --git a/stdlib/source/library/lux/ffi.old.lux b/stdlib/source/library/lux/ffi.old.lux
index 496b4475c..8e8c03e53 100644
--- a/stdlib/source/library/lux/ffi.old.lux
+++ b/stdlib/source/library/lux/ffi.old.lux
@@ -1,6 +1,6 @@
 (.module:
   [library
-   [lux (#- type interface:)
+   [lux (#- type)
     ["." type ("#\." equivalence)]
     [abstract
      ["." monad (#+ Monad do)]
@@ -78,12 +78,13 @@
    #UpperBound
    #LowerBound))
 
-(type: #rec GenericType
-  (Variant
-   (#GenericTypeVar Text)
-   (#GenericClass [Text (List GenericType)])
-   (#GenericArray GenericType)
-   (#GenericWildcard (Maybe [BoundKind GenericType]))))
+(type: GenericType
+  (Rec GenericType
+    (Variant
+     (#GenericTypeVar Text)
+     (#GenericClass [Text (List GenericType)])
+     (#GenericArray GenericType)
+     (#GenericWildcard (Maybe [BoundKind GenericType])))))
 
 (type: Type_Parameter
   [Text (List GenericType)])
diff --git a/stdlib/source/library/lux/math/infix.lux b/stdlib/source/library/lux/math/infix.lux
index c2847d72e..207484719 100644
--- a/stdlib/source/library/lux/math/infix.lux
+++ b/stdlib/source/library/lux/math/infix.lux
@@ -18,12 +18,13 @@
       ["n" nat]
       ["i" int]]]]])
 
-(type: #rec Infix
-  (Variant
-   (#Const Code)
-   (#Call (List Code))
-   (#Unary Code Infix)
-   (#Binary Infix Code Infix)))
+(type: Infix
+  (Rec Infix
+    (Variant
+     (#Const Code)
+     (#Call (List Code))
+     (#Unary Code Infix)
+     (#Binary Infix Code Infix))))
 
 (def: literal
   (Parser Code)
diff --git a/stdlib/source/library/lux/math/number/i64.lux b/stdlib/source/library/lux/math/number/i64.lux
index e1706c217..ecad8a4ec 100644
--- a/stdlib/source/library/lux/math/number/i64.lux
+++ b/stdlib/source/library/lux/math/number/i64.lux
@@ -178,15 +178,16 @@
          swap/02
          swap/01)))
 
-(interface: .public (Sub size)
-  (: (Equivalence (I64 size))
-     &equivalence)
-  (: Nat
-     width)
-  (: (-> I64 (I64 size))
-     narrow)
-  (: (-> (I64 size) I64)
-     wide))
+(type: .public (Sub size)
+  (Interface
+   (: (Equivalence (I64 size))
+      &equivalence)
+   (: Nat
+      width)
+   (: (-> I64 (I64 size))
+      narrow)
+   (: (-> (I64 size) I64)
+      wide)))
 
 (def: .public (sub width)
   (Ex [size] (-> Nat (Maybe (Sub size))))
diff --git a/stdlib/source/library/lux/math/number/rev.lux b/stdlib/source/library/lux/math/number/rev.lux
index 5af0bf3ff..06cc92053 100644
--- a/stdlib/source/library/lux/math/number/rev.lux
+++ b/stdlib/source/library/lux/math/number/rev.lux
@@ -20,12 +20,15 @@
    ["#." nat]
    ["#." int]])
 
+(def: .public /1
+  Rev
+  (.rev -1))
+
 (template [<power> <name>]
   [(def: .public <name>
      Rev
      (.rev (//i64.left_shifted (//nat.- <power> //i64.width) 1)))]
 
-  [00 /1]
   [01 /2]
   [02 /4]
   [03 /8]
diff --git a/stdlib/source/library/lux/math/random.lux b/stdlib/source/library/lux/math/random.lux
index 2f83a8d00..b416d2c8a 100644
--- a/stdlib/source/library/lux/math/random.lux
+++ b/stdlib/source/library/lux/math/random.lux
@@ -37,8 +37,9 @@
     [type
      [refinement (#+ Refiner Refined)]]]])
 
-(type: .public #rec PRNG
-  (-> Any [PRNG I64]))
+(type: .public PRNG
+  (Rec PRNG
+    (-> Any [PRNG I64])))
 
 (type: .public (Random a)
   (-> PRNG [PRNG a]))
diff --git a/stdlib/source/library/lux/meta/annotation.lux b/stdlib/source/library/lux/meta/annotation.lux
index 292445ea8..d2cc9a45a 100644
--- a/stdlib/source/library/lux/meta/annotation.lux
+++ b/stdlib/source/library/lux/meta/annotation.lux
@@ -64,14 +64,9 @@
   (-> Name Annotation Bit)
   (|>> (..bit flag) (maybe.else false)))
 
-(template [<name> <tag>]
-  [(def: .public <name>
-     (-> Annotation Bit)
-     (..flagged? (name_of <tag>)))]
-
-  [implementation? #.implementation?]
-  [recursive_type? #.type_rec?]
-  )
+(def: .public implementation?
+  (-> Annotation Bit)
+  (..flagged? (name_of #.implementation?)))
 
 (def: (text_parser input)
   (-> Code (Maybe Text))
diff --git a/stdlib/source/library/lux/target/jvm/attribute.lux b/stdlib/source/library/lux/target/jvm/attribute.lux
index 640ad8683..658b53a06 100644
--- a/stdlib/source/library/lux/target/jvm/attribute.lux
+++ b/stdlib/source/library/lux/target/jvm/attribute.lux
@@ -52,10 +52,11 @@
        (|>> nameT lengthT infoT)])))
 
 (with_expansions [<Code> (as_is (/code.Code Attribute))]
-  (type: .public #rec Attribute
-    (Variant
-     (#Constant (Info (Constant Any)))
-     (#Code (Info <Code>))))
+  (type: .public Attribute
+    (Rec Attribute
+      (Variant
+       (#Constant (Info (Constant Any)))
+       (#Code (Info <Code>)))))
 
   (type: .public Code
     <Code>)
diff --git a/stdlib/source/library/lux/target/jvm/class.lux b/stdlib/source/library/lux/target/jvm/class.lux
index 1280b23c4..03853a4ee 100644
--- a/stdlib/source/library/lux/target/jvm/class.lux
+++ b/stdlib/source/library/lux/target/jvm/class.lux
@@ -27,19 +27,20 @@
    ["#." constant (#+ Constant)
     ["#/." pool (#+ Pool Resource)]]])
 
-(type: .public #rec Class
-  (Record
-   {#magic Magic
-    #minor_version Minor
-    #major_version Major
-    #constant_pool Pool
-    #modifier (Modifier Class)
-    #this (Index //constant.Class)
-    #super (Index //constant.Class)
-    #interfaces (Row (Index //constant.Class))
-    #fields (Row Field)
-    #methods (Row Method)
-    #attributes (Row Attribute)}))
+(type: .public Class
+  (Rec Class
+    (Record
+     {#magic Magic
+      #minor_version Minor
+      #major_version Major
+      #constant_pool Pool
+      #modifier (Modifier Class)
+      #this (Index //constant.Class)
+      #super (Index //constant.Class)
+      #interfaces (Row (Index //constant.Class))
+      #fields (Row Field)
+      #methods (Row Method)
+      #attributes (Row Attribute)})))
 
 (modifiers: Class
   ["0001" public]
diff --git a/stdlib/source/library/lux/target/jvm/field.lux b/stdlib/source/library/lux/target/jvm/field.lux
index 4ccaf58c4..5514a2674 100644
--- a/stdlib/source/library/lux/target/jvm/field.lux
+++ b/stdlib/source/library/lux/target/jvm/field.lux
@@ -20,12 +20,13 @@
     [category (#+ Value)]
     [descriptor (#+ Descriptor)]]])
 
-(type: .public #rec Field
-  (Record
-   {#modifier (Modifier Field)
-    #name (Index UTF8)
-    #descriptor (Index (Descriptor Value))
-    #attributes (Row Attribute)}))
+(type: .public Field
+  (Rec Field
+    (Record
+     {#modifier (Modifier Field)
+      #name (Index UTF8)
+      #descriptor (Index (Descriptor Value))
+      #attributes (Row Attribute)})))
 
 (modifiers: Field
   ["0001" public]
diff --git a/stdlib/source/library/lux/target/jvm/method.lux b/stdlib/source/library/lux/target/jvm/method.lux
index 38bae94fc..09a7d56f1 100644
--- a/stdlib/source/library/lux/target/jvm/method.lux
+++ b/stdlib/source/library/lux/target/jvm/method.lux
@@ -26,12 +26,13 @@
     ["#/." category]
     ["#." descriptor (#+ Descriptor)]]])
 
-(type: .public #rec Method
-  (Record
-   {#modifier (Modifier Method)
-    #name (Index UTF8)
-    #descriptor (Index (Descriptor //type/category.Method))
-    #attributes (Row Attribute)}))
+(type: .public Method
+  (Rec Method
+    (Record
+     {#modifier (Modifier Method)
+      #name (Index UTF8)
+      #descriptor (Index (Descriptor //type/category.Method))
+      #attributes (Row Attribute)})))
 
 (modifiers: Method
   ["0001" public]
diff --git a/stdlib/source/library/lux/tool/compiler/language/lux/analysis.lux b/stdlib/source/library/lux/tool/compiler/language/lux/analysis.lux
index c8d3e1d9e..e7c01dc34 100644
--- a/stdlib/source/library/lux/tool/compiler/language/lux/analysis.lux
+++ b/stdlib/source/library/lux/tool/compiler/language/lux/analysis.lux
@@ -80,11 +80,12 @@
    (#Variant (Variant a))
    (#Tuple (Tuple a))))
 
-(type: .public #rec Pattern
-  (.Variant
-   (#Simple Primitive)
-   (#Complex (Composite Pattern))
-   (#Bind Register)))
+(type: .public Pattern
+  (Rec Pattern
+    (.Variant
+     (#Simple Primitive)
+     (#Complex (Composite Pattern))
+     (#Bind Register))))
 
 (type: .public (Branch' e)
   (Record
@@ -97,15 +98,16 @@
 (type: .public (Environment a)
   (List a))
 
-(type: .public #rec Analysis
-  (.Variant
-   (#Primitive Primitive)
-   (#Structure (Composite Analysis))
-   (#Reference Reference)
-   (#Case Analysis (Match' Analysis))
-   (#Function (Environment Analysis) Analysis)
-   (#Apply Analysis Analysis)
-   (#Extension (Extension Analysis))))
+(type: .public Analysis
+  (Rec Analysis
+    (.Variant
+     (#Primitive Primitive)
+     (#Structure (Composite Analysis))
+     (#Reference Reference)
+     (#Case Analysis (Match' Analysis))
+     (#Function (Environment Analysis) Analysis)
+     (#Apply Analysis Analysis)
+     (#Extension (Extension Analysis)))))
 
 (type: .public Branch
   (Branch' Analysis))
diff --git a/stdlib/source/library/lux/tool/compiler/language/lux/generation.lux b/stdlib/source/library/lux/tool/compiler/language/lux/generation.lux
index aab4af121..1b8cc945d 100644
--- a/stdlib/source/library/lux/tool/compiler/language/lux/generation.lux
+++ b/stdlib/source/library/lux/tool/compiler/language/lux/generation.lux
@@ -49,20 +49,21 @@
   [no_buffer_for_saving_code]
   )
 
-(interface: .public (Host expression directive)
-  (: (-> Context expression (Try Any))
-     evaluate!)
-  (: (-> directive (Try Any))
-     execute!)
-  (: (-> Context (Maybe Text) expression (Try [Text Any directive]))
-     define!)
-
-  (: (-> Context Binary directive)
-     ingest)
-  (: (-> Context (Maybe Text) directive (Try Any))
-     re_learn)
-  (: (-> Context (Maybe Text) directive (Try Any))
-     re_load))
+(type: .public (Host expression directive)
+  (Interface
+   (: (-> Context expression (Try Any))
+      evaluate!)
+   (: (-> directive (Try Any))
+      execute!)
+   (: (-> Context (Maybe Text) expression (Try [Text Any directive]))
+      define!)
+
+   (: (-> Context Binary directive)
+      ingest)
+   (: (-> Context (Maybe Text) directive (Try Any))
+      re_learn)
+   (: (-> Context (Maybe Text) directive (Try Any))
+      re_load)))
 
 (type: .public (State anchor expression directive)
   (Record
diff --git a/stdlib/source/library/lux/tool/compiler/language/lux/phase/analysis/case/coverage.lux b/stdlib/source/library/lux/tool/compiler/language/lux/phase/analysis/case/coverage.lux
index 36c5f193f..d9b47d757 100644
--- a/stdlib/source/library/lux/tool/compiler/language/lux/phase/analysis/case/coverage.lux
+++ b/stdlib/source/library/lux/tool/compiler/language/lux/phase/analysis/case/coverage.lux
@@ -47,14 +47,15 @@
 ... The #Partial tag covers arbitrary partial coverages in a general
 ... way, while the other tags cover more specific cases for bits
 ... and variants.
-(type: .public #rec Coverage
-  (.Variant
-   #Partial
-   (#Bit Bit)
-   (#Variant (Maybe Nat) (Dictionary Nat Coverage))
-   (#Seq Coverage Coverage)
-   (#Alt Coverage Coverage)
-   #Exhaustive))
+(type: .public Coverage
+  (Rec Coverage
+    (.Variant
+     #Partial
+     (#Bit Bit)
+     (#Variant (Maybe Nat) (Dictionary Nat Coverage))
+     (#Seq Coverage Coverage)
+     (#Alt Coverage Coverage)
+     #Exhaustive)))
 
 (def: .public (exhaustive? coverage)
   (-> Coverage Bit)
diff --git a/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/reference.lux b/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/reference.lux
index 9259c0ef1..cc0e2e859 100644
--- a/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/reference.lux
+++ b/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/reference.lux
@@ -44,11 +44,12 @@
           "m" (%.nat module)
           "a" (%.nat artifact)))
 
-(interface: .public (System expression)
-  (: (-> Text expression)
-     constant)
-  (: (-> Text expression)
-     variable))
+(type: .public (System expression)
+  (Interface
+   (: (-> Text expression)
+      constant)
+   (: (-> Text expression)
+      variable)))
 
 (def: .public (constant system archive name)
   (All [anchor expression directive]
diff --git a/stdlib/source/library/lux/tool/compiler/language/lux/synthesis.lux b/stdlib/source/library/lux/tool/compiler/language/lux/synthesis.lux
index dc555b85d..1fe8d3abd 100644
--- a/stdlib/source/library/lux/tool/compiler/language/lux/synthesis.lux
+++ b/stdlib/source/library/lux/tool/compiler/language/lux/synthesis.lux
@@ -126,13 +126,14 @@
    (#Loop (Loop s))
    (#Function (Function s))))
 
-(type: .public #rec Synthesis
-  (Variant
-   (#Primitive Primitive)
-   (#Structure (Composite Synthesis))
-   (#Reference Reference)
-   (#Control (Control Synthesis))
-   (#Extension (Extension Synthesis))))
+(type: .public Synthesis
+  (Rec Synthesis
+    (Variant
+     (#Primitive Primitive)
+     (#Structure (Composite Synthesis))
+     (#Reference Reference)
+     (#Control (Control Synthesis))
+     (#Extension (Extension Synthesis)))))
 
 (template [<special> <general>]
   [(type: .public <special>
diff --git a/stdlib/source/library/lux/type/implicit.lux b/stdlib/source/library/lux/type/implicit.lux
index faaa608b2..ca568e7fd 100644
--- a/stdlib/source/library/lux/type/implicit.lux
+++ b/stdlib/source/library/lux/type/implicit.lux
@@ -200,10 +200,11 @@
     [actual_output (monad.mix check.monad ..on_argument member_type input_types)]
     (check.check expected_output actual_output)))
 
-(type: #rec Instance
-  (Record
-   {#constructor Name
-    #dependencies (List Instance)}))
+(type: Instance
+  (Rec Instance
+    (Record
+     {#constructor Name
+      #dependencies (List Instance)})))
 
 (def: (candidate_provision provision context dep alts)
   (-> (-> Lux Type_Context Type (Check Instance))
diff --git a/stdlib/source/library/lux/type/poly.lux b/stdlib/source/library/lux/type/poly.lux
index def324897..9fb6a945b 100644
--- a/stdlib/source/library/lux/type/poly.lux
+++ b/stdlib/source/library/lux/type/poly.lux
@@ -88,11 +88,11 @@
             (|> (dictionary.value idx env) maybe.trusted product.left (code env))
             (` (.$ (~ (code.nat (-- idx)))))))
 
-        (#.Apply (#.Named [(~~ (static .prelude_module)) "Nothing"] _) (#.Parameter idx))
-        (let [idx (<type>.adjusted_idx env idx)]
-          (if (n.= 0 idx)
-            (|> (dictionary.value idx env) maybe.trusted product.left (code env))
-            (undefined)))
+        (#.Apply (#.Named [(~~ (static .prelude_module)) "Nothing"] _)
+                 (#.Parameter idx))
+        (case (<type>.adjusted_idx env idx)
+          0 (|> env (dictionary.value 0) maybe.trusted product.left (code env))
+          idx (undefined))
         
         (^template [<tag>]
           [(<tag> left right)
diff --git a/stdlib/source/library/lux/type/unit.lux b/stdlib/source/library/lux/type/unit.lux
index c4f1e5e58..5c42da5ed 100644
--- a/stdlib/source/library/lux/type/unit.lux
+++ b/stdlib/source/library/lux/type/unit.lux
@@ -61,19 +61,21 @@
     )
   )
 
-(interface: .public (Unit a)
-  (: (-> Int (Qty a))
-     in)
-  (: (-> (Qty a) Int)
-     out))
-
-(interface: .public (Scale s)
-  (: (All [u] (-> (Qty u) (Qty (s u))))
-     scale)
-  (: (All [u] (-> (Qty (s u)) (Qty u)))
-     de_scale)
-  (: Ratio
-     ratio))
+(type: .public (Unit a)
+  (Interface
+   (: (-> Int (Qty a))
+      in)
+   (: (-> (Qty a) Int)
+      out)))
+
+(type: .public (Scale s)
+  (Interface
+   (: (All [u] (-> (Qty u) (Qty (s u))))
+      scale)
+   (: (All [u] (-> (Qty (s u)) (Qty u)))
+      de_scale)
+   (: Ratio
+      ratio)))
 
 (type: .public Pure
   (Qty Any))
diff --git a/stdlib/source/library/lux/world/console.lux b/stdlib/source/library/lux/world/console.lux
index 02d4ee299..d113e1fab 100644
--- a/stdlib/source/library/lux/world/console.lux
+++ b/stdlib/source/library/lux/world/console.lux
@@ -16,15 +16,16 @@
      ["." text (#+ Char)
       ["%" format (#+ format)]]]]])
 
-(interface: .public (Console !)
-  (: (-> [] (! (Try Char)))
-     read)
-  (: (-> [] (! (Try Text)))
-     read_line)
-  (: (-> Text (! (Try Any)))
-     write)
-  (: (-> [] (! (Try Any)))
-     close))
+(type: .public (Console !)
+  (Interface
+   (: (-> [] (! (Try Char)))
+      read)
+   (: (-> [] (! (Try Text)))
+      read_line)
+   (: (-> Text (! (Try Any)))
+      write)
+   (: (-> [] (! (Try Any)))
+      close)))
 
 (def: .public (async console)
   (-> (Console IO) (Console Async))
@@ -102,15 +103,16 @@
   (All [!] (-> Text (Console !) (! (Try Any))))
   (\ console write (format message text.new_line)))
 
-(interface: .public (Mock s)
-  (: (-> s (Try [s Char]))
-     on_read)
-  (: (-> s (Try [s Text]))
-     on_read_line)
-  (: (-> Text s (Try s))
-     on_write)
-  (: (-> s (Try s))
-     on_close))
+(type: .public (Mock s)
+  (Interface
+   (: (-> s (Try [s Char]))
+      on_read)
+   (: (-> s (Try [s Text]))
+      on_read_line)
+   (: (-> Text s (Try s))
+      on_write)
+   (: (-> s (Try s))
+      on_close)))
 
 (def: .public (mock mock init)
   (All [s] (-> (Mock s) s (Console IO)))
diff --git a/stdlib/source/library/lux/world/db/jdbc.lux b/stdlib/source/library/lux/world/db/jdbc.lux
index f2ca6ee00..dd11cd4f3 100644
--- a/stdlib/source/library/lux/world/db/jdbc.lux
+++ b/stdlib/source/library/lux/world/db/jdbc.lux
@@ -79,15 +79,16 @@
 (capability: .public (Can_Close !)
   (can_close Any (! (Try Any))))
 
-(interface: .public (DB !)
-  (: (Can_Execute !)
-     execute)
-  (: (Can_Insert !)
-     insert)
-  (: (Can_Query !)
-     query)
-  (: (Can_Close !)
-     close))
+(type: .public (DB !)
+  (Interface
+   (: (Can_Execute !)
+      execute)
+   (: (Can_Insert !)
+      insert)
+   (: (Can_Query !)
+      query)
+   (: (Can_Close !)
+      close)))
 
 (def: (with_statement statement conn action)
   (All [i a]
diff --git a/stdlib/source/library/lux/world/file.lux b/stdlib/source/library/lux/world/file.lux
index d9676e54e..3fd525b37 100644
--- a/stdlib/source/library/lux/world/file.lux
+++ b/stdlib/source/library/lux/world/file.lux
@@ -38,42 +38,43 @@
 (type: .public Path
   Text)
 
-(`` (interface: .public (System !)
-      (: Text
-         separator)
-
-      (~~ (template [<name> <output>]
-            [(: (-> Path (! <output>))
-                <name>)]
-
-            [file? Bit]
-            [directory? Bit]
-            ))
-
-      (~~ (template [<name> <output>]
-            [(: (-> Path (! (Try <output>)))
-                <name>)]
-
-            [make_directory  Any]
-            [directory_files (List Path)]
-            [sub_directories (List Path)]
-            
-            [file_size     Nat]
-            [last_modified Instant]
-            [can_execute?  Bit]
-            [read          Binary]
-            [delete        Any]
-            ))
-
-      (~~ (template [<name> <input>]
-            [(: (-> <input> Path (! (Try Any)))
-                <name>)]
-
-            [modify Instant]
-            [write  Binary]
-            [append Binary]
-            [move   Path]
-            ))
+(`` (type: .public (System !)
+      (Interface
+       (: Text
+          separator)
+
+       (~~ (template [<name> <output>]
+             [(: (-> Path (! <output>))
+                 <name>)]
+
+             [file? Bit]
+             [directory? Bit]
+             ))
+
+       (~~ (template [<name> <output>]
+             [(: (-> Path (! (Try <output>)))
+                 <name>)]
+
+             [make_directory  Any]
+             [directory_files (List Path)]
+             [sub_directories (List Path)]
+             
+             [file_size     Nat]
+             [last_modified Instant]
+             [can_execute?  Bit]
+             [read          Binary]
+             [delete        Any]
+             ))
+
+       (~~ (template [<name> <input>]
+             [(: (-> <input> Path (! (Try Any)))
+                 <name>)]
+
+             [modify Instant]
+             [write  Binary]
+             [append Binary]
+             [move   Path]
+             )))
       ))
 
 (def: (un_rooted fs path)
@@ -998,8 +999,9 @@
     #mock_can_execute Bit
     #mock_content Binary}))
 
-(type: #rec Mock
-  (Dictionary Text (Either Mock_File Mock)))
+(type: Mock
+  (Rec Mock
+    (Dictionary Text (Either Mock_File Mock))))
 
 (def: empty_mock
   Mock
diff --git a/stdlib/source/library/lux/world/file/watch.lux b/stdlib/source/library/lux/world/file/watch.lux
index 581beba6d..decd4d5a5 100644
--- a/stdlib/source/library/lux/world/file/watch.lux
+++ b/stdlib/source/library/lux/world/file/watch.lux
@@ -83,15 +83,16 @@
         ))
   )
 
-(interface: .public (Watcher !)
-  (: (-> Concern //.Path (! (Try Any)))
-     start)
-  (: (-> //.Path (! (Try Concern)))
-     concern)
-  (: (-> //.Path (! (Try Concern)))
-     stop)
-  (: (-> [] (! (Try (List [Concern //.Path]))))
-     poll))
+(type: .public (Watcher !)
+  (Interface
+   (: (-> Concern //.Path (! (Try Any)))
+      start)
+   (: (-> //.Path (! (Try Concern)))
+      concern)
+   (: (-> //.Path (! (Try Concern)))
+      stop)
+   (: (-> [] (! (Try (List [Concern //.Path]))))
+      poll)))
 
 (template [<name>]
   [(exception: .public (<name> {path //.Path})
diff --git a/stdlib/source/library/lux/world/net/http/client.lux b/stdlib/source/library/lux/world/net/http/client.lux
index 4790ab3c5..f1c4120a1 100644
--- a/stdlib/source/library/lux/world/net/http/client.lux
+++ b/stdlib/source/library/lux/world/net/http/client.lux
@@ -30,10 +30,11 @@
   ["." //
    [// (#+ URL)]])
 
-(interface: .public (Client !)
-  (: (-> //.Method URL //.Headers (Maybe Binary)
-         (! (Try (//.Response !))))
-     request))
+(type: .public (Client !)
+  (Interface
+   (: (-> //.Method URL //.Headers (Maybe Binary)
+          (! (Try (//.Response !))))
+      request)))
 
 (syntax: (method_function [[_ name] <code>.tag])
   (in (list (code.local_identifier (text.lower_cased name)))))
diff --git a/stdlib/source/library/lux/world/program.lux b/stdlib/source/library/lux/world/program.lux
index 00aa1553d..6fd8c63bc 100644
--- a/stdlib/source/library/lux/world/program.lux
+++ b/stdlib/source/library/lux/world/program.lux
@@ -39,17 +39,18 @@
   (exception.report
    ["Name" (%.text name)]))
 
-(interface: .public (Program !)
-  (: (-> Any (! (List Text)))
-     available_variables)
-  (: (-> Text (! (Try Text)))
-     variable)
-  (: Path
-     home)
-  (: Path
-     directory)
-  (: (-> Exit (! Nothing))
-     exit))
+(type: .public (Program !)
+  (Interface
+   (: (-> Any (! (List Text)))
+      available_variables)
+   (: (-> Text (! (Try Text)))
+      variable)
+   (: Path
+      home)
+   (: Path
+      directory)
+   (: (-> Exit (! Nothing))
+      exit)))
 
 (def: .public (environment monad program)
   (All [!] (-> (Monad !) (Program !) (! Environment)))
diff --git a/stdlib/source/library/lux/world/shell.lux b/stdlib/source/library/lux/world/shell.lux
index 470ac4cd2..d473f7cdb 100644
--- a/stdlib/source/library/lux/world/shell.lux
+++ b/stdlib/source/library/lux/world/shell.lux
@@ -45,17 +45,18 @@
   [+1 error]
   )
 
-(interface: .public (Process !)
-  (: (-> [] (! (Try Text)))
-     read)
-  (: (-> [] (! (Try Text)))
-     error)
-  (: (-> Text (! (Try Any)))
-     write)
-  (: (-> [] (! (Try Any)))
-     destroy)
-  (: (-> [] (! (Try Exit)))
-     await))
+(type: .public (Process !)
+  (Interface
+   (: (-> [] (! (Try Text)))
+      read)
+   (: (-> [] (! (Try Text)))
+      error)
+   (: (-> Text (! (Try Any)))
+      write)
+   (: (-> [] (! (Try Any)))
+      destroy)
+   (: (-> [] (! (Try Exit)))
+      await)))
 
 (def: (async_process process)
   (-> (Process IO) (Process Async))
@@ -78,9 +79,10 @@
 (type: .public Argument
   Text)
 
-(interface: .public (Shell !)
-  (: (-> [Environment Path Command (List Argument)] (! (Try (Process !))))
-     execute))
+(type: .public (Shell !)
+  (Interface
+   (: (-> [Environment Path Command (List Argument)] (! (Try (Process !))))
+      execute)))
 
 (def: .public (async shell)
   (-> (Shell IO) (Shell Async))
@@ -92,13 +94,14 @@
         (in (..async_process process)))))))
 
 ... https://en.wikipedia.org/wiki/Code_injection#Shell_injection
-(interface: (Policy ?)
-  (: (-> Command (Safe Command ?))
-     command)
-  (: (-> Argument (Safe Argument ?))
-     argument)
-  (: (All [a] (-> (Safe a ?) a))
-     value))
+(type: (Policy ?)
+  (Interface
+   (: (-> Command (Safe Command ?))
+      command)
+   (: (-> Argument (Safe Argument ?))
+      argument)
+   (: (All [a] (-> (Safe a ?) a))
+      value)))
 
 (type: (Sanitizer a)
   (-> a a))
@@ -307,17 +310,18 @@
         @.jvm (as_is <jvm>)}
        (as_is)))
 
-(interface: .public (Mock s)
-  (: (-> s (Try [s Text]))
-     on_read)
-  (: (-> s (Try [s Text]))
-     on_error)
-  (: (-> Text s (Try s))
-     on_write)
-  (: (-> s (Try s))
-     on_destroy)
-  (: (-> s (Try [s Exit]))
-     on_await))
+(type: .public (Mock s)
+  (Interface
+   (: (-> s (Try [s Text]))
+      on_read)
+   (: (-> s (Try [s Text]))
+      on_error)
+   (: (-> Text s (Try s))
+      on_write)
+   (: (-> s (Try s))
+      on_destroy)
+   (: (-> s (Try [s Exit]))
+      on_await)))
 
 (`` (implementation: (mock_process state mock)
       (All [s] (-> (Atom s) (Mock s) (Process IO)))
diff --git a/stdlib/source/poly/lux/data/format/json.lux b/stdlib/source/poly/lux/data/format/json.lux
index 8de72193b..d538a7e92 100644
--- a/stdlib/source/poly/lux/data/format/json.lux
+++ b/stdlib/source/poly/lux/data/format/json.lux
@@ -324,24 +324,6 @@
           ))))
 
 (syntax: .public (codec [inputT <code>.any])
-  {#.doc (example "A macro for automatically producing JSON codecs."
-                  (type: Variant
-                    (#Bit Bit)
-                    (#Text Text)
-                    (#Frac Frac))
-
-                  (type: Record
-                    {#bit Bit
-                     #frac Frac
-                     #text Text
-                     #maybe (Maybe Frac)
-                     #list (List Frac)
-                     #variant Variant
-                     #tuple [Bit Frac Text]
-                     #dictionary (Dictionary Text Frac)})
-
-                  (derived: codec
-                    (..codec Record)))}
   (in (.list (` (: (codec.Codec /.JSON (~ inputT))
                    (implementation
                     (def: (~' encoded)
diff --git a/stdlib/source/program/aedifex/repository.lux b/stdlib/source/program/aedifex/repository.lux
index 914cd1420..d1aa5a1b9 100644
--- a/stdlib/source/program/aedifex/repository.lux
+++ b/stdlib/source/program/aedifex/repository.lux
@@ -15,13 +15,14 @@
      [net
       [uri (#+ URI)]]]]])
 
-(interface: .public (Repository !)
-  (: Text
-     description)
-  (: (-> URI (! (Try Binary)))
-     download)
-  (: (-> URI Binary (! (Try Any)))
-     upload))
+(type: .public (Repository !)
+  (Interface
+   (: Text
+      description)
+   (: (-> URI (! (Try Binary)))
+      download)
+   (: (-> URI Binary (! (Try Any)))
+      upload)))
 
 (def: .public (async repository)
   (-> (Repository IO) (Repository Async))
@@ -35,13 +36,14 @@
      (async.future (\ repository upload uri content)))
    ))
 
-(interface: .public (Mock s)
-  (: Text
-     the_description)
-  (: (-> URI s (Try [s Binary]))
-     on_download)
-  (: (-> URI Binary s (Try s))
-     on_upload))
+(type: .public (Mock s)
+  (Interface
+   (: Text
+      the_description)
+   (: (-> URI s (Try [s Binary]))
+      on_download)
+   (: (-> URI Binary s (Try s))
+      on_upload)))
 
 (def: .public (mock mock init)
   (All [s] (-> (Mock s) s (Repository Async)))
diff --git a/stdlib/source/test/lux.lux b/stdlib/source/test/lux.lux
index a072fbc25..df0eb2f09 100644
--- a/stdlib/source/test/lux.lux
+++ b/stdlib/source/test/lux.lux
@@ -227,9 +227,10 @@
                    false))
         )))
 
-(/.interface: (Returner a)
-  (: (-> Any a)
-     return))
+(type: (Returner a)
+  (/.Interface
+   (: (-> Any a)
+      return)))
 
 (/.implementation: (global_returner value)
   (All [a] (-> a (Returner a)))
@@ -249,7 +250,7 @@
                              (/.implementation
                               (def: (return _)
                                 expected)))]]
-    (_.for [/.interface:]
+    (_.for [/.Interface]
            ($_ _.and
                (_.cover [/.implementation:]
                         (n.= expected (\ (global_returner expected) return [])))
@@ -557,6 +558,17 @@
                        (: /.Type ..for_type/record)
                        (: /.Type ..for_type/all)
                        true))
+            (_.cover [/.Variant]
+                     (exec
+                       (: for_type/variant
+                          (#Case/1 expected_left))
+                       true))
+            (_.cover [/.Record]
+                     (exec
+                       (: for_type/record
+                          {#slot/0 (n.= expected_left expected_right)
+                           #slot/1 (.rev expected_right)})
+                       true))
             ))))
 
 (def: for_i64
diff --git a/stdlib/source/test/lux/control/function/contract.lux b/stdlib/source/test/lux/control/function/contract.lux
index 48246a7c2..0cc1612d2 100644
--- a/stdlib/source/test/lux/control/function/contract.lux
+++ b/stdlib/source/test/lux/control/function/contract.lux
@@ -5,7 +5,10 @@
     [abstract
      [monad (#+ do)]]
     [control
-     ["." try]]
+     ["." try]
+     ["." exception]]
+    [data
+     ["." text]]
     [math
      ["." random]
      [number
@@ -19,20 +22,24 @@
       (do {! random.monad}
         [expected random.nat])
       ($_ _.and
-          (_.cover [/.pre]
+          (_.cover [/.pre /.pre_condition_failed]
                    (case (try (/.pre (n.even? expected)
                                      true))
                      (#try.Success output)
                      output
                      
                      (#try.Failure error)
-                     (not (n.even? expected))))
-          (_.cover [/.post]
+                     (and (text.contains? (value@ #exception.label /.pre_condition_failed)
+                                          error)
+                          (not (n.even? expected)))))
+          (_.cover [/.post /.post_condition_failed]
                    (case (try (/.post n.odd?
                                       expected))
                      (#try.Success actual)
                      (same? expected actual)
                      
                      (#try.Failure error)
-                     (not (n.odd? expected))))
+                     (and (text.contains? (value@ #exception.label /.post_condition_failed)
+                                          error)
+                          (not (n.odd? expected)))))
           )))
diff --git a/stdlib/source/test/lux/control/security/policy.lux b/stdlib/source/test/lux/control/security/policy.lux
index 5c2f1bf67..b49d04df9 100644
--- a/stdlib/source/test/lux/control/security/policy.lux
+++ b/stdlib/source/test/lux/control/security/policy.lux
@@ -33,15 +33,16 @@
 (type: Password
   (Private Text))
 
-(interface: (Policy %)
-  (: (Hash (Password %))
-     &hash)
+(type: (Policy %)
+  (Interface
+   (: (Hash (Password %))
+      &hash)
 
-  (: (-> Text (Password %))
-     password)
+   (: (-> Text (Password %))
+      password)
 
-  (: (Privilege Privacy %)
-     privilege))
+   (: (Privilege Privacy %)
+      privilege)))
 
 (def: (policy _)
   (Ex [%] (-> Any (Policy %)))
diff --git a/stdlib/source/test/lux/math/number/frac.lux b/stdlib/source/test/lux/math/number/frac.lux
index 7b11df2cb..cb8d4abaa 100644
--- a/stdlib/source/test/lux/math/number/frac.lux
+++ b/stdlib/source/test/lux/math/number/frac.lux
@@ -175,15 +175,15 @@
                            (and (/.= div (/./ left right))
                                 (/.= rem (/.% left right)))))
                 (_.cover [/.mod]
-                         (and (/.= (/.signum left)
-                                   (/.signum (/.mod left right)))
-                              (/.= (/.signum right)
-                                   (/.signum (/.% left right)))
-                              (if (/.= (/.signum left) (/.signum right))
-                                (/.= (/.% left right)
-                                     (/.mod left right))
-                                (or (and (/.= +0.0 (/.% left right))
-                                         (/.= +0.0 (/.mod left right)))
+                         (or (and (/.= +0.0 (/.% left right))
+                                  (/.= +0.0 (/.mod left right)))
+                             (and (/.= (/.signum left)
+                                       (/.signum (/.mod left right)))
+                                  (/.= (/.signum right)
+                                       (/.signum (/.% left right)))
+                                  (if (/.= (/.signum left) (/.signum right))
+                                    (/.= (/.% left right)
+                                         (/.mod left right))
                                     (/.= (/.+ left (/.% left right))
                                          (/.mod left right))))))
                 ))
diff --git a/stdlib/source/test/lux/math/number/rev.lux b/stdlib/source/test/lux/math/number/rev.lux
index cde50ec02..e55b08222 100644
--- a/stdlib/source/test/lux/math/number/rev.lux
+++ b/stdlib/source/test/lux/math/number/rev.lux
@@ -63,6 +63,7 @@
                               (/.= <whole>
                                    (/.+ <half> <half>)))]
 
+                    [/./1 (-- /./1)]
                     [/./2 .0]
                     [/./4 /./2]
                     [/./8 /./4]
diff --git a/stdlib/source/test/lux/meta/annotation.lux b/stdlib/source/test/lux/meta/annotation.lux
index f80ffeb29..c9a0f6946 100644
--- a/stdlib/source/test/lux/meta/annotation.lux
+++ b/stdlib/source/test/lux/meta/annotation.lux
@@ -101,21 +101,16 @@
                             (not (|> expected code.bit
                                      (..annotation dummy)
                                      (/.flagged? key))))))
-            (~~ (template [<definition> <tag>]
-                  [(do !
-                     [expected random.bit]
-                     (_.cover [<definition>]
-                              (and (|> expected code.bit
-                                       (..annotation (name_of <tag>))
-                                       <definition>
-                                       (\ bit.equivalence = expected))
-                                   (not (|> expected code.bit
-                                            (..annotation key)
-                                            <definition>)))))]
-
-                  [/.implementation? #.implementation?]
-                  [/.recursive_type? #.type_rec?]
-                  ))
+            (do !
+              [expected random.bit]
+              (_.cover [/.implementation?]
+                       (and (|> expected code.bit
+                                (..annotation (name_of #.implementation?))
+                                /.implementation?
+                                (\ bit.equivalence = expected))
+                            (not (|> expected code.bit
+                                     (..annotation key)
+                                     /.implementation?)))))
             ))))
 
 (def: arguments
diff --git a/stdlib/source/test/lux/type/poly/equivalence.lux b/stdlib/source/test/lux/type/poly/equivalence.lux
index 5d1953a52..a66c390b3 100644
--- a/stdlib/source/test/lux/type/poly/equivalence.lux
+++ b/stdlib/source/test/lux/type/poly/equivalence.lux
@@ -30,10 +30,11 @@
    (#Case1 Int)
    (#Case2 Frac)))
 
-(type: #rec Recursive
-  (.Variant
-   (#Number Frac)
-   (#Addition Frac Recursive)))
+(type: Recursive
+  (Rec Recursive
+    (.Variant
+     (#Number Frac)
+     (#Addition Frac Recursive))))
 
 (type: Record
   (.Record
@@ -77,7 +78,7 @@
         gen_recursive)))
 
 (derived: equivalence
-  (/.equivalence Record))
+  (/.equivalence ..Record))
 
 (def: .public test
   Test
diff --git a/stdlib/source/test/lux/type/poly/json.lux b/stdlib/source/test/lux/type/poly/json.lux
index 8e09a998a..2a7c17814 100644
--- a/stdlib/source/test/lux/type/poly/json.lux
+++ b/stdlib/source/test/lux/type/poly/json.lux
@@ -54,10 +54,11 @@
    (#Text Text)
    (#Frac Frac)))
 
-(type: #rec Recursive
-  (.Variant
-   (#Number Frac)
-   (#Addition Frac Recursive)))
+(type: Recursive
+  (Rec Recursive
+    (.Variant
+     (#Number Frac)
+     (#Addition Frac Recursive))))
 
 (type: Record
   (.Record
-- 
cgit v1.2.3