Repository: asteroid-lang/asteroid (language: python)

Issue:
review documentation for 2.0.1 release
We need to review the documentation for the 2.0.1 release.  In particular the User Guide.  A lot of terminology has been refined and that should be reflected in the documentation.
review documentation for 2.0.1 release
We need to review the documentation for the 2.0.1 release.  In particular the User Guide.  A lot of terminology has been refined and that should be reflected in the documentation.


Discussion / hints:

Fix patch:
diff --git a/docs/User Guide.rst b/docs/User Guide.rst
index fea18faf..802ff271 100644
--- a/docs/User Guide.rst
+++ b/docs/User Guide.rst
@@ -32,7 +32,7 @@ paradigm with first-class patterns.  Here are just two examples:
 **Example:** All statements that look like assignments are actually pattern-match statements.  For example if we state,
 ::
     let [x,2,y] = [1,2,3].
-that means the subject term ``[1,2,3]`` is matched to the pattern ``[x,2,y]`` and ``x`` and ``y`` are bound to the values 1 and 3, respectively.  By the way, there is nothing wrong with the following statement,
+that means the list ``[1,2,3]`` is matched to the pattern ``[x,2,y]`` and ``x`` and ``y`` are bound to the values 1 and 3, respectively.  By the way, there is nothing wrong with the following statement,
 ::
     let [1,2,3] = [1,2,3].
 which is just another pattern match without any variable instantiations.
@@ -43,20 +43,20 @@ that recursively computes the factorial of a positive integer and uses first-cla
 in order to ensure that the domain of the function is not violated,
 ::
     -- define first-class patterns
-    let POS_INT = pattern (x:%integer) if x > 0.
-    let NEG_INT = pattern (x:%integer) if x < 0.
+    let pos_int = pattern (x:%integer) if x > 0.
+    let neg_int = pattern (x:%integer) if x < 0.
 
     -- define our factorial function
     function fact
         with 0 do
             return 1
-        with n:*POS_INT do            -- use first pattern
+        with n:*pos_int do            -- use first pattern
             return n * fact (n-1).
-        with n:*NEG_INT do            -- use second pattern
+        with n:*neg_int do            -- use second pattern
             throw Error("undefined for "+n).
         end
 As you can see, the program first creates patterns and stores them in the variables
-``POS_INT`` and ``NEG_INT`` and it uses those patterns later in the code by
+``pos_int`` and ``neg_int`` and it uses those patterns later in the code by
 dereferencing those variables with the ``*`` operator.  First-class patterns have
 profound implications for software development in that pattern definition and usage
 points are now separate and patterns can be reused in different contexts.
@@ -69,7 +69,8 @@ with programming in Asteroid.
 The Basics
 ----------
 
-As with most programming languages we are familiar with, Asteroid has variables (alpha-numeric symbols starting with an alpha character) and constants.  Constants are available for all the primitive data types,
+As with most programming languages we are familiar with, Asteroid has variables (alpha-numeric symbols
+starting with an alpha character) and constants.  Constants are available for all four primitive data types,
 
 * ``integer``, e.g. ``1024``
 * ``real``, e.g. ``1.75``
@@ -81,7 +82,13 @@ Asteroid also supports the built-in data types:
 * ``list``
 * ``tuple``
 
-These are structured data types in that they can contain entities that belong to other data types. Both of these data types have constructors which are possibly empty sequences of comma separated values enclosed by square brackets for lists, e.g. ``[1,2,3]``, and enclosed by parentheses for tuples, e.g. ``(x,y)``. For tuples we have the caveat that the 1-tuple is represented by a value followed by a comma to distinguish it from parenthesized expressions, e.g. ``(3,)`` the 1-tuple versus ``(3)`` the parenthesized expression.
+These are structured data types in that they can contain entities that belong to other data types.
+Both of these data types have constructors which are sequences of comma separated values
+enclosed by square brackets for lists, e.g. ``[1,2,3]``, and enclosed by parentheses for tuples, e.g. ``(x,y)``.
+Lists are mutable structures in that we can add or delete elements.  On the other hand, tuples are immutable objects;
+once created you cannot change them.
+Furthermore, for tuples we have the caveat that the 1-tuple is represented by a value followed by a comma to distinguish it
+from parenthesized expressions, e.g. ``(3,)`` the 1-tuple versus ``(3)`` the parenthesized expression.
 Here are some examples,
 ::
     let l = [1,2,3].  -- this is a list
@@ -89,8 +96,6 @@ Here are some examples,
 As we said above, in order to distinguish it from a parenthesized value the single element in a 1-tuple has to be followed by a comma, like so,
 ::
     let one_tuple = (1,).  -- this is a 1-tuple
-Lists are mutable objects whereas tuples are immutable.
-
 We can cast lists and tuples to strings for easy printing,
 ::
     load system io.
@@ -117,6 +122,13 @@ also have the types ``function`` and ``pattern``,
 
    -- show that 'inc' is of type 'function'
    assert (gettype(inc) == "function").
+Here is a small program demonstrating the ``pattern`` data type,
+::
+   -- define a first-class pattern
+   let p = pattern (x:%integer) if x>0.
+
+   -- check the type of the value stored in p
+   assert (gettype(p) == "pattern").
 Data types in Asteroid do not form type hierarchies as in C/C++ and Java, for example.
 Therefore, in mixed type arithmetic statements we have to explicitly convert data types as in,
 ::
@@ -134,20 +146,14 @@ Lists
 In Asteroid the ``list`` is a fundamental, built-in data structure.  A trait it shares with programming languages such as Lisp, Python, ML, and Prolog.  Below is a list reversal example program.  Notice that lists are zero-indexed and
 elements of a list are accessed via the ``@`` operator,
 ::
-    load system io.
-
     let a = [1,2,3].          -- construct list a
     let b = [a@2, a@1, a@0].  -- reverse list a
-    io @println b.
-The output is: ``[3,2,1]``.
-
+    assert (b == [3,2,1]).
 We can achieve the same effect by giving a list of index values (a slice) to the ``@`` operator,
 ::
-    load system io.
-
     let a = [1,2,3].     -- construct list a
     let b = a@[2,1,0].   -- reverse list a using slice [2,1,0]
-    io @println b.
+    assert (b == [3,2,1]).
 In Asteroid lists are considered objects with member functions that can manipulate list
 objects. We could rewrite the above example as,
 ::
@@ -206,7 +212,7 @@ where the output is,
 Tuples
 ^^^^^^
 
-As we saw earlier, the tuple is another fundamental, built-in data structure that can be found in Asteroid.
+The tuple is another fundamental, built-in data structure that can be found in Asteroid.
 Below is an example of a tuple declaration and access.
 ::
     let a = (1,2,3).    -- construct tuple a
@@ -220,7 +226,7 @@ Lists and tuples may be nested,
              ("g","h","i")].
     -- Access an element in the nested structure.
     assert (b@0@1 == "b").
-As we have mentioned earlier, unlike lists, tuples are immutable. This means that their contents cannot be changed once they have been declared.  The following program demonstrates this,
+Unlike lists, tuples are immutable. This means that their contents cannot be changed once they have been declared.  The following program demonstrates this,
 ::
     load system io.
 
@@ -327,6 +333,7 @@ where we pattern match the pattern 1 on the left side to the value 1 on the righ
 
 Simple patterns are expressions that consist purely of constructors and variables. Constructors themselves consist of constants, list and tuple constructors, as well as user defined structures.
 The advantage of pattern matching is that it provides direct access to substructures of a particular value.
+This is often called "destructuring" of a value.
 Consider that we want to access the constituent values of the pair ``(1,2)``.  In a non-pattern-matching approach we would have to access each of these constituent values one-by-one,
 ::
     let p = (1,2).
@@ -341,7 +348,7 @@ the variables ``x`` and ``y`` where we expect our values to be,
     let (x,y) = p.
     assert (x==1 and y==2).
 
-Matching the pattern against the value ``(1,2)`` stored in ``p`` first matches the pair structure against the pair value and the matches the variables to the appropriate substructures.  Once the variables have been matched to value the ``let`` statement declares the variables in the current scope and they become available for computation.
+Matching the pattern against the value ``(1,2)`` stored in ``p`` first matches the pair structure against the pair value and then matches the variables to the appropriate substructures.  Once the variables have been matched to value the ``let`` statement declares the variables in the current scope and they become available for computation.
 
 The following is an example involving structures and objects,
 ::
@@ -355,34 +362,40 @@ The following is an example involving structures and objects,
     let Person(n,a,p) = joe.              -- pattern match object
 
     assert (n=="Joe" and a==32 and p=="Cook").
-We first construct an object ``joe`` with the first ``let`` statement and the use pattern matching to desctructure it with the second ``let`` statement binding its substructures to the variables ``n``, ``a``, and ``p``.
+We first construct an object ``joe`` with the first ``let`` statement and then use pattern matching to desctructure it with the second ``let`` statement binding its substructures to the variables ``n``, ``a``, and ``p``.
 
 Asteroid supports special patterns called type patterns that match any value
 of a given type.  For instance, the ``%integer`` pattern matches any integer value.  Here is a simple example,
 ::
     let %integer = 1.
-This let statement succeeds because ``1`` is an integer value can be pattern-matched against
-the type pattern ``%integer``.
-
-Asteroid also
-supports something called a named pattern were a (sub)pattern can be given a name
-and that name will be instantiated with a term during pattern matching.  For example,
+This ``let`` statement succeeds because ``1`` is an integer value that can be pattern-matched against
+the type pattern ``%integer``.  Type pattern exist for all builtin data types, ``%real`` and ``%list``.
+If you introduce a user defined type via a structure, then Asteroid will create a type pattern for all objects
+of that data type.  Here is a simple example,
 ::
-    load system io.
+    structure Foo with
+        data a.
+        data b.
+    end
 
-    let t:(x,y) = (1,2).  -- using a named pattern on lhs
-    io @println t.
-Here, the construct ``t:(x,y)`` is called a named pattern and the variable ``t`` will be unified with the term ``(1,2)``, or more generally, the variable will be unified with term
-that matches the pattern on the right of the colon.  The program will print,
+    let %Foo = Foo(1,2).
+Notice the type pattern for the user defined type ``Foo`` in the ``let`` statement.
+
+Asteroid also supports conditional patterns.  Here is an example where we to make sure that the
+variable ``t`` on the left matches a pair of integer values,
 ::
-    (1,2)
+    let t if t is (%integer,%integer) = (1,2).
 
-Named patterns are a shorthand notation for conditional patterns; in this case,
+Of course, this ``let`` statement is going to be successful because the value on the right is indeed a
+pair of integers.  This kind of conditional pattern appears so often in Asteroid code that
+Asteroid has a shorthand notation for this,
 ::
-    let t if t is (x,y) = (1,2).
+    let t:(%integer,%integer) = (1,2).
+
+Again, here the ``let`` statement is only successful if ``t`` matches a pair of integers.
 
-We can combine type patterns and named patterns to give us something that looks
-like a variable declaration in other languages. In Asteroid, though, it is still just all
+Shorthand conditional patterns often look
+like a variable declarations in other languages. In Asteroid, though, it is still just all
 about pattern matching.  Consider,
 ::
     load system io.
@@ -390,10 +403,9 @@ about pattern matching.  Consider,
 
     let x:%real = math @pi.
     io @println x.
-The left side of the ``let`` statement is a named type pattern that matches any real value, and
-if that match is successful then the value is bound to the variable ``x``.  Note
-that even though this looks like a declaration, it is in fact a pattern matching
-operation.  The program will print the value ``3.141592653589793``.
+The left side of the ``let`` statement is a conditional pattern that matches any real value, and
+if that match is successful then the value is bound to the variable ``x``.
+The program will print the value ``3.141592653589793``.
 
 Beware of the fact that even though the ``let`` statement above looks like a
 declaration of a real variable it is not; it is a pattern match statement enforcing that the
@@ -446,7 +458,7 @@ The output is,
     the third bird is a chicken
 
 In the loop we first create a list of pairs using the ``zip`` function, over which we then
-iterate pattern matching on each of the pairs on the list with the pattern ``(ix,bird)``.
+iterate while pattern matching on each of the pairs on the list with the pattern ``(ix,bird)``.
 
 The following is a short program that demonstrates an ``if`` statement,
 ::
@@ -502,8 +514,8 @@ In Asteroid functions are multi-dispatch, that is,
 a single function can have multiple bodies each attached to a different pattern
 matching the actual argument.
 The following is the quick sort implemented in
-Asteroid where each ``with`` clause introduces a new function body with its
-corresponding pattern,
+Asteroid where each ``with`` clause introduces a new pattern with its
+corresponding function body,
 ::
     load system io.
 
@@ -537,7 +549,7 @@ The output is as expected,
 Notice that we use the multi-dispatch mechanism to deal with the base cases in the first two ``with`` clauses.
 In the third ``with`` clause we use the pattern ``[pivot|rest]`` to match the input list.
 Here the variable ``pivot`` matches the first element of the list, and the variable ``rest`` matches the remaining list. This remaining list is the original list with its first element removed.
-The function body then implements the pretty much standard recursive definition of the
+The function body then implements the pretty much standard definition of the
 quick sort.  Just keep in mind that function calls are expressed via juxtaposition
 of function name and actual argument; no parentheses necessary.
 
@@ -562,6 +574,10 @@ Pattern Matching in Expressions: The Is Predicate
 
 We can also have pattern matching
 in expressions using the ``is`` predicate.
+The
+left operand of the ``is`` predicate is a term and
+the right operand is a pattern.
+If the pattern match succeeds the predicate will return ``true`` otherwise it will return ``false``.
 Consider the following example,
 ::
     load system io.
@@ -587,9 +603,7 @@ be used.  That means we can use the predicate also on the right side of ``let``
 
     let true = (1,2) is (1,2).
 
-This is kind of strange looking but it succeeds.  Here the
-left operand of the ``is`` predicate is a term and
-the right operand is a pattern.  Obviously this pattern match will succeed because the
+This is kind of strange looking but it succeeds.    Obviously this pattern match will succeed because the
 term and the pattern look identical.  The return value of the ``is`` predicate is then
 pattern matched against the ``true`` pattern on the left of the ``=`` symbol.
 
@@ -866,21 +880,21 @@ Here is the program listing for the example in Asteroid,
    for (Dog(name,tricks) if tostring tricks is ".*fetch.*") in dogs do
       io @println (name+" knows how to fetch").
    end
-After declaring the structure we instantiate the dogs with their
-respective trick repertoires and put them on a list.  The last couple of lines
-of the program consist of a ``for`` loop over a list of our dogs.
+After declaring the structure, we instantiate the dogs with their
+respective trick repertoires and we then put them on a list.  The last couple of lines
+of the program consist of a ``for`` loop over the list of our dogs.
 The ``for`` loop is interesting
 because here we use structural, conditional, and regular expression pattern
 matching in order to only select the dogs that know how to do ``fetch`` from
 the list of dogs.  The pattern is,
 ::
-    Dog(name,tricks) if type @tostring tricks is ".*fetch.*"
+    Dog(name,tricks) if tostring tricks is ".*fetch.*"
 
 The structural part of the pattern is ``Dog(name,tricks)`` which simply matches
 any dog instance on the list.  However, that match is only successful if
 the conditional part of the pattern holds,
 ::
-    if type @tostring tricks is ".*fetch.*"
+    if tostring tricks is ".*fetch.*"
 
 This condition only succeeds if the ``tricks`` list viewed as a string matches
 the regular expression ``".*fetch.*"``. That is, if the list contains the word ``fetch``.
@@ -939,17 +953,17 @@ difficult to read.
 
 We can express the same function with a first-class pattern,
 ::
-    let TP = pattern q if (q is %boolean) or
+    let tp = pattern q if (q is %boolean) or
                           (q is %integer) or
                           (q is %string).
 
-    function foo with (x:*TP,y) do
+    function foo with (x:*tp,y) do
         io @println (x,y).
     end
 
 It is clear now that the main input structure to the function is a pair and the
 conditional type restriction pattern has been relegated to a subpattern stored in the variable
-``TP``.
+``tp``.
 
 Pattern Reuse
 ^^^^^^^^^^^^^
@@ -980,94 +994,94 @@ In order to write these two functions we had to repeat the almost identical patt
 four times.  First-class patterns allow us to write the same two functions in a
 much more elegant way,
 ::
-    let POS_INT = pattern (x:%integer) if x > 0.
-    let NEG_INT = pattern (x:%integer) if x < 0.
+    let pos_int = pattern (x:%integer) if x > 0.
+    let neg_int = pattern (x:%integer) if x < 0.
 
     function fact
         with 0 do
             return 1
-        with n:*POS_INT do
+        with n:*pos_int do
             return n * fact (n-1).
-        with *NEG_INT do
+        with *neg_int do
             throw Error("fact undefined for negative values").
     end
 
     function sign
         with 0 do
             return 1
-        with *POS_INT do
+        with *pos_int do
             return 1.
-        with *NEG_INT do
+        with *neg_int do
             return -1.
     end
-The relevant patterns are now stored in the variables ``POS_INT`` and ``NEG_INT``
+The relevant patterns are now stored in the variables ``pos_int`` and ``neg_int``
 which are then used in the function definitions.
 
-Constraint Patterns
-^^^^^^^^^^^^^^^^^^^
+Patterns as Constraints
+^^^^^^^^^^^^^^^^^^^^^^^
 
 Sometimes we want to use patterns as constraints on other patterns.  Consider
-the following (somewhat artificial) example,
+the following example,
 ::
 
-   let x: (v if (v is %integer) and v > 0) = some_value.
+   let x: v if (v is %integer) and (v > 0) = some_value.
 
-Here we want to use the pattern ``v if (v is %integer) and v > 0`` purely as a constraint
+Here we want to use the pattern ``v if (v is %integer) and (v > 0)`` purely as a constraint
 on the pattern ``x`` in the sense that we want a match on ``x`` only to succeed
-if ``some_value`` is a positive integer.  The problem is that this constraint pattern
+if the variable ``some_value`` holds a positive integer.  The problem is that this pattern
 introduces a spurious binding of the variable ``v`` into the current environment
-which might be undesirable due to variable name clashes.  Constraint patterns
-address this.  We can rewrite the above statement as follows,
+which might be undesirable due to variable name clashes.
+We can rewrite the above statement using the pattern scope operator ``%[...]%`` as follows,
 ::
 
-   let x: %[v if (v is %integer) and v > 0]% = some_value.
+   let x: %[v if (v is %integer) and (v > 0) ]% = some_value.
 
-By placing the pattern ``v if (v is %integer) and v > 0`` within the ``%[...]%``
-operators the pattern still functions as before but does not bind the variable ``v``
+By placing the pattern ``v if (v is %integer) and (v > 0)`` within the ``%[...]%``
+scope operator the pattern still functions as before but does not bind the variable ``v``
 into the current environment.
 
-The most common use of constraint patterns is the prevention of non-linear patterns
+The most common use of patterns as constraints is the prevention of non-linear patterns
 in functions.  Consider the following program,
 ::
    load system io.
 
-   let POS_INT = pattern %[v if (v is %integer) and v > 0]%.
+   let pos_int = pattern %[v if (v is %integer) and (v > 0)]%.
 
-   function add with (a:*POS_INT,b:*POS_INT) do
+   function add with (a:*pos_int,b:*pos_int) do
       return a+b.
    end
 
    io @println (add(1,2)).
-Without the ``%[...]%`` operators around the pattern ``v if (v is %integer) and v > 0``
+Without the ``%[...]%`` scope operator the pattern ``v if (v is %integer) and (v > 0)``
 the argument list pattern for the function
-``(a:*POS_INT,b:*POS_INT)`` would instantiate two instances of the variable ``v``
+``(a:*pos_int,b:*pos_int)`` would instantiate two instances of the variable ``v``
 leading to a non-linear pattern which is not supported by Asteroid.
-With the ``%[...]%`` operators in place we prevent
-the pattern ``v if (v is %integer) and v > 0`` from instantiating the variable ``v`` thus preventing a non-linearity
+With the ``%[...]%`` scope operator in place we prevent
+the pattern ``v if (v is %integer) and (v > 0)`` from instantiating the variable ``v`` thus preventing a non-linearity
 to occur in the argument list pattern.
 
-Sometimes we need to use constraint patterns instead of straightforward patterns
+Sometimes we need to use patterns as constraints instead of straightforward patterns
 in order to avoid non-linearities but
 we also want controlled access to the variables these constraint patterns declare.
 We achieve this by using the ``bind`` keyword at the pattern-match site.
 Consider the following program,
 ::
    -- declare a pattern that matches scalar values
-   let Scalar = pattern %[p if (p is %integer) or (p is %real)]%.
+   let scalar = pattern %[p if (p is %integer) or (p is %real)]%.
 
    -- declare a pattern that matches pairs of scalars
-   let Pair = pattern %[(x:*Scalar,y:*Scalar)]%.
+   let pair = pattern %[(x:*scalar,y:*scalar)]%.
 
    -- compute the dot product of two pairs of scalars
    function dot2d
-      with (*Pair bind [x as a1, y as a2], *Pair bind [x as b1, y as b2]) do
+      with (*pair bind [x as a1, y as a2], *pair bind [x as b1, y as b2]) do
          a1*b1 + a2*b2
    end
 
    assert(dot2d((1,0),(0,1)) == 0).
-In the function definition of ``dot2d`` we see that the ``Pair`` pattern is used
+In the function definition of ``dot2d`` we see that the ``pair`` pattern is used
 twice to make sure that the function is called with a pair of pairs as its argument.
-However, in order to compute the dot product of those two pairs we need access
+However, to compute the dot product of those two pairs we need access
 to the values each pair matched.  We use the ``bind`` keyword together with an
 appropriate binding term list to extract the matched values.  For the first
 pair we map ``x`` and ``y`` to ``a1`` and ``a2`` and for the second
@@ -1094,12 +1108,13 @@ The output is
 
     a + b = 3
 
-We can use the ``tostring`` function defined in the ``type`` module to provide some
+We can use the builtin ``tostring`` function to provide some
 additional formatting. The idea is that the ``tostring`` function takes a value to be turned into a string together with an optional ``stringformat`` formatting specifier object,
 ::
 
-    type @tostring(value[,type @stringformat(width spec[,precision spec])])
+    tostring(value[,stringformat(width spec[,precision spec])])
 
+Here the structures appearing in square brackets are optional.
 The width specifier tells the ``tostring`` function how many characters to reserve for the string conversion of the value.  If the value requires more characters than given in the width specifier then the width specifier is ignored.  If the width specifier is larger than than the number of characters required for the value then the value will be right justified.  For real values there is an optional precision specifier.
 
 Here is a program that exercises some of the string formatting options,
@@ -1149,8 +1164,8 @@ The output is,
     Hello Leo!
 
 
-We can use the type casting functions such as ``tointeger`` or ``toreal`` defined in the
-``type`` module to convert the string returned from ``input`` into a numeric value,
+We can use the builtin type casting functions such as ``tointeger`` or ``toreal``
+to convert the string returned from ``input`` into a numeric value,
 ::
     load system io.
 
@@ -1168,7 +1183,6 @@ The output is,
     3
 
 
-Finally, the function ``read`` reads from ``stdin`` and returns the input as a string.  The function ``write`` writes a string to ``stdout``.
 
 The Module System
 -----------------
@@ -1203,7 +1217,7 @@ Say that you wanted to load the ``math`` module so you could execute a certain t
     io @println("The sine of pi / 2 is " + tostring x + ".").
 Both the function ``sin`` and the constant value ``pi`` are defined in the ``math`` module.
 In addition, the ``io`` module is where all input/output functions in Asteroid (such as ``println``) come from.
-If you want the complete list of modules, make sure to check out the reference guide `here <https://asteroid-lang.readthedocs.io/en/latest/Reference%20Guide.html>`_.
+If you want the complete list of modules, make sure to check out the reference guide.
 
 
 More on Exceptions
@@ -1371,8 +1385,9 @@ written in Asteroid,
     io @println (collide(Asteroid(101), Spaceship(300))).
     io @println (collide(Asteroid(10), Spaceship(10))).
     io @println (collide(Spaceship(101), Spaceship(10))).
-Each ``with`` clause in the function ``collide_with`` introduces a new function body with its
-corresponding pattern.
+Each ``with`` clause in the function ``collide_with`` introduces a new pattern with its
+corresponding function body.
+Each pattern represents a different data type.  In this case different kinds of pairs.
 The function bodies in this case are simple ``return`` statements
 but they could be arbitrary computations.  The output of the program is,
 ::
diff --git a/docs/User Guide.txt b/docs/User Guide.txt
index 351bbc69..1e04b81a 100644
--- a/docs/User Guide.txt
+++ b/docs/User Guide.txt
@@ -31,7 +31,7 @@ paradigm with first-class patterns.  Here are just two examples:
 ::
 #include "../asteroid/test-suites/ug-programs/prgm-001.ast"
 
-that means the subject term ``[1,2,3]`` is matched to the pattern ``[x,2,y]`` and ``x`` and ``y`` are bound to the values 1 and 3, respectively.  By the way, there is nothing wrong with the following statement,
+that means the list ``[1,2,3]`` is matched to the pattern ``[x,2,y]`` and ``x`` and ``y`` are bound to the values 1 and 3, respectively.  By the way, there is nothing wrong with the following statement,
 ::
 #include "../asteroid/test-suites/ug-programs/prgm-002.ast"
 
@@ -45,7 +45,7 @@ in order to ensure that the domain of the function is not violated,
 #include "../asteroid/test-suites/ug-programs/prgm-003.ast"
 
 As you can see, the program first creates patterns and stores them in the variables
-``POS_INT`` and ``NEG_INT`` and it uses those patterns later in the code by
+``pos_int`` and ``neg_int`` and it uses those patterns later in the code by
 dereferencing those variables with the ``*`` operator.  First-class patterns have
 profound implications for software development in that pattern definition and usage
 points are now separate and patterns can be reused in different contexts.
@@ -58,7 +58,8 @@ with programming in Asteroid.
 The Basics
 ----------
 
-As with most programming languages we are familiar with, Asteroid has variables (alpha-numeric symbols starting with an alpha character) and constants.  Constants are available for all the primitive data types,
+As with most programming languages we are familiar with, Asteroid has variables (alpha-numeric symbols 
+starting with an alpha character) and constants.  Constants are available for all four primitive data types,
 
 * ``integer``, e.g. ``1024``
 * ``real``, e.g. ``1.75``
@@ -70,7 +71,13 @@ Asteroid also supports the built-in data types:
 * ``list``
 * ``tuple``
 
-These are structured data types in that they can contain entities that belong to other data types. Both of these data types have constructors which are possibly empty sequences of comma separated values enclosed by square brackets for lists, e.g. ``[1,2,3]``, and enclosed by parentheses for tuples, e.g. ``(x,y)``. For tuples we have the caveat that the 1-tuple is represented by a value followed by a comma to distinguish it from parenthesized expressions, e.g. ``(3,)`` the 1-tuple versus ``(3)`` the parenthesized expression.
+These are structured data types in that they can contain entities that belong to other data types. 
+Both of these data types have constructors which are sequences of comma separated values 
+enclosed by square brackets for lists, e.g. ``[1,2,3]``, and enclosed by parentheses for tuples, e.g. ``(x,y)``. 
+Lists are mutable structures in that we can add or delete elements.  On the other hand, tuples are immutable objects;
+once created you cannot change them.
+Furthermore, for tuples we have the caveat that the 1-tuple is represented by a value followed by a comma to distinguish it 
+from parenthesized expressions, e.g. ``(3,)`` the 1-tuple versus ``(3)`` the parenthesized expression.
 Here are some examples,
 ::
 #include "../asteroid/test-suites/ug-programs/prgm-005.ast"
@@ -79,8 +86,6 @@ As we said above, in order to distinguish it from a parenthesized value the sing
 ::
 #include "../asteroid/test-suites/ug-programs/prgm-006.ast"
 
-Lists are mutable objects whereas tuples are immutable.  
-
 We can cast lists and tuples to strings for easy printing,
 ::
 #include "../asteroid/test-suites/ug-programs/prgm-007.ast"
@@ -102,6 +107,11 @@ also have the types ``function`` and ``pattern``,
 ::
 #include "../asteroid/test-suites/ug-programs/prgm-008a.ast"
 
+Here is a small program demonstrating the ``pattern`` data type,
+::
+#include "../asteroid/test-suites/ug-programs/prgm-008c.ast"
+
+
 Data types in Asteroid do not form type hierarchies as in C/C++ and Java, for example.  
 Therefore, in mixed type arithmetic statements we have to explicitly convert data types as in,
 ::
@@ -122,8 +132,6 @@ elements of a list are accessed via the ``@`` operator,
 ::
 #include "../asteroid/test-suites/ug-programs/prgm-009.ast"
 
-The output is: ``[3,2,1]``.
-
 We can achieve the same effect by giving a list of index values (a slice) to the ``@`` operator,
 ::
 #include "../asteroid/test-suites/ug-programs/prgm-009a.ast"
@@ -170,7 +178,7 @@ where the output is,
 Tuples
 ^^^^^^
 
-As we saw earlier, the tuple is another fundamental, built-in data structure that can be found in Asteroid.
+The tuple is another fundamental, built-in data structure that can be found in Asteroid.
 Below is an example of a tuple declaration and access.
 ::
 #include "../asteroid/test-suites/ug-programs/prgm-014.ast"
@@ -179,7 +187,7 @@ Lists and tuples may be nested,
 ::
 #include "../asteroid/test-suites/ug-programs/prgm-015.ast"
 
-As we have mentioned earlier, unlike lists, tuples are immutable. This means that their contents cannot be changed once they have been declared.  The following program demonstrates this,
+Unlike lists, tuples are immutable. This means that their contents cannot be changed once they have been declared.  The following program demonstrates this,
 ::
 #include "../asteroid/test-suites/ug-programs/prgm-016.ast"
 
@@ -252,6 +260,7 @@ where we pattern match the pattern 1 on the left side to the value 1 on the righ
 
 Simple patterns are expressions that consist purely of constructors and variables. Constructors themselves consist of constants, list and tuple constructors, as well as user defined structures.
 The advantage of pattern matching is that it provides direct access to substructures of a particular value.
+This is often called "destructuring" of a value.
 Consider that we want to access the constituent values of the pair ``(1,2)``.  In a non-pattern-matching approach we would have to access each of these constituent values one-by-one,
 ::
     let p = (1,2).
@@ -266,47 +275,50 @@ the variables ``x`` and ``y`` where we expect our values to be,
     let (x,y) = p.
     assert (x==1 and y==2).
 
-Matching the pattern against the value ``(1,2)`` stored in ``p`` first matches the pair structure against the pair value and the matches the variables to the appropriate substructures.  Once the variables have been matched to value the ``let`` statement declares the variables in the current scope and they become available for computation.
+Matching the pattern against the value ``(1,2)`` stored in ``p`` first matches the pair structure against the pair value and then matches the variables to the appropriate substructures.  Once the variables have been matched to value the ``let`` statement declares the variables in the current scope and they become available for computation.
 
 The following is an example involving structures and objects,
 ::
 #include "../asteroid/test-suites/ug-programs/prgm-018.ast"
 
-We first construct an object ``joe`` with the first ``let`` statement and the use pattern matching to desctructure it with the second ``let`` statement binding its substructures to the variables ``n``, ``a``, and ``p``.
+We first construct an object ``joe`` with the first ``let`` statement and then use pattern matching to desctructure it with the second ``let`` statement binding its substructures to the variables ``n``, ``a``, and ``p``.
 
 Asteroid supports special patterns called type patterns that match any value
 of a given type.  For instance, the ``%integer`` pattern matches any integer value.  Here is a simple example,
 ::
 #include "../asteroid/test-suites/ug-programs/prgm-019.ast"
 
-This let statement succeeds because ``1`` is an integer value can be pattern-matched against
-the type pattern ``%integer``. 
-
-Asteroid also
-supports something called a named pattern were a (sub)pattern can be given a name
-and that name will be instantiated with a term during pattern matching.  For example,
+This ``let`` statement succeeds because ``1`` is an integer value that can be pattern-matched against
+the type pattern ``%integer``.  Type pattern exist for all builtin data types, ``%real`` and ``%list``.
+If you introduce a user defined type via a structure, then Asteroid will create a type pattern for all objects
+of that data type.  Here is a simple example,
 ::
-#include "../asteroid/test-suites/ug-programs/prgm-020.ast"
+#include "../asteroid/test-suites/ug-programs/prgm-019a.ast"
+
+Notice the type pattern for the user defined type ``Foo`` in the ``let`` statement.
 
-Here, the construct ``t:(x,y)`` is called a named pattern and the variable ``t`` will be unified with the term ``(1,2)``, or more generally, the variable will be unified with term
-that matches the pattern on the right of the colon.  The program will print,
+Asteroid also supports conditional patterns.  Here is an example where we to make sure that the
+variable ``t`` on the left matches a pair of integer values,
 ::
-    (1,2)
+    let t if t is (%integer,%integer) = (1,2).
 
-Named patterns are a shorthand notation for conditional patterns; in this case,
+Of course, this ``let`` statement is going to be successful because the value on the right is indeed a
+pair of integers.  This kind of conditional pattern appears so often in Asteroid code that 
+Asteroid has a shorthand notation for this,
 ::
-    let t if t is (x,y) = (1,2).
+    let t:(%integer,%integer) = (1,2).
+
+Again, here the ``let`` statement is only successful if ``t`` matches a pair of integers.
 
-We can combine type patterns and named patterns to give us something that looks
-like a variable declaration in other languages. In Asteroid, though, it is still just all
+Shorthand conditional patterns often look
+like a variable declarations in other languages. In Asteroid, though, it is still just all
 about pattern matching.  Consider,
 ::
 #include "../asteroid/test-suites/ug-programs/prgm-021.ast"
 
-The left side of the ``let`` statement is a named type pattern that matches any real value, and
-if that match is successful then the value is bound to the variable ``x``.  Note
-that even though this looks like a declaration, it is in fact a pattern matching
-operation.  The program will print the value ``3.141592653589793``.
+The left side of the ``let`` statement is a conditional pattern that matches any real value, and
+if that match is successful then the value is bound to the variable ``x``.  
+The program will print the value ``3.141592653589793``.
 
 Beware of the fact that even though the ``let`` statement above looks like a 
 declaration of a real variable it is not; it is a pattern match statement enforcing that the 
@@ -349,7 +361,7 @@ The output is,
     the third bird is a chicken
 
 In the loop we first create a list of pairs using the ``zip`` function, over which we then
-iterate pattern matching on each of the pairs on the list with the pattern ``(ix,bird)``.
+iterate while pattern matching on each of the pairs on the list with the pattern ``(ix,bird)``.
 
 The following is a short program that demonstrates an ``if`` statement,
 ::
@@ -385,8 +397,8 @@ In Asteroid functions are multi-dispatch, that is,
 a single function can have multiple bodies each attached to a different pattern
 matching the actual argument.
 The following is the quick sort implemented in
-Asteroid where each ``with`` clause introduces a new function body with its
-corresponding pattern,
+Asteroid where each ``with`` clause introduces a new pattern with its
+corresponding function body,
 ::
 #include "../asteroid/test-suites/ug-programs/prgm-026.ast"
 
@@ -398,7 +410,7 @@ The output is as expected,
 Notice that we use the multi-dispatch mechanism to deal with the base cases in the first two ``with`` clauses.
 In the third ``with`` clause we use the pattern ``[pivot|rest]`` to match the input list.
 Here the variable ``pivot`` matches the first element of the list, and the variable ``rest`` matches the remaining list. This remaining list is the original list with its first element removed.
-The function body then implements the pretty much standard recursive definition of the
+The function body then implements the pretty much standard definition of the
 quick sort.  Just keep in mind that function calls are expressed via juxtaposition
 of function name and actual argument; no parentheses necessary.
 
@@ -422,6 +434,10 @@ Pattern Matching in Expressions: The Is Predicate
 
 We can also have pattern matching
 in expressions using the ``is`` predicate.
+The
+left operand of the ``is`` predicate is a term and
+the right operand is a pattern.
+If the pattern match succeeds the predicate will return ``true`` otherwise it will return ``false``.
 Consider the following example,
 ::
 #include "../asteroid/test-suites/ug-programs/prgm-028.ast"
@@ -438,9 +454,7 @@ be used.  That means we can use the predicate also on the right side of ``let``
 
     let true = (1,2) is (1,2).
 
-This is kind of strange looking but it succeeds.  Here the
-left operand of the ``is`` predicate is a term and
-the right operand is a pattern.  Obviously this pattern match will succeed because the
+This is kind of strange looking but it succeeds.    Obviously this pattern match will succeed because the
 term and the pattern look identical.  The return value of the ``is`` predicate is then
 pattern matched against the ``true`` pattern on the left of the ``=`` symbol.
 
@@ -585,21 +599,21 @@ Here is the program listing for the example in Asteroid,
 ::
 #include "../asteroid/test-suites/ug-programs/prgm-037.ast"
 
-After declaring the structure we instantiate the dogs with their
-respective trick repertoires and put them on a list.  The last couple of lines
-of the program consist of a ``for`` loop over a list of our dogs.
+After declaring the structure, we instantiate the dogs with their
+respective trick repertoires and we then put them on a list.  The last couple of lines
+of the program consist of a ``for`` loop over the list of our dogs.
 The ``for`` loop is interesting
 because here we use structural, conditional, and regular expression pattern
 matching in order to only select the dogs that know how to do ``fetch`` from
 the list of dogs.  The pattern is,
 ::
-    Dog(name,tricks) if type @tostring tricks is ".*fetch.*"
+    Dog(name,tricks) if tostring tricks is ".*fetch.*"
 
 The structural part of the pattern is ``Dog(name,tricks)`` which simply matches
 any dog instance on the list.  However, that match is only successful if
 the conditional part of the pattern holds,
 ::
-    if type @tostring tricks is ".*fetch.*"
+    if tostring tricks is ".*fetch.*"
 
 This condition only succeeds if the ``tricks`` list viewed as a string matches
 the regular expression ``".*fetch.*"``. That is, if the list contains the word ``fetch``.
@@ -658,17 +672,17 @@ difficult to read.
 
 We can express the same function with a first-class pattern,
 ::
-    let TP = pattern q if (q is %boolean) or
+    let tp = pattern q if (q is %boolean) or
                           (q is %integer) or
                           (q is %string).
 
-    function foo with (x:*TP,y) do
+    function foo with (x:*tp,y) do
         io @println (x,y).
     end
 
 It is clear now that the main input structure to the function is a pair and the
 conditional type restriction pattern has been relegated to a subpattern stored in the variable
-``TP``.
+``tp``.
 
 Pattern Reuse
 ^^^^^^^^^^^^^
@@ -686,46 +700,46 @@ much more elegant way,
 ::
 #include "../asteroid/test-suites/ug-programs/prgm-039.ast"
 
-The relevant patterns are now stored in the variables ``POS_INT`` and ``NEG_INT``
+The relevant patterns are now stored in the variables ``pos_int`` and ``neg_int``
 which are then used in the function definitions.
 
-Constraint Patterns
-^^^^^^^^^^^^^^^^^^^
+Patterns as Constraints
+^^^^^^^^^^^^^^^^^^^^^^^
 
 Sometimes we want to use patterns as constraints on other patterns.  Consider
-the following (somewhat artificial) example,
+the following example,
 ::
 
-   let x: (v if (v is %integer) and v > 0) = some_value.
+   let x: v if (v is %integer) and (v > 0) = some_value.
 
-Here we want to use the pattern ``v if (v is %integer) and v > 0`` purely as a constraint
+Here we want to use the pattern ``v if (v is %integer) and (v > 0)`` purely as a constraint
 on the pattern ``x`` in the sense that we want a match on ``x`` only to succeed
-if ``some_value`` is a positive integer.  The problem is that this constraint pattern
+if the variable ``some_value`` holds a positive integer.  The problem is that this pattern
 introduces a spurious binding of the variable ``v`` into the current environment
-which might be undesirable due to variable name clashes.  Constraint patterns
-address this.  We can rewrite the above statement as follows,
+which might be undesirable due to variable name clashes.   
+We can rewrite the above statement using the pattern scope operator ``%[...]%`` as follows,
 ::
 
-   let x: %[v if (v is %integer) and v > 0]% = some_value.
+   let x: %[v if (v is %integer) and (v > 0) ]% = some_value.
 
-By placing the pattern ``v if (v is %integer) and v > 0`` within the ``%[...]%``
-operators the pattern still functions as before but does not bind the variable ``v``
+By placing the pattern ``v if (v is %integer) and (v > 0)`` within the ``%[...]%``
+scope operator the pattern still functions as before but does not bind the variable ``v``
 into the current environment.
 
-The most common use of constraint patterns is the prevention of non-linear patterns
+The most common use of patterns as constraints is the prevention of non-linear patterns
 in functions.  Consider the following program,
 ::
 #include "../asteroid/test-suites/ug-programs/prgm-043.ast"
 
-Without the ``%[...]%`` operators around the pattern ``v if (v is %integer) and v > 0``
+Without the ``%[...]%`` scope operator the pattern ``v if (v is %integer) and (v > 0)``
 the argument list pattern for the function
-``(a:*POS_INT,b:*POS_INT)`` would instantiate two instances of the variable ``v``
+``(a:*pos_int,b:*pos_int)`` would instantiate two instances of the variable ``v``
 leading to a non-linear pattern which is not supported by Asteroid.
-With the ``%[...]%`` operators in place we prevent
-the pattern ``v if (v is %integer) and v > 0`` from instantiating the variable ``v`` thus preventing a non-linearity
+With the ``%[...]%`` scope operator in place we prevent
+the pattern ``v if (v is %integer) and (v > 0)`` from instantiating the variable ``v`` thus preventing a non-linearity
 to occur in the argument list pattern.
 
-Sometimes we need to use constraint patterns instead of straightforward patterns
+Sometimes we need to use patterns as constraints instead of straightforward patterns
 in order to avoid non-linearities but
 we also want controlled access to the variables these constraint patterns declare.
 We achieve this by using the ``bind`` keyword at the pattern-match site.  
@@ -733,9 +747,9 @@ Consider the following program,
 ::
 #include "../asteroid/test-suites/ug-programs/prgm-043a.ast"
 
-In the function definition of ``dot2d`` we see that the ``Pair`` pattern is used 
+In the function definition of ``dot2d`` we see that the ``pair`` pattern is used 
 twice to make sure that the function is called with a pair of pairs as its argument.
-However, in order to compute the dot product of those two pairs we need access 
+However, to compute the dot product of those two pairs we need access 
 to the values each pair matched.  We use the ``bind`` keyword together with an 
 appropriate binding term list to extract the matched values.  For the first
 pair we map ``x`` and ``y`` to ``a1`` and ``a2`` and for the second 
@@ -759,12 +773,13 @@ The output is
 
     a + b = 3
 
-We can use the ``tostring`` function defined in the ``type`` module to provide some
+We can use the builtin ``tostring`` function to provide some
 additional formatting. The idea is that the ``tostring`` function takes a value to be turned into a string together with an optional ``stringformat`` formatting specifier object,
 ::
 
-    type @tostring(value[,type @stringformat(width spec[,precision spec])])
+    tostring(value[,stringformat(width spec[,precision spec])])
 
+Here the structures appearing in square brackets are optional.
 The width specifier tells the ``tostring`` function how many characters to reserve for the string conversion of the value.  If the value requires more characters than given in the width specifier then the width specifier is ignored.  If the width specifier is larger than than the number of characters required for the value then the value will be right justified.  For real values there is an optional precision specifier.
 
 Here is a program that exercises some of the string formatting options,
@@ -795,8 +810,8 @@ The output is,
     Hello Leo!
 
 
-We can use the type casting functions such as ``tointeger`` or ``toreal`` defined in the
-``type`` module to convert the string returned from ``input`` into a numeric value,
+We can use the builtin type casting functions such as ``tointeger`` or ``toreal``
+to convert the string returned from ``input`` into a numeric value,
 ::
 #include "../asteroid/test-suites/ug-programs/prgm-054.ast"
 
@@ -809,7 +824,6 @@ The output is,
     3
 
 
-Finally, the function ``read`` reads from ``stdin`` and returns the input as a string.  The function ``write`` writes a string to ``stdout``.
 
 The Module System
 -----------------
@@ -841,7 +855,7 @@ Say that you wanted to load the ``math`` module so you could execute a certain t
 
 Both the function ``sin`` and the constant value ``pi`` are defined in the ``math`` module.
 In addition, the ``io`` module is where all input/output functions in Asteroid (such as ``println``) come from.
-If you want the complete list of modules, make sure to check out the reference guide `here <https://asteroid-lang.readthedocs.io/en/latest/Reference%20Guide.html>`_.
+If you want the complete list of modules, make sure to check out the reference guide.
 
 
 More on Exceptions
@@ -936,8 +950,9 @@ written in Asteroid,
 ::
 #include "../asteroid/test-suites/ug-programs/prgm-044.ast"
 
-Each ``with`` clause in the function ``collide_with`` introduces a new function body with its
-corresponding pattern.
+Each ``with`` clause in the function ``collide_with`` introduces a new pattern with its
+corresponding function body.
+Each pattern represents a different data type.  In this case different kinds of pairs.
 The function bodies in this case are simple ``return`` statements
 but they could be arbitrary computations.  The output of the program is,
 ::


Test patch:
diff --git a/asteroid/test-suites/ug-programs/prgm-003.ast b/asteroid/test-suites/ug-programs/prgm-003.ast
index f3779ce0..8c25a17f 100644
--- a/asteroid/test-suites/ug-programs/prgm-003.ast
+++ b/asteroid/test-suites/ug-programs/prgm-003.ast
@@ -1,13 +1,13 @@
     -- define first-class patterns
-    let POS_INT = pattern (x:%integer) if x > 0.
-    let NEG_INT = pattern (x:%integer) if x < 0.
+    let pos_int = pattern (x:%integer) if x > 0.
+    let neg_int = pattern (x:%integer) if x < 0.
 
     -- define our factorial function
     function fact
         with 0 do
             return 1
-        with n:*POS_INT do            -- use first pattern
+        with n:*pos_int do            -- use first pattern
             return n * fact (n-1).
-        with n:*NEG_INT do            -- use second pattern
+        with n:*neg_int do            -- use second pattern
             throw Error("undefined for "+n).
         end
diff --git a/asteroid/test-suites/ug-programs/prgm-008c.ast b/asteroid/test-suites/ug-programs/prgm-008c.ast
new file mode 100644
index 00000000..5f33705e
--- /dev/null
+++ b/asteroid/test-suites/ug-programs/prgm-008c.ast
@@ -0,0 +1,7 @@
+   -- define a first-class pattern
+   let p = pattern (x:%integer) if x>0.
+
+   -- check the type of the value stored in p
+   assert (gettype(p) == "pattern").
+
+
diff --git a/asteroid/test-suites/ug-programs/prgm-009.ast b/asteroid/test-suites/ug-programs/prgm-009.ast
index 79ea85f1..790bf1b4 100644
--- a/asteroid/test-suites/ug-programs/prgm-009.ast
+++ b/asteroid/test-suites/ug-programs/prgm-009.ast
@@ -1,5 +1,3 @@
-    load system io.   
-
     let a = [1,2,3].          -- construct list a
     let b = [a@2, a@1, a@0].  -- reverse list a
-    io @println b.
+    assert (b == [3,2,1]).
diff --git a/asteroid/test-suites/ug-programs/prgm-009a.ast b/asteroid/test-suites/ug-programs/prgm-009a.ast
index 3b1d5253..37d12758 100644
--- a/asteroid/test-suites/ug-programs/prgm-009a.ast
+++ b/asteroid/test-suites/ug-programs/prgm-009a.ast
@@ -1,5 +1,3 @@
-    load system io.  
-
     let a = [1,2,3].     -- construct list a
     let b = a@[2,1,0].   -- reverse list a using slice [2,1,0]
-    io @println b.
+    assert (b == [3,2,1]).
diff --git a/asteroid/test-suites/ug-programs/prgm-019a.ast b/asteroid/test-suites/ug-programs/prgm-019a.ast
new file mode 100644
index 00000000..18e245a2
--- /dev/null
+++ b/asteroid/test-suites/ug-programs/prgm-019a.ast
@@ -0,0 +1,6 @@
+    structure Foo with
+        data a.
+        data b.
+    end
+
+    let %Foo = Foo(1,2).
diff --git a/asteroid/test-suites/ug-programs/prgm-039.ast b/asteroid/test-suites/ug-programs/prgm-039.ast
index 0ea8da05..36eb8d98 100644
--- a/asteroid/test-suites/ug-programs/prgm-039.ast
+++ b/asteroid/test-suites/ug-programs/prgm-039.ast
@@ -1,20 +1,20 @@
-    let POS_INT = pattern (x:%integer) if x > 0.
-    let NEG_INT = pattern (x:%integer) if x < 0.
+    let pos_int = pattern (x:%integer) if x > 0.
+    let neg_int = pattern (x:%integer) if x < 0.
 
     function fact
         with 0 do
             return 1
-        with n:*POS_INT do
+        with n:*pos_int do
             return n * fact (n-1).
-        with *NEG_INT do
+        with *neg_int do
             throw Error("fact undefined for negative values").
     end
 
     function sign
         with 0 do
             return 1
-        with *POS_INT do
+        with *pos_int do
             return 1.
-        with *NEG_INT do
+        with *neg_int do
             return -1.
     end
diff --git a/asteroid/test-suites/ug-programs/prgm-043.ast b/asteroid/test-suites/ug-programs/prgm-043.ast
index d85223e3..faca2aa9 100644
--- a/asteroid/test-suites/ug-programs/prgm-043.ast
+++ b/asteroid/test-suites/ug-programs/prgm-043.ast
@@ -1,8 +1,8 @@
    load system io.
 
-   let POS_INT = pattern %[v if (v is %integer) and v > 0]%.
+   let pos_int = pattern %[v if (v is %integer) and (v > 0)]%.
 
-   function add with (a:*POS_INT,b:*POS_INT) do
+   function add with (a:*pos_int,b:*pos_int) do
       return a+b.
    end
 
diff --git a/asteroid/test-suites/ug-programs/prgm-043a.ast b/asteroid/test-suites/ug-programs/prgm-043a.ast
index 20c09726..919faf8e 100644
--- a/asteroid/test-suites/ug-programs/prgm-043a.ast
+++ b/asteroid/test-suites/ug-programs/prgm-043a.ast
@@ -1,12 +1,12 @@
    -- declare a pattern that matches scalar values
-   let Scalar = pattern %[p if (p is %integer) or (p is %real)]%.
+   let scalar = pattern %[p if (p is %integer) or (p is %real)]%.
 
    -- declare a pattern that matches pairs of scalars
-   let Pair = pattern %[(x:*Scalar,y:*Scalar)]%.
+   let pair = pattern %[(x:*scalar,y:*scalar)]%.
 
    -- compute the dot product of two pairs of scalars
    function dot2d 
-      with (*Pair bind [x as a1, y as a2], *Pair bind [x as b1, y as b2]) do
+      with (*pair bind [x as a1, y as a2], *pair bind [x as b1, y as b2]) do
          a1*b1 + a2*b2
    end