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

Issue:
remove automatic type promotion
There is a fundamental issue in Asteroid where some computations work intuitively and others don't. Consider the following scenarios,
```
let x = 1 + 3.1.
```
This computation is successful by virtue of promoting the integer 1 to the real value 1.0 and then performing a floating point value addition.

However, in the next scenario the computation is not successful,
```
function add_real with (a:%real, b:%real) do
   a+b
end

let x = add_real (1, 3.1).  <<< error
```
Asteroid does not support type promotion during pattern matching, therefore, the above fails since the function expects a real value but is passed an integer in the first component of the pair.

This inconsistent behavior that in some instances type promotion is applied and in others not is confusing to the user.  Therefore I think it is best to remove automatic type promotion all together.  

PS:  I wonder if the Rust folks discovered the same thing and therefore did not implement automatic type promotion in Rust.



Discussion / hints:
Should this include `map2boolean`? or should we insist that logical expressions and loop conditions are expressed in true boolean constants?

Fix patch:
diff --git a/asteroid/modules/hash.ast b/asteroid/modules/hash.ast
index c57e3366..a119fe2c 100644
--- a/asteroid/modules/hash.ast
+++ b/asteroid/modules/hash.ast
@@ -5,7 +5,6 @@
 --
 -- (c) Lutz Hamel, University of Rhode Island
 ------------------------------------------------------------------
-load system type.
 
 ------------------------------------------------------------------
 structure __HASH__ with
@@ -121,7 +120,7 @@ end -- aslist
 function __str__
 ------------------------------------------------------------------
 with none do
-  return type @tostring (this @aslist ()).
+  return tostring (this @aslist ()).
 end -- __str__
 
 end -- __HASH__
diff --git a/asteroid/modules/io.ast b/asteroid/modules/io.ast
index 8a2fe0ff..de0e27c0 100644
--- a/asteroid/modules/io.ast
+++ b/asteroid/modules/io.ast
@@ -6,8 +6,6 @@
 -- (c) University of Rhode Island
 
 
-load system type.
-
 ------------------------------------------------------------------
 -- Basic file i/o
 ------------------------------------------------------------------
@@ -141,7 +139,7 @@ what_val = state.symbol_table.lookup_sym('what')
 
 (FOREIGN, f_val) = memory[0]
 
-f_val.write(what_val[1])
+f_val.write(term2string(what_val))
 "
 end
 
@@ -246,14 +244,14 @@ end
 function println
 ------------------------------------------------------------------
 with item do
-    this @writeln(type @tostring item).
+    this @writeln(tostring item).
 end
 
 ------------------------------------------------------------------
 function print
 ------------------------------------------------------------------
 with item do
-    this @write(type @tostring item).
+    this @write(tostring item).
 end
 
 ------------------------------------------------------------------
@@ -263,7 +261,7 @@ function input
 with none do
     return this @readln() @replace("\n","").
 with prompt do
-    this @write (type @tostring prompt).
+    this @write (tostring prompt).
     return this @readln() @replace("\n","").
 end
 
diff --git a/asteroid/modules/math.ast b/asteroid/modules/math.ast
index c8d32629..f4fcb4a9 100644
--- a/asteroid/modules/math.ast
+++ b/asteroid/modules/math.ast
@@ -227,22 +227,19 @@ end
 ------------------------------------------------------------------
 function mod
 ------------------------------------------------------------------
-with (v,d) do return escape
+-- only defined as a function over integers for now
+with (v:%integer,d:%integer) do return escape
 "
 global __retval__
-from asteroid.state import state
-from asteroid.support import promote
 
 val_v = state.symbol_table.lookup_sym('v')
 val_d = state.symbol_table.lookup_sym('d')
 
-if val_v[0] not in ['integer','real']:
-  raise ValueError('unsupported type \'{}\' for mod'.format(val_v[0]))
-
-if val_d[0] not in ['integer','real']:
-  raise ValueError('unsupported type \'{}\' for mod'.format(val_d[0]))
-
-__retval__ = (promote(val_v[0],val_d[0]),val_v[1] % val_d[1])
+__retval__ = ('integer',val_v[1] % val_d[1])
+"
+with _ do escape 
+"
+raise ValueError('unsupported type in \'mod\'')
 "
 end
 
diff --git a/asteroid/modules/prologue.ast b/asteroid/modules/prologue.ast
index 8f8ceef1..e2f88eda 100644
--- a/asteroid/modules/prologue.ast
+++ b/asteroid/modules/prologue.ast
@@ -147,6 +147,234 @@ with
       end
 end
 
+------------------------------------------------------------------
+let __TP__ = pattern
+------------------------------------------------------------------
+-- pattern for selecting proper formatting body in 'tostring'
+with x if (x is %boolean) or
+         (x is %integer) or
+         (x is %string).
+
+------------------------------------------------------------------
+structure __STRINGFORMAT__
+------------------------------------------------------------------
+-- formatting object for 'tostring'
+with
+  data length.
+  data precision.
+  data scientific.
+  function __init__
+    with (l:%integer,p:%integer,s:%boolean) do
+      let this @length = l.
+      let this @precision = p.
+      let this @scientific = s.
+    with (l:%integer,p:%integer) do
+      let this @length = l.
+      let this @precision = p.
+      let this @scientific = none.
+    with l:%integer do
+      let this @length = l.
+      let this @precision = none.
+      let this @scientific = none.
+    end
+end
+
+------------------------------------------------------------------
+-- TYPE CONVERSION FUNCTIONS --
+------------------------------------------------------------------
+
+------------------------------------------------------------------
+function tobase
+------------------------------------------------------------------
+-- represent the given integer x as a numeral in different bases
+with (x:%integer,base:%integer) do return escape
+"
+global __retval__
+
+x_val = state.symbol_table.lookup_sym('x')
+base_val = state.symbol_table.lookup_sym('base')
+
+if base_val[1] == 2:
+  __retval__ = ('string', format(x_val[1],'b'))
+elif base_val[1] == 8:
+  __retval__ = ('string', format(x_val[1],'o'))
+elif base_val[1] == 16:
+  __retval__ = ('string', format(x_val[1],'X'))
+else:
+  raise ValueError('illegal base value {}'
+          .format(base_val[1]))
+"
+end
+
+-- Note: we no longer support this, it encourages lazy programming
+-- by relying on the fuzzy concept of "truthiness"
+------------------------------------------------------------------
+-- function toboolean
+------------------------------------------------------------------
+-- with item do return escape
+-- "
+-- global __retval__
+--
+-- item_val = state.symbol_table.lookup_sym('item')
+-- __retval__ = ('boolean', bool(item_val[1]))
+-- "
+-- end
+
+------------------------------------------------------------------
+function tointeger
+------------------------------------------------------------------
+with (item:%string,base:%integer) do return escape
+"
+global __retval__
+item_val = state.symbol_table.lookup_sym('item')
+base_val = state.symbol_table.lookup_sym('base')
+__retval__ = ('integer', int(item_val[1], base=base_val[1]))
+"
+with item do return escape
+"
+global __retval__
+
+item_val = state.symbol_table.lookup_sym('item')
+__retval__ = ('integer', int(item_val[1]))
+"
+end
+
+------------------------------------------------------------------
+function toreal
+------------------------------------------------------------------
+with item do return escape
+"
+global __retval__
+
+item_val = state.symbol_table.lookup_sym('item')
+__retval__ = ('real', float(item_val[1]))
+"
+end
+
+------------------------------------------------------------------
+function tostring
+------------------------------------------------------------------
+-- convert an asteroid object to string.
+-- if format values are given apply the
+-- formatting to the object.
+
+with (v:*__TP__,__STRINGFORMAT__(w:%integer,none,none)) do
+  -- booleans, integers, and strings (see TP pattern) with width spec are
+  -- right justified. if width spec is too narrow it is ignored.
+  let vs = tostring v.
+  let padl = w - vs @length().
+  if padl > 0 do
+    return [1 to padl] @map(lambda with _ do return " ") @join("") + vs.
+  else do
+    return vs.
+  end
+with (v:%real,__STRINGFORMAT__(w:%integer,none,none)) do return escape
+-- floating point values with only a width spec are left justified with
+-- zero padding on the right.
+"
+global __retval__
+(V_TYPE, v_val) = state.symbol_table.lookup_sym('v')
+(W_TYPE, w_val) = state.symbol_table.lookup_sym('w')
+
+fmtstr = '{:'+str(w_val)+'f}'
+__retval__ = ('string', fmtstr.format(v_val))
+"
+-- floating point values with a width and precision specs
+-- are formatted according to Python formatting rules
+with (v:%real,__STRINGFORMAT__(w:%integer,p:%integer,none)) do return escape
+"
+global __retval__
+(V_TYPE, v_val) = state.symbol_table.lookup_sym('v')
+(W_TYPE, w_val) = state.symbol_table.lookup_sym('w')
+(P_TYPE, p_val) = state.symbol_table.lookup_sym('p')
+
+fmtstr = '{:'+str(w_val)+'.'+str(p_val)+'f}'
+__retval__ = ('string', fmtstr.format(v_val))
+"
+-- floating point values with width, precision and scientific notation specs
+-- are formatted according to Python formatting rules
+with (v:%real,__STRINGFORMAT__(w:%integer,p:%integer,s:%boolean)) do return escape
+"
+global __retval__
+(V_TYPE, v_val) = state.symbol_table.lookup_sym('v')
+(W_TYPE, w_val) = state.symbol_table.lookup_sym('w')
+(P_TYPE, p_val) = state.symbol_table.lookup_sym('p')
+(S_TYPE, s_val) = state.symbol_table.lookup_sym('s')
+
+fmtstr = '{:'+str(w_val)+'.'+str(p_val)+('e}' if s_val else 'f}')
+__retval__ = ('string', fmtstr.format(v_val))
+"
+with item do return escape
+-- default clause
+"
+global __retval__
+from asteroid.support import term2string
+
+item_val = state.symbol_table.lookup_sym('item')
+__retval__ = ('string', term2string(item_val))
+"
+end
+
+------------------------------------------------------------------
+function stringformat
+------------------------------------------------------------------
+-- a wrapper around our __STRINGFORMAT__ object as a member
+-- of our module.
+with (l:%integer,p:%integer,s:%boolean) do
+  return __STRINGFORMAT__(l,p,s).
+with (l:%integer,p:%integer) do
+  return __STRINGFORMAT__(l,p).
+with l:%integer do
+  return __STRINGFORMAT__(l).
+end
+
+------------------------------------------------------------------
+-- TYPE QUERY FUNCTIONS --
+------------------------------------------------------------------
+
+------------------------------------------------------------------
+function islist
+------------------------------------------------------------------
+with item do
+  return item is %list
+end
+
+------------------------------------------------------------------
+function isnone
+------------------------------------------------------------------
+with x do
+  return x is %none.
+end
+
+------------------------------------------------------------------
+function isscalar
+------------------------------------------------------------------
+with item do
+  return (item is %integer) or (item is %real).
+end
+
+------------------------------------------------------------------
+function gettype
+------------------------------------------------------------------
+-- get the type of 'x' as an Asteroid string
+with x do return escape
+"
+global __retval__
+val = state.symbol_table.lookup_sym('x')
+if val[0] == 'object':
+  (OBJECT, (STRUCT_ID, (ID, x_type)), OBJECT_MEMORY) = val
+elif val[0] in ['function-val','member-function-val']:
+  # internally we store functions as function values
+  # but to the user these look like functions as the 
+  # type counter part to the %function type pattern
+  # will match both function-val and member-function-val
+  x_type = 'function'
+else:
+  x_type = val[0]
+__retval__ = ('string', x_type)
+"
+end
+
 ------------------------------------------------------------------
 -- List member functions
 ------------------------------------------------------------------
@@ -467,7 +695,11 @@ function __list_filter__
 with f:%function do
     let out = [].
     for e in this do
-        let out = out+([e] if f(e) else []).
+        let r = f e.
+        if gettype r =/= "boolean" do 
+          escape "raise ValueError('list filter function has to return a Boolean')"
+        end
+        let out = out+([e] if r else []).
     end
     return out.
 end
@@ -704,10 +936,7 @@ startix_val = state.symbol_table.lookup_sym('startix')
 endix_val = state.symbol_table.lookup_sym('endix')
 
 val = this_val[1].find(item_val[1], startix_val[1], endix_val[1])
-if val == -1:
-    __retval__ = ('none', None)
-else:
-    __retval__ = ('integer', val)
+__retval__ = ('integer', val)
 "
 with (item:%string,loc(startix:%integer,none)) do return escape
 "
@@ -718,10 +947,7 @@ item_val = state.symbol_table.lookup_sym('item')
 startix_val = state.symbol_table.lookup_sym('startix')
 
 val = this_val[1].find(item_val[1], startix_val[1])
-if val == -1:
-    __retval__ = ('none', None)
-else:
-    __retval__ = ('integer',val)
+__retval__ = ('integer',val)
 "
 with item:%string do return escape
 "
@@ -731,10 +957,7 @@ this_val = state.symbol_table.lookup_sym('this')
 item_val = state.symbol_table.lookup_sym('item')
 
 val = this_val[1].find(item_val[1])
-if val == -1:
-    __retval__ = ('none', None)
-else:
-    __retval__ = ('integer',val)
+__retval__ = ('integer',val)
 "
 end
 
diff --git a/asteroid/modules/type.ast b/asteroid/modules/type.ast
deleted file mode 100644
index a943504c..00000000
--- a/asteroid/modules/type.ast
+++ /dev/null
@@ -1,242 +0,0 @@
-------------------------------------------------------------------
--- type.ast
---
--- type related functions and structures
---
--- (c) University of Rhode Island
-------------------------------------------------------------------
-
-------------------------------------------------------------------
-let __TP__ = pattern
-------------------------------------------------------------------
--- pattern for selecting proper formatting body in 'tostring'
-with x if (x is %boolean) or
-         (x is %integer) or
-         (x is %string).
-
-------------------------------------------------------------------
-structure __STRINGFORMAT__
-------------------------------------------------------------------
--- formatting object for 'tostring'
-with
-  data length.
-  data precision.
-  data scientific.
-  function __init__
-    with (l:%integer,p:%integer,s:%boolean) do
-      let this @length = l.
-      let this @precision = p.
-      let this @scientific = s.
-    with (l:%integer,p:%integer) do
-      let this @length = l.
-      let this @precision = p.
-      let this @scientific = none.
-    with l:%integer do
-      let this @length = l.
-      let this @precision = none.
-      let this @scientific = none.
-    end
-end
-
-
-------------------------------------------------------------------
-structure __TYPE_MODULE__ with
-
-------------------------------------------------------------------
--- TYPE CONVERSION FUNCTIONS --
-------------------------------------------------------------------
-
-------------------------------------------------------------------
-function tobase
-------------------------------------------------------------------
--- represent the given integer x as a numeral in different bases
-with (x:%integer,base:%integer) do return escape
-"
-global __retval__
-
-x_val = state.symbol_table.lookup_sym('x')
-base_val = state.symbol_table.lookup_sym('base')
-
-if base_val[1] == 2:
-  __retval__ = ('string', format(x_val[1],'b'))
-elif base_val[1] == 8:
-  __retval__ = ('string', format(x_val[1],'o'))
-elif base_val[1] == 16:
-  __retval__ = ('string', format(x_val[1],'X'))
-else:
-  raise ValueError('illegal base value {}'
-          .format(base_val[1]))
-"
-end
-
-------------------------------------------------------------------
-function toboolean
-------------------------------------------------------------------
-with item do return escape
-"
-global __retval__
-
-item_val = state.symbol_table.lookup_sym('item')
-__retval__ = ('boolean', bool(item_val[1]))
-"
-end
-
-------------------------------------------------------------------
-function tointeger
-------------------------------------------------------------------
-with (item:%string,base:%integer) do return escape
-"
-global __retval__
-item_val = state.symbol_table.lookup_sym('item')
-base_val = state.symbol_table.lookup_sym('base')
-__retval__ = ('integer', int(item_val[1], base=base_val[1]))
-"
-with item do return escape
-"
-global __retval__
-
-item_val = state.symbol_table.lookup_sym('item')
-__retval__ = ('integer', int(item_val[1]))
-"
-end
-
-------------------------------------------------------------------
-function toreal
-------------------------------------------------------------------
-with item do return escape
-"
-global __retval__
-
-item_val = state.symbol_table.lookup_sym('item')
-__retval__ = ('real', float(item_val[1]))
-"
-end
-
-------------------------------------------------------------------
-function tostring
-------------------------------------------------------------------
--- convert an asteroid object to string.
--- if format values are given apply the
--- formatting to the object.
-
-with (v:*__TP__,__STRINGFORMAT__(w:%integer,none,none)) do
-  -- booleans, integers, and strings (see TP pattern) with width spec are
-  -- right justified. if width spec is too narrow it is ignored.
-  let vs = this @tostring(v).
-  let padl = w - vs @length().
-  if padl > 0 do
-    return [1 to padl] @map(lambda with _ do return " ") @join("") + vs.
-  else do
-    return vs.
-  end
-with (v:%real,__STRINGFORMAT__(w:%integer,none,none)) do return escape
--- floating point values with only a width spec are left justified with
--- zero padding on the right.
-"
-global __retval__
-(V_TYPE, v_val) = state.symbol_table.lookup_sym('v')
-(W_TYPE, w_val) = state.symbol_table.lookup_sym('w')
-
-fmtstr = '{:'+str(w_val)+'f}'
-__retval__ = ('string', fmtstr.format(v_val))
-"
--- floating point values with a width and precision specs
--- are formatted according to Python formatting rules
-with (v:%real,__STRINGFORMAT__(w:%integer,p:%integer,none)) do return escape
-"
-global __retval__
-(V_TYPE, v_val) = state.symbol_table.lookup_sym('v')
-(W_TYPE, w_val) = state.symbol_table.lookup_sym('w')
-(P_TYPE, p_val) = state.symbol_table.lookup_sym('p')
-
-fmtstr = '{:'+str(w_val)+'.'+str(p_val)+'f}'
-__retval__ = ('string', fmtstr.format(v_val))
-"
--- floating point values with width, precision and scientific notation specs
--- are formatted according to Python formatting rules
-with (v:%real,__STRINGFORMAT__(w:%integer,p:%integer,s:%boolean)) do return escape
-"
-global __retval__
-(V_TYPE, v_val) = state.symbol_table.lookup_sym('v')
-(W_TYPE, w_val) = state.symbol_table.lookup_sym('w')
-(P_TYPE, p_val) = state.symbol_table.lookup_sym('p')
-(S_TYPE, s_val) = state.symbol_table.lookup_sym('s')
-
-fmtstr = '{:'+str(w_val)+'.'+str(p_val)+('e}' if s_val else 'f}')
-__retval__ = ('string', fmtstr.format(v_val))
-"
-with item do return escape
--- default clause
-"
-global __retval__
-from asteroid.support import term2string
-
-item_val = state.symbol_table.lookup_sym('item')
-__retval__ = ('string', term2string(item_val))
-"
-end
-
-------------------------------------------------------------------
-function stringformat
-------------------------------------------------------------------
--- a wrapper around our __STRINGFORMAT__ object as a member
--- of our module.
-with (l:%integer,p:%integer,s:%boolean) do
-  return __STRINGFORMAT__(l,p,s).
-with (l:%integer,p:%integer) do
-  return __STRINGFORMAT__(l,p).
-with l:%integer do
-  return __STRINGFORMAT__(l).
-end
-
-------------------------------------------------------------------
--- TYPE QUERY FUNCTIONS --
-------------------------------------------------------------------
-
-------------------------------------------------------------------
-function islist
-------------------------------------------------------------------
-with item do
-  return item is %list
-end
-
-------------------------------------------------------------------
-function isnone
-------------------------------------------------------------------
-with x do
-  return x is %none.
-end
-
-------------------------------------------------------------------
-function isscalar
-------------------------------------------------------------------
-with item do
-  return (item is %integer) or (item is %real).
-end
-
-------------------------------------------------------------------
-function gettype
-------------------------------------------------------------------
--- get the type of 'x' as an Asteroid string
-with x do return escape
-"
-global __retval__
-val = state.symbol_table.lookup_sym('x')
-if val[0] == 'object':
-  (OBJECT, (STRUCT_ID, (ID, x_type)), OBJECT_MEMORY) = val
-elif val[0] in ['function-val','member-function-val']:
-  # internally we store functions as function values
-  # but to the user these look like functions as the 
-  # type counter part to the %function type pattern
-  # will match both function-val and member-function-val
-  x_type = 'function'
-else:
-  x_type = val[0]
-__retval__ = ('string', x_type)
-"
-end
-
-end -- __TYPE_MODULE__
-
-------------------------------------------------------------------
-let type = __TYPE_MODULE__().
diff --git a/asteroid/modules/util.ast b/asteroid/modules/util.ast
index 7698a8ff..a3c8d9e7 100644
--- a/asteroid/modules/util.ast
+++ b/asteroid/modules/util.ast
@@ -6,8 +6,6 @@
 -- (c) University of Rhode Island
 ------------------------------------------------------------------
 
-load system type.
-
 ------------------------------------------------------------------
 structure __UTIL_MODULE__ 
 ------------------------------------------------------------------
@@ -85,7 +83,7 @@ end
 function sleep
 ------------------------------------------------------------------
 -- program sleep for secs seconds
-with secs if type @isscalar(secs) do escape
+with secs if isscalar secs do escape
 "
 from time import sleep
 secs_val = state.symbol_table.lookup_sym('secs')
diff --git a/asteroid/modules/vector.ast b/asteroid/modules/vector.ast
index 4d00802a..6e2120c1 100644
--- a/asteroid/modules/vector.ast
+++ b/asteroid/modules/vector.ast
@@ -7,7 +7,6 @@
 ------------------------------------------------------------------
 
 load system util.
-load system type.
 
 ------------------------------------------------------------------
 structure __VECTOR_MODULE__ with
@@ -45,12 +44,12 @@ with (f:%function,a:%list,b:%list) do
   end
   let v = util @zip(a,b).
   return v @map(f).
-with (f:%function,a:%list,b if type @isscalar(b)) do
+with (f:%function,a:%list,b if isscalar b) do
   -- promote b to a vector
   let bv = [1 to a @length()] @map(lambda with _ do return b).
   let v = util @zip(a,bv).
   return v @map(f).
-with (f:%function,a if type @isscalar(a),b:%list) do
+with (f:%function,a if isscalar a,b:%list) do
   -- promote a to a vector
   let av = [1 to b @length()] @map(lambda with _ do return a).
   let v = util @zip(av,b).
diff --git a/asteroid/support.py b/asteroid/support.py
index ac572540..bd2b4cbf 100644
--- a/asteroid/support.py
+++ b/asteroid/support.py
@@ -119,13 +119,8 @@ def promote(type1, type2):
         return 'list'
     elif type1 == 'tuple' and type2 == 'tuple':
         return 'tuple'
-    elif type1 == 'none' and type2 == 'none':
-        return 'none'
     else:
-        if type1 == type2:
-            raise ValueError("binary operation on type '{}' not supported".format(type1))
-        else:
-            raise ValueError("type '{}' and type '{}' are incompatible".format(type1, type2))
+        return 'none'
 
 ###########################################################################################
 # Asteroid uses truth values similar to Python's Pythonic truth values:
@@ -205,7 +200,8 @@ def data_ix_list(memory):
 
 def term2string(term):
     TYPE = term[0]
-
+    #lhh
+    #print(term)
     if TYPE == 'string':
         val = term[1]
         output_str = ""
diff --git a/asteroid/version.py b/asteroid/version.py
index 730a0b19..c72066d3 100644
--- a/asteroid/version.py
+++ b/asteroid/version.py
@@ -5,4 +5,4 @@
 # (c) University of Rhode Island
 ##########################################################################################
 
-VERSION = "2.0.1"
+VERSION = "2.0.1dev"
diff --git a/asteroid/walk.py b/asteroid/walk.py
index ef61cc9d..26e12b77 100644
--- a/asteroid/walk.py
+++ b/asteroid/walk.py
@@ -6,6 +6,7 @@
 
 from copy import deepcopy,copy
 from re import match as re_match
+from math import isclose
 
 from asteroid.globals import *
 from asteroid.support import *
@@ -179,7 +180,10 @@ def unify(term, pattern, unifying = True ):
         # unifiers if conditional was successful
         state.symbol_table.push_scope({})
         declare_unifiers(unify(term, pexp, unifying))
-        bool_val = map2boolean(walk(cond_exp))
+        bool_val = walk(cond_exp)
+        if bool_val[0] != 'boolean':
+            raise ValueError("found '{}' expected 'boolean' in conditional pattern"
+                             .format(bool_val[0]))
         # copy unifiers out of the temporary scope of the
         # if expression.
         unifiers = state.symbol_table.get_curr_scope("unifiers")
@@ -633,99 +637,238 @@ def handle_builtins(node):
         val_b = walk(bin_args[1])
 
         if opname == '__plus__':
-            type = promote(val_a[0], val_b[0])
-            if type in ['integer', 'real', 'list', 'boolean']:
-                return (type, val_a[1] + val_b[1])
-            elif type == 'string':
-                return (type, term2string(val_a) + term2string(val_b))
+            if val_a[0] in ['integer', 'real', 'list', 'string']:
+                if val_b[0] in ['integer', 'real', 'list', 'string']:
+                    if val_a[0]==val_b[0]:
+                        return (val_a[0], val_a[1] + val_b[1])
+                    else:
+                        type = promote(val_a[0], val_b[0])
+                        if type == None:
+                            raise ValueError(
+                                "operation '{} + {}' not supported"
+                                .format(val_a[0],val_b[0]))
+                        else:
+                            raise ValueError(
+                                "found '{} + {}' expected '{} + {}'"
+                                .format(val_a[0],val_b[0],type,type))
+                else:
+                    raise ValueError("unsupported type '{}' in '+'".format(val_b[0]))
             else:
-                raise ValueError("unsupported type '{}' in +".format(type))
+                raise ValueError("unsupported type '{}' in '+'".format(val_a[0]))
         elif opname == '__minus__':
-            type = promote(val_a[0], val_b[0])
-            if type in ['integer', 'real']:
-                return (type, val_a[1] - val_b[1])
+            if val_a[0] in ['integer', 'real']:
+                if val_b[0] in ['integer', 'real']:
+                    if val_a[0]==val_b[0]:
+                        return (val_a[0], val_a[1] - val_b[1])
+                    else:
+                        type = promote(val_a[0], val_b[0])
+                        if type == None:
+                            raise ValueError(
+                                "operation '{} - {}' not supported"
+                                .format(val_a[0],val_b[0]))
+                        else:
+                            raise ValueError(
+                                "found '{} - {}' expected '{} - {}'"
+                                .format(val_a[0],val_b[0],type,type))
+                else:
+                    raise ValueError("unsupported type '{}' in '-'".format(val_b[0]))
             else:
-                raise ValueError("unsupported type '{}' in -".format(type))
+                raise ValueError("unsupported type '{}' in '-'".format(val_a[0]))
         elif opname == '__times__':
-            type = promote(val_a[0], val_b[0])
-            if type in ['integer', 'real']:
-                return (type, val_a[1] * val_b[1])
+            if val_a[0] in ['integer', 'real']:
+                if val_b[0] in ['integer', 'real']:
+                    if val_a[0]==val_b[0]:
+                        return (val_a[0], val_a[1] * val_b[1])
+                    else:
+                        type = promote(val_a[0], val_b[0])
+                        if type == None:
+                            raise ValueError(
+                                "operation '{} * {}' not supported"
+                                .format(val_a[0],val_b[0]))
+                        else:
+                            raise ValueError(
+                                "found '{} * {}' expected '{} * {}'"
+                                .format(val_a[0],val_b[0],type,type))
+                else:
+                    raise ValueError("unsupported type '{}' in '*'".format(val_b[0]))
             else:
-                raise ValueError('unsupported type in *')
+                raise ValueError("unsupported type '{}' in '*'".format(val_a[0]))
         elif opname == '__divide__':
-            type = promote(val_a[0], val_b[0])
-            if type == 'integer':
-                return (type, int(val_a[1]) // int(val_b[1]))
-            elif type == 'real':
-                return ('real', float(val_a[1]) / float(val_b[1]))
+            if val_a[0] in ['integer', 'real']:
+                if val_b[0] in ['integer', 'real']:
+                    if val_a[0]==val_b[0]:
+                        if val_a[0] == 'integer':
+                            return ('integer', val_a[1] // val_b[1])
+                        elif val_a[0] == 'real':
+                            return ('real', val_a[1] / val_b[1])
+                    else:
+                        type = promote(val_a[0], val_b[0])
+                        if type == None:
+                            raise ValueError(
+                                "operation '{} / {}' not supported"
+                                .format(val_a[0],val_b[0]))
+                        else:
+                            raise ValueError(
+                                "found '{} / {}' expected '{} / {}'"
+                                .format(val_a[0],val_b[0],type,type))
+                else:
+                    raise ValueError("unsupported type '{}' in '/'".format(val_b[0]))
             else:
-                raise ValueError('unsupported type in /')
+                raise ValueError("unsupported type '{}' in '/'".format(val_a[0]))
         elif opname == '__or__':
-            # NOTE: do we need to typecheck here?
-            if map2boolean(val_a)[1] == True or map2boolean(val_b)[1] == True:
-               return ('boolean', True)
+            if val_a[0] == 'boolean' and val_b[0] == 'boolean':
+                return ('boolean', val_a[1] or val_b[1])
             else:
-               return ('boolean', False)
+                raise ValueError(
+                    "found '{} or {}' expected 'boolean or boolean'"
+                    .format(val_a[0],val_b[0]))
         elif opname == '__and__':
-            # NOTE: do we need to typecheck here?
-            if map2boolean(val_a)[1] == True and map2boolean(val_b)[1] == True:
-               return ('boolean', True)
+            if val_a[0] == 'boolean' and val_b[0] == 'boolean':
+                return ('boolean', val_a[1] and val_b[1])
             else:
-               return ('boolean', False)
+                raise ValueError(
+                    "found '{} and {}' expected 'boolean and boolean'"
+                    .format(val_a[0],val_b[0]))
         elif opname == '__eq__':
-            type = promote(val_a[0], val_b[0])
-            if type in ['integer', 'real', 'list', 'tuple', 'boolean', 'none']:
-                return ('boolean', val_a[1] == val_b[1])
-            elif type == 'string':
-                return ('boolean', term2string(val_a) == term2string(val_b))
+            if val_a[0] in ['integer', 'real', 'list', 'tuple', 'boolean', 'string', 'none']:
+                if val_b[0] in ['integer', 'real', 'list', 'tuple', 'boolean', 'string', 'none']:
+                    if val_a[0]==val_b[0]:
+                        if val_a[0] == 'real' and val_a[1] != val_b[1] and isclose(val_a[1],val_b[1]):
+                            warning("possible rounding error issue")
+                        return ('boolean', val_a[1] == val_b[1])
+                    else:
+                        type = promote(val_a[0], val_b[0])
+                        if type == None:
+                            raise ValueError(
+                                "operation '{} == {}' not supported"
+                                .format(val_a[0],val_b[0]))
+                        else:
+                            raise ValueError(
+                                "found '{} == {}' expected '{} == {}'"
+                                .format(val_a[0],val_b[0],type,type))
+                else:
+                    raise ValueError("unsupported type '{}' in '=='".format(val_b[0]))
             else:
-                raise ValueError('unsupported type in ==')
+                raise ValueError("unsupported type '{}' in '=='".format(val_a[0]))
         elif opname  == '__ne__':
-            type = promote(val_a[0], val_b[0])
-            if type in ['integer', 'real', 'list', 'tuple', 'boolean', 'none']:
-                return ('boolean', val_a[1] != val_b[1])
-            elif type == 'string':
-                return ('boolean', term2string(val_a) != term2string(val_b))
+            if val_a[0] in ['integer', 'real', 'list', 'tuple', 'boolean', 'string', 'none']:
+                if val_b[0] in ['integer', 'real', 'list', 'tuple', 'boolean', 'string', 'none']:
+                    if val_a[0]==val_b[0]:
+                        if val_a[0] == 'real' and val_a[1] != val_b[1] and isclose(val_a[1],val_b[1]):
+                            warning("possible rounding error issue")
+                        return ('boolean', val_a[1] != val_b[1])
+                    else:
+                        type = promote(val_a[0], val_b[0])
+                        if type == None:
+                            raise ValueError(
+                                "operation '{} =/= {}' not supported"
+                                .format(val_a[0],val_b[0]))
+                        else:
+                            raise ValueError(
+                                "found '{} =/= {}' expected '{} =/= {}'"
+                                .format(val_a[0],val_b[0],type,type))
+                else:
+                    raise ValueError("unsupported type '{}' in '=/='".format(val_b[0]))
             else:
-                raise ValueError('unsupported type in =/=')
+                raise ValueError("unsupported type '{}' in '=/='".format(val_a[0]))
         elif opname == '__le__':
-            type = promote(val_a[0], val_b[0])
-            if type in ['integer', 'real']:
-                return ('boolean', val_a[1] <= val_b[1])
+            if val_a[0] in ['integer', 'real', 'string']:
+                if val_b[0] in ['integer', 'real', 'string']:
+                    if val_a[0]==val_b[0]:
+                        if val_a[0] == 'real' and val_a[1] != val_b[1] and isclose(val_a[1],val_b[1]):
+                            warning("possible rounding error issue")
+                        return ('boolean', val_a[1] <= val_b[1])
+                    else:
+                        type = promote(val_a[0], val_b[0])
+                        if type == None:
+                            raise ValueError(
+                                "operation '{} <= {}' not supported"
+                                .format(val_a[0],val_b[0]))
+                        else:
+                            raise ValueError(
+                                "found '{} <= {}' expected '{} <= {}'"
+                                .format(val_a[0],val_b[0],type,type))
+                else:
+                    raise ValueError("unsupported type '{}' in '<='".format(val_b[0]))
             else:
-                raise ValueError('unsupported type in <=')
+                raise ValueError("unsupported type '{}' in '<='".format(val_a[0]))
         elif opname == '__lt__':
-            type = promote(val_a[0], val_b[0])
-            if type in ['integer', 'real']:
-                return ('boolean', val_a[1] < val_b[1])
+            if val_a[0] in ['integer', 'real', 'string']:
+                if val_b[0] in ['integer', 'real', 'string']:
+                    if val_a[0]==val_b[0]:
+                        if val_a[0] == 'real' and val_a[1] != val_b[1] and isclose(val_a[1],val_b[1]):
+                            warning("possible rounding error issue")
+                        return ('boolean', val_a[1] < val_b[1])
+                    else:
+                        type = promote(val_a[0], val_b[0])
+                        if type == None:
+                            raise ValueError(
+                                "operation '{} < {}' not supported"
+                                .format(val_a[0],val_b[0]))
+                        else:
+                            raise ValueError(
+                                "found '{} < {}' expected '{} < {}'"
+                                .format(val_a[0],val_b[0],type,type))
+                else:
+                    raise ValueError("unsupported type '{}' in '<'".format(val_b[0]))
             else:
-                raise ValueError('unsupported type in <')
+                raise ValueError("unsupported type '{}' in '<'".format(val_a[0]))
         elif opname == '__ge__':
-            type = promote(val_a[0], val_b[0])
-            if type in ['integer', 'real']:
-                return ('boolean', val_a[1] >= val_b[1])
+            if val_a[0] in ['integer', 'real', 'string']:
+                if val_b[0] in ['integer', 'real', 'string']:
+                    if val_a[0]==val_b[0]:
+                        if val_a[0] == 'real' and val_a[1] != val_b[1] and isclose(val_a[1],val_b[1]):
+                            warning("possible rounding error issue")
+                        return ('boolean', val_a[1] >= val_b[1])
+                    else:
+                        type = promote(val_a[0], val_b[0])
+                        if type == None:
+                            raise ValueError(
+                                "operation '{} >= {}' not supported"
+                                .format(val_a[0],val_b[0]))
+                        else:
+                            raise ValueError(
+                                "found '{} >= {}' expected '{} >= {}'"
+                                .format(val_a[0],val_b[0],type,type))
+                else:
+                    raise ValueError("unsupported type '{}' in '>='".format(val_b[0]))
             else:
-                raise ValueError('unsupported type in >=')
+                raise ValueError("unsupported type '{}' in '>='".format(val_a[0])) 
         elif opname == '__gt__':
-            type = promote(val_a[0], val_b[0])
-            if type in ['integer', 'real']:
-                return ('boolean', val_a[1] > val_b[1])
+            if val_a[0] in ['integer', 'real', 'string']:
+                if val_b[0] in ['integer', 'real', 'string']:
+                    if val_a[0]==val_b[0]:
+                        if val_a[0] == 'real' and val_a[1] != val_b[1] and isclose(val_a[1],val_b[1]):
+                            warning("possible rounding error issue")
+                        return ('boolean', val_a[1] > val_b[1])
+                    else:
+                        type = promote(val_a[0], val_b[0])
+                        if type == None:
+                            raise ValueError(
+                                "operation '{} > {}' not supported"
+                                .format(val_a[0],val_b[0]))
+                        else:
+                            raise ValueError(
+                                "found '{} > {}' expected '{} > {}'"
+                                .format(val_a[0],val_b[0],type,type))
+                else:
+                    raise ValueError("unsupported type '{}' in '>'".format(val_b[0]))
             else:
-                raise ValueError('unsupported type in >')
+                raise ValueError("unsupported type '{}' in '>'".format(val_a[0])) 
         else:
             raise ValueError("unknown builtin binary operation '{}'".format(opname))
 
     elif opname in unary_operators:
-        arg_val = walk(args)
-
+        arg_val = walk(args)             
         if opname == '__not__':
-            val = map2boolean(arg_val)
-            if val[1] == False:
-                return ('boolean', True)
-            elif val[1] == True:
-                return ('boolean', False)
+            if arg_val[0] == 'boolean':
+                if arg_val[1] == False:
+                    return ('boolean', True)
+                else:
+                    return ('boolean', False)
             else:
-                raise ValueError("not a boolean value in 'not'")
+                raise ValueError("found 'not {}' expected 'not boolean'"
+                                 .format(arg_val[0]))
         elif opname == '__uminus__':
             if arg_val[0] in ['integer', 'real']:
                 return (arg_val[0], - arg_val[1])
@@ -1115,10 +1258,16 @@ def while_stmt(node):
     try:
         stepping = debugger_has_stepped()
 
-        (COND_TYPE, cond_val) = map2boolean(walk(cond))
+        (cond_type, cond_val) = walk(cond)
+        if cond_type != 'boolean':
+            raise ValueError("found '{}' expected 'boolean' in while loop"
+                             .format(cond_type))
         while cond_val:
             walk_stmt_list(body, step_state=stepping)
-            (COND_TYPE, cond_val) = map2boolean(walk(cond))
+            (cond_type, cond_val) = walk(cond)
+            if cond_type != 'boolean':
+                raise ValueError("found '{}' expected 'boolean' in while loop"
+                                .format(cond_type))
     except Break:
         pass
 
@@ -1136,7 +1285,10 @@ def repeat_stmt(node):
         stepping = debugger_has_stepped()
         while True:
             walk_stmt_list(body, step_state=stepping)
-            (COND_TYPE, cond_val) = map2boolean(walk(cond))
+            (cond_type, cond_val) = walk(cond)
+            if cond_type != 'boolean':
+                raise ValueError("found '{}' expected 'boolean' in repeat loop"
+                                .format(cond_type))
             if cond_val:
                 break
 
@@ -1203,7 +1355,10 @@ def if_stmt(node):
          (COND, cond),
          (STMT_LIST, stmts)) = if_list[ i + 1 ]
 
-        (BOOLEAN, cond_val) = map2boolean(walk(cond))
+        (cond_type, cond_val) = walk(cond)
+        if cond_type != 'boolean':
+            raise ValueError("found '{}' expected 'boolean' in if clause"
+                            .format(cond_type))
 
         if cond_val:
             walk_stmt_list(stmts)
@@ -1515,8 +1670,10 @@ def if_exp(node):
     if else_exp[0] == 'null':
         raise ValueError("if expressions need an 'else' clause")
 
-    (BOOLEAN, cond_val) = map2boolean(walk(cond_exp))
-
+    (cond_type, cond_val) = walk(cond_exp)
+    if cond_type != 'boolean':
+        raise ValueError("found '{}' expected 'boolean' in if expression"
+                        .format(cond_type))
     if cond_val:
         return walk(then_exp)
     else:
diff --git a/docs/Asteroid in Action.rst b/docs/Asteroid in Action.rst
index 24152c0e..caaa390b 100644
--- a/docs/Asteroid in Action.rst
+++ b/docs/Asteroid in Action.rst
@@ -201,7 +201,7 @@ Challenge: Incrementing filenames
   let ext = ".txt".
 
   for i in 1 to 5 do
-      io @println (root+i+ext).
+      io @println (root + tostring i + ext).
   end
 Output::
 
@@ -220,7 +220,6 @@ Challenge: Random passwords
 In our solution we take advantage of Asteroid's ``Pick`` object.  The ``Pick`` object maintains a list of items that we can randomly select from using the ``pick`` member function.  As input to the ``Pick`` object, we compute a bunch of lists of characters that are useful for password construction.  The function ``achar`` converts a decimal ASCII code to a single character string.
 ::
   load system io.
-  load system type.
   load system util.
   load system pick.
   load system random.
@@ -228,7 +227,7 @@ In our solution we take advantage of Asteroid's ``Pick`` object.  The ``Pick`` o
   random @seed(42).
 
   -- make up lists of symbols useful for password construction
-  let int_list = [0 to 9] @map(type @tostring).
+  let int_list = [0 to 9] @map(tostring).
   let lc_list = [97 to 122] @map(util @achar). -- lower case characters
   let uc_list = [65 to 90] @map(util @achar). --upper case characters
   let sp_list = ["!","_","#","$","%","*"].
@@ -366,7 +365,7 @@ If there is only one file, then the phrase should be ``1 file found`` instead.
   load system io.
 
   for n in 0 to 5 do
-      io @println (n+" file"+("s " if n>1 or n==0 else " ")+"found").
+      io @println (tostring n + " file" + ("s " if n>1 or n==0 else " ") + "found").
   end
 Output::
 
@@ -427,7 +426,7 @@ In our solution we use a hash table to count the number of word occurences.
   -- put the words into a hash table, the value is the count of the words
   let ht = hash @hash().
   for w in wl do
-      if not ht @get(w) do
+      if ht @get(w) is none do
           ht @insert(w,1).
       else do
           ht @insert(w,ht @get(w)+1).
@@ -467,13 +466,13 @@ second string (``strb``).
   for startix in 0 to stra @length()-1 do
       for endix in startix to stra @length()-1 do
           let s = stra @[startix to endix].
-          if strb @index(s) and s @length() > common @length() do
+          if strb @index(s) =/= -1 and s @length() > common @length() do
               let common = s.
           end
       end
   end
 
-  if common do
+  if common =/= "" do
       io @println ("The longest common substring is '"+common+"'.").
   else do
       io @println ("There are no common substrings.").
@@ -711,7 +710,7 @@ We do this by finding and hashing N-grams after the appropriate preprocessing.
       -- Note: make this code more general
       let n_gram = [word_list@i, word_list@(i+1), word_list @(i+2)] @join(" ").
       -- put the N-gram into a hash table, the value is the count of the N-gram in the text.
-      if not ht @get(n_gram) do
+      if ht @get(n_gram) is none do
           ht @insert(n_gram,1).
       else do
           ht @insert(n_gram,ht @get(n_gram)+1).
@@ -719,7 +718,7 @@ We do this by finding and hashing N-grams after the appropriate preprocessing.
   end
 
   for ((n_gram,cnt) if cnt > 1) in ht @aslist() do
-      io @println (n_gram+": "+cnt).
+      io @println (n_gram+": "+ tostring cnt).
   end
 Output::
 
@@ -759,7 +758,7 @@ Other constants are also available.
   load system io.
   load system math.
 
-  let tau = 2 * math @pi.
+  let tau = 2.0 * math @pi.
 
   io @println (math @e).
   io @println tau.
@@ -812,7 +811,7 @@ the predicate applied to the input is true.  The last case is of some interest b
           throw Error("factorial is not defined for "+n).
       end
 
-  io @println ("The factorial of 3 is: " + fact (3)).
+  io @println ("The factorial of 3 is: " + tostring(fact 3)).
   assert (fact(3) == 6).
 Output::
 
@@ -956,7 +955,7 @@ Prime numbers are those that can be divided only by 1, and by themselves.
   function isprime with x do
       if x >= 2 do
           for y in range(2,x) do
-              if not math @mod(x,y) do
+              if math @mod(x,y) == 0 do
                   return false.
               end
           end
@@ -989,7 +988,7 @@ Challenge: List of prime numbers
   function isprime with x do
       if x >= 2 do
           for y in range(2,x) do
-              if not math @mod(x,y) do
+              if math @mod(x,y) == 0 do
                   return false.
               end
           end
@@ -1035,7 +1034,7 @@ Prime factors are the prime numbers that divide the given integer number exactly
   function isprime with x do
       if x >= 2 do
           for y in range(2,x) do
-              if not math @mod(x,y) do
+              if math @mod(x,y) == 0 do
                   return false.
               end
           end
@@ -1061,7 +1060,7 @@ Prime factors are the prime numbers that divide the given integer number exactly
   while n > 1 do
       let factor = primes_list @ix.
       let ix = ix+1.
-      if not math @mod(n,factor) do
+      if math @mod(n,factor) == 0 do
           let ix = 0.
           let n = n/factor.
           let factors = factors+[factor].
@@ -1141,7 +1140,6 @@ Asteroid has two random number generation functions: ``random()`` generates a ra
   load system io.
   load system random.
   load system util.
-  load system type.
 
   let randint = random @randint.
 
@@ -1153,7 +1151,7 @@ Asteroid has two random number generation functions: ``random()`` generates a ra
 
   -- generating a random number in the appropriate interval
   let n = 10.
-  io @println (randint(0.0,type @toreal(n))).
+  io @println (randint(0.0, toreal n)).
   io @println (randint(0,n)).
 Output:
 ::
@@ -1182,18 +1180,17 @@ To illustrate it with an example, let’s take the number 1234 as the seed. On s
 ::
   load system io.
   load system util.
-  load system type.
 
   let n = 1234.
   let sq = n*n.
-  let sq_str = type @tostring(sq).
+  let sq_str = tostring sq.
   if sq_str @length() < 8 do
       let prefix = [1 to 8-sq_str@length()] @map(lambda with _ do return "0")
                                             @join("").
       let sq_str = prefix + sq_str.
   end
   let rstr = sq_str @[2 to 5].
-  let rval = type @tointeger(rstr).
+  let rval = tointeger rstr.
   io @println rval.
 
   assert (rval == 5227)
@@ -1300,11 +1297,11 @@ where :math:`n` is the number of elements in the array :math:`x`; :math:`\bar{x}
 
   let values = [727.7, 1086.5, 1091.0, 1361.3, 1490.5, 1956.1].
 
-  let avg = values @reduce(lambda with (x,y) do return x+y) / values @length().
+  let avg = values @reduce(lambda with (x,y) do return x+y) / toreal(values @length()).
   let diff_sq = values @map(lambda with x do return math @pow(x-avg,2)).
   let numerator = diff_sq @reduce(lambda with (x,y) do return x+y).
   let denominator = values @length() -1.
-  let sigma = math @sqrt(numerator/denominator).
+  let sigma = math @sqrt(numerator/toreal denominator).
   io @println sigma.
 
   assert (sigma == 420.96248961952256)
@@ -1372,7 +1369,6 @@ All these variants can be implemented by using ``with`` clauses and conditional
   load system io.
   load system math.
   load system util.
-  load system type.
 
   -- define common math functions locally so the
   -- formulas are easy to read
@@ -1382,7 +1378,6 @@ All these variants can be implemented by using ``with`` clauses and conditional
   let pow = math @pow.
   let atan = math @atan.
   let pi = math @pi.
-  let toreal = type @toreal.
 
   function polar_to_cartesian with (r,psi) do
       -- return a tuple: (x,y)
@@ -1395,11 +1390,11 @@ All these variants can be implemented by using ``with`` clauses and conditional
 
   function cartesian_to_psi
       with (x,y) if x > 0  do
-          return atan(toreal(y)/x).
+          return atan(toreal y/toreal x).
       with (x,y) if x < 0 and y >= 0 do
-          return atan(toreal(y)/x)+pi.
+          return atan(toreal y/toreal x)+pi.
       with (x,y) if x < 0 and y < 0 do
-          return atan(toreal(y)/x)-pi.
+          return atan(toreal y/toreal x)-pi.
       with (x,y) if x == 0 and y > 0 do
           return pi/2.
       with (x,y) if x == 0 and y < 0 do
@@ -1449,7 +1444,7 @@ To calculate the area of a circle with a radius of 1, pairs of random numbers be
           let inside = inside+1.
       end
   end
-  let area = 4.0 * inside / n.
+  let area = 4.0 * toreal inside / toreal n.
   io @println area.
 
   assert (area == 3.1392).
@@ -1470,19 +1465,18 @@ ask for the initial guess and enter the loop, which compares the guess with the
   load system io.
   load system random.
   load system util.
-  load system type.
 
   random @seed(42).
 
   let n = random @randint(0,10).
-  let guess = type @tointeger(io @input("Guess my number between 0 and 10: ")).
+  let guess = tointeger(io @input("Guess my number between 0 and 10: ")).
   while guess =/= n do
       if guess < n do
           io @println "Too small.".
       elif guess > n  do
            io @println "Too big.".
       end
-      let guess = type @tointeger(io @input("Try again: ")).
+      let guess = tointeger(io @input("Try again: ")).
   end
   io @println "Yes, this is it!".
 Challenge: Binary to integer
@@ -1493,10 +1487,9 @@ Challenge: Binary to integer
 In Asteroid this is straightforward using the built-in ``tointeger`` function, passing it a string representation of the binary number and the base.
 ::
   load system io.
-  load system type.
 
   let bin = "101101".
-  let int = type @tointeger(bin,2).
+  let int = tointeger(bin,2).
   io @println int.
 
   assert (int == 45).
@@ -1514,10 +1507,6 @@ Challenge: Integer as binary, octal, and hex
 In Asteroid this is easily done with the ``tobase`` function.
 ::
   load system io.
-  load system type.
-
-  let tobase = type @tobase.
-  let tointeger = type @tointeger.
 
   let val = 42.
 
@@ -1545,14 +1534,13 @@ Challenge: Sum of digits
 Pretty straightforward using string and list manipulation.
 ::
   load system io.
-  load system type.
 
   let number = 139487854.
 
 
-  let s = type @tostring number @explode()
-                                @map(type @tointeger)
-                                @reduce(lambda with (x,y) do return x+y).
+  let s = tostring number @explode()
+                          @map tointeger
+                          @reduce (lambda with (x,y) do x+y).
   io @println s.
 
   assert (s == 49).
@@ -1590,9 +1578,8 @@ Challenge: Compose the largest number
 The easiest way to achieve that is to treat the numbers as strings, sort them alphabetically in descending order, concatenate the pieces to a single string, and get the resulting integer.
 ::
   load system io.
-  load system type.
 
-  let a = type @tointeger([67, 8, 1, 5, 45] @map(type @tostring) @sort(true) @join("")).
+  let a = tointeger ([67, 8, 1, 5, 45] @map tostring @sort true @join "").
   io @println a.
 
   assert (a == 8675451).
@@ -1617,7 +1604,6 @@ In the program below, there are four such sequences: for thousands, hundreds, te
   load system math.
   load system util.
   load system hash.
-  load system type.
 
   let roman_hash = hash @hash().
   roman_hash @insert(1000,["","M","MM","MMM"]).
@@ -1626,11 +1612,11 @@ In the program below, there are four such sequences: for thousands, hundreds, te
   roman_hash @insert(1,["","I","II","III","IV","V","VI","VII","VIII","IX"]).
 
   let n = 2018.
-  let p10 = range(type @tostring n @length()) @map(lambda with x do return math @pow(10,x))
-                                              @reverse().
-  let digits = type @tostring n @explode()
-                                @map(type @tointeger).
-  let z = util @zip(digits, p10).
+  let p10 = range(tostring n @length()) @map(lambda with x do math @pow (10,x))
+                                        @reverse().
+  let digits = tostring n @explode ()
+                          @map tointeger.
+  let z = util @zip (digits, p10).
   io @println z.
   let roman = "".
   for (d,p) in z do
@@ -1680,7 +1666,7 @@ The zero name appears only in the case when the given number is zero.
           return names @n.
       with (n:%integer) if n < 100 do
           let r = names @(n / 10 + 18).
-          let r = r + ("-" + names @(mod(n,10))) if mod(n,10) else "".
+          let r = r + ("-" + names @(mod(n,10))) if mod(n,10) =/= 0 else "".
           return r.
       with (n:%integer) if n < 1000 do
           return spell_part(n,100,"hundred").
@@ -1691,7 +1677,7 @@ The zero name appears only in the case when the given number is zero.
   function spell_part
       with (n:%integer,base:%integer,name:%string) do
           let r = spell_number(n/base) + " " + name.
-          return r + " " + spell_number(mod(n,base)) if mod(n,base) else r.
+          return r + " " + spell_number(mod(n,base)) if mod(n,base) =/= 0 else r.
       end
 
   io @println (spell_number 15).
@@ -1726,7 +1712,7 @@ Consider the complete program:
 
   let (a,b) = (10,20).
   let (b,a) = (a,b).
-  io @println ("a = "+a,"b = "+b).
+  io @println ("a = "+ tostring a,"b = "+ tostring b).
 
   assert ((a,b) is (20,10)).
 Output:
@@ -1993,7 +1979,9 @@ Challenge: Is an element in a list?
 
   let array = [10, 14, 0, 15, 17, 20, 30, 35].
   let x = 17.
-  io @println ((x+" is in the list") if array @member(x) else (x+" is not in the list")).
+  io @println ((tostring x +" is in the list")
+          if array @member x
+          else (tostring x + " is not in the list")).
 Output:
 ::
 
@@ -2007,10 +1995,10 @@ We can also use a reduction function to solve this,
   let array = [10, 14, 0, 15, 17, 20, 30, 35].
   let x = 17.
 
-  if array @reduce(lambda with (acc,i) do return true if i==x else acc,false) do
-      io @println (x+" is in the list").
+  if array @reduce(lambda with (acc,i) do true if i==x else acc,false) do
+      io @println (tostring x + " is in the list").
   else
-      io @println (x+" is not in the list").
+      io @println (tostring x + " is not in the list").
   end
 Output:
 ::
@@ -2028,12 +2016,11 @@ The easiest way to do this is with a reduction,
   load system io.
   load system math.
   load system util.
-  load system type.
 
   let mod = math @mod.
 
   let array = [2, 4, 18, 9, 16, 7, 10].
-  let odd = array @reduce(lambda with (acc,i) do return i if type @isnone(acc) and mod(i,2) else acc,none).
+  let odd = array @reduce (lambda with (acc,i) do i if isnone acc and mod(i,2) =/= 0 else acc,none).
   io @println odd.
 Output:
 ::
@@ -2049,7 +2036,7 @@ Challenge: Take every second element
   load system io.
   load system math.
 
-  let array = [20 to 30] @filter(lambda with x do return math @mod(x,2)).
+  let array = [20 to 30] @filter(lambda with x do math @mod(x,2)=/=0).
   io @println array.
 
   assert (array == [21,23,25,27,29]).
@@ -2166,14 +2153,13 @@ Challenge: Increasing sequences
 > Check if the given array contains increasing (or decreasing) numbers.
 ::
   load system io.
-  load system type.
 
   let a = [3, 7, 19, 20, 34].
-  let b = type @toboolean(a @reduce(lambda with (x,y) do return y if x<y else false)).
+  let b = a @reduce(lambda with ((_,x),y) do (true,y) if x<=y else (false,y),(true,a@0)).
 
-  io @println b.
+  io @println (b@0).
 
-  assert (b).
+  assert (b@0).
 Output:
 ::
 
@@ -2242,7 +2228,7 @@ The procedure:
       io @println "".
       for r in m do
           for e in r do
-              io @print (e + " ").
+              io @print (tostring e + " ").
           end
           io @println ("").
       end
@@ -2369,7 +2355,7 @@ For example, a hash is a collection mapping a car’s license plate to the colou
 
   let color_hash = hash @hash().
   for (_,color) in fruit_lst do
-      if not color_hash @get(color) do
+      if color_hash @get(color) is none do
           color_hash @insert(color,1).
       else
           color_hash @insert(color, color_hash @get(color) +1).
@@ -2396,16 +2382,15 @@ Challenge: Product table
 We will do this with an outer loop  and a ``map`` function.
 ::
   load system io.
-  load system type.
 
   function format with v do
       let maxlen = 3.
-      let vstr = type @tostring v.
-      return [1 to maxlen-len(vstr)] @map(lambda with _ do return " ") @join("") + vstr.
+      let vstr = tostring v.
+      return [1 to maxlen-len(vstr)] @map(lambda with _ do " ") @join("") + vstr.
   end
 
   for i in 1 to 10 do
-      io @println ([1 to 10] @map(lambda with x do return format(i*x)) @join(" ")).
+      io @println ([1 to 10] @map(lambda with x do format(i*x)) @join(" ")).
   end
 Output:
 ::
@@ -2472,7 +2457,6 @@ The only thing that is left to do is to iterate appropiately and format the outp
   load system io.
   load system vector.
   load system util.
-  load system type.
 
   let triangle = [[1]].
   let ix = 0.
@@ -2487,7 +2471,7 @@ The only thing that is left to do is to iterate appropiately and format the outp
   end
 
   for r in triangle do
-      io @println (r @map(lambda with v do return type @tostring v) @join(" ")).
+      io @println (r @map(lambda with v do tostring v) @join(" ")).
   end
 Output:
 ::
diff --git a/docs/Reference Guide.rst b/docs/Reference Guide.rst
index b4a9d2f8..1ea8c117 100644
--- a/docs/Reference Guide.rst
+++ b/docs/Reference Guide.rst
@@ -832,6 +832,9 @@ Builtin Functions
 **getid** x
       Returns a unique id of any Asteroid object as an integer.
 
+**gettype** x
+      Returns the type of x as a string.
+
 **hd** x:%list
       Returns the first element of a list. It is an error to apply this
       function to an empty list.
@@ -839,6 +842,15 @@ Builtin Functions
 **isdefined** x:%string
       Returns true if a variable or type name is defined in the
       current environment otherwise it returns false. The variable or type name must be given as a string.
+**islist** x
+      Returns true if x is a list otherwise it will return false.
+
+**isnone** x
+      Returns true if x is equal to the value none.
+
+**isscalar** x
+      Returns true if x is either an integer or a real value.
+
 **len** x
       Returns the length of x. The
       function can only be applied to lists, strings, tuples, or structures.
@@ -854,6 +866,22 @@ Builtin Functions
       Returns the rest of the list without the first element.  It is an
       error to apply this function to an empty list.
 
+**tobase** (x:%integer,base:%integer)
+      Represents the given integer x as a numeral string in different bases.
+
+**toboolean** x
+      Interpret x as a Boolean value.
+
+**tointeger** (x:%string,base:%integer) | x
+      Converts a given input to an integer. If a base value is specified then
+      the resulting integer is in the corresponding base.
+
+**toreal** x
+      Returns the input as a real number.
+
+**tostring** x | (x,stringformat(width:%integer,precision:%integer,scientific:%boolean))
+      Converts an Asteroid object to a string. If format values are given,
+      it applies the formatting to the string object.
 
 
 List and String Objects
@@ -971,7 +999,7 @@ string **@flip** ()
       Returns a copy of the string with its characters in the reverse order.
 
 string **@index** item:%string | (item:%string, loc(startix:%integer)) | (item:%string, loc(startix:%integer, endix:%integer))
-      Returns an integer index of the item in the string or none if item was not found.
+      Returns an integer index of the item in the string or -1 if item was not found.
       The  argument loc allows you to specify startix and endix and are used to limit the search
       to a particular substring of the string. The returned index is computed relative to the beginning
       of the full string rather than the startix.
@@ -1144,8 +1172,8 @@ An example:
     load system io.
     load system math.
 
-    let x = math @sin( math @pi / 2 ).
-    io @println("The sine of pi / 2 is " + x + ".").
+    let x = math @sin( math @pi / 2.0 ).
+    io @println("The sine of pi / 2 is " + tostring x + ".").
 Constants
 %%%%%%%%%
 
@@ -1500,7 +1528,7 @@ A simple use case:
 
    let s = stream @stream [1 to 10].
    while not s @eof() do
-      io @print (s @get() + " ").
+      io @print (tostring (s @get()) + " ").
    end
    io @println "".
 which outputs::
@@ -1532,85 +1560,7 @@ __STREAM__ **@rewind** ()
       Resets the stream pointer to the first element of the stream.
 
 
-type
-^^^^
-
-The type module defines type related functions and structures.
-Here is a program that exercises some of the string formatting options:
-::
-    load system io.
-    load system type.
-    load system math.
-
-    -- if the width specifier is larger than the length of the value
-    -- then the value will be right justified
-    let b = type @tostring(true,type @stringformat(10)).
-    io @println b.
-
-    let i = type @tostring(5,type @stringformat(5)).
-    io @println i.
-
-    -- we can format a string by applying tostring to the string
-    let s = type @tostring("hello there!",type @stringformat(30)).
-    io @println s.
-
-    -- for floating point values: first value is width, second value precision.
-    -- if precision is missing then value is left justified and zero padded on right.
-    let r = type @tostring(math @pi,type @stringformat(6,3)).
-    io @println r.
-The output of the program is,
-::
-
-          true
-        5
-                      hello there!
-     3.142
-
-Notice the right justification of the various values within the given string length.
-
-Type Conversion
-%%%%%%%%%%%%%%%
-
-type **@tobase** (x:%integer,base:%integer)
-      Represents the given integer x as a numeral string in different bases.
-
-type **@toboolean** x
-      Interpret x as a Boolean value.
-
-type **@tointeger** (x:%string,base:%integer) | x
-      Converts a given input to an integer. If a base value is specified then
-      the resulting integer is in the corresponding base.
-
-type **@toreal** x
-      Returns the input as a real number.
-
-type  **@tostring** x | (x,type @stringformat(width:%integer,precision:%integer,scientific:%boolean))
-      Converts an Asteroid object to a string. If format values are given,
-      it applies the formatting to the string object.
-
-
-
-Type Query Functions
-%%%%%%%%%%%%%%%%%%%%
-
-type **@islist** x
-      Returns true if x is a list otherwise it will return false.
-
-type **@isnone** x
-      Returns true if x is equal to the value none.
-
-type **@isscalar** x
-      Returns true if x is either an integer or a real value.
-
-type **@gettype** x
-      Returns the type of x as a string.
-
-A simple example program using the ``gettype`` function,
-::
-   load system type.
 
-   let i = 1.
-   assert(type @gettype(i) == "integer").
 util
 ^^^^
 
diff --git a/docs/Reference Guide.txt b/docs/Reference Guide.txt
index a42ea083..865dec6c 100644
--- a/docs/Reference Guide.txt
+++ b/docs/Reference Guide.txt
@@ -692,6 +692,9 @@ Builtin Functions
 **getid** x
       Returns a unique id of any Asteroid object as an integer.
 
+**gettype** x
+      Returns the type of x as a string.
+
 **hd** x:%list
       Returns the first element of a list. It is an error to apply this 
       function to an empty list.
@@ -699,6 +702,15 @@ Builtin Functions
 **isdefined** x:%string
       Returns true if a variable or type name is defined in the
       current environment otherwise it returns false. The variable or type name must be given as a string.
+**islist** x 
+      Returns true if x is a list otherwise it will return false.
+
+**isnone** x
+      Returns true if x is equal to the value none.
+
+**isscalar** x
+      Returns true if x is either an integer or a real value.
+
 **len** x
       Returns the length of x. The
       function can only be applied to lists, strings, tuples, or structures.
@@ -714,6 +726,22 @@ Builtin Functions
       Returns the rest of the list without the first element.  It is an 
       error to apply this function to an empty list.
 
+**tobase** (x:%integer,base:%integer)
+      Represents the given integer x as a numeral string in different bases.
+
+**toboolean** x
+      Interpret x as a Boolean value.
+
+**tointeger** (x:%string,base:%integer) | x 
+      Converts a given input to an integer. If a base value is specified then 
+      the resulting integer is in the corresponding base.
+
+**toreal** x
+      Returns the input as a real number.
+
+**tostring** x | (x,stringformat(width:%integer,precision:%integer,scientific:%boolean)) 
+      Converts an Asteroid object to a string. If format values are given, 
+      it applies the formatting to the string object. 
 
 
 List and String Objects
@@ -831,7 +859,7 @@ string **@flip** ()
       Returns a copy of the string with its characters in the reverse order.
 
 string **@index** item:%string | (item:%string, loc(startix:%integer)) | (item:%string, loc(startix:%integer, endix:%integer))
-      Returns an integer index of the item in the string or none if item was not found.  
+      Returns an integer index of the item in the string or -1 if item was not found.  
       The  argument loc allows you to specify startix and endix and are used to limit the search 
       to a particular substring of the string. The returned index is computed relative to the beginning 
       of the full string rather than the startix.  
@@ -1377,64 +1405,6 @@ __STREAM__ **@rewind** ()
       Resets the stream pointer to the first element of the stream.
 
 
-type
-^^^^
-
-The type module defines type related functions and structures.
-Here is a program that exercises some of the string formatting options:
-::
-#include "../asteroid/test-suites/ref-programs/format.ast"
-
-The output of the program is,
-::
-
-          true
-        5
-                      hello there!
-     3.142
-
-Notice the right justification of the various values within the given string length.
-
-Type Conversion
-%%%%%%%%%%%%%%%
-
-type **@tobase** (x:%integer,base:%integer)
-      Represents the given integer x as a numeral string in different bases.
-
-type **@toboolean** x
-      Interpret x as a Boolean value.
-
-type **@tointeger** (x:%string,base:%integer) | x 
-      Converts a given input to an integer. If a base value is specified then 
-      the resulting integer is in the corresponding base.
-
-type **@toreal** x
-      Returns the input as a real number.
-
-type  **@tostring** x | (x,type @stringformat(width:%integer,precision:%integer,scientific:%boolean)) 
-      Converts an Asteroid object to a string. If format values are given, 
-      it applies the formatting to the string object. 
-      
-
-
-Type Query Functions
-%%%%%%%%%%%%%%%%%%%%
-
-type **@islist** x 
-      Returns true if x is a list otherwise it will return false.
-
-type **@isnone** x
-      Returns true if x is equal to the value none.
-
-type **@isscalar** x
-      Returns true if x is either an integer or a real value.
-
-type **@gettype** x
-      Returns the type of x as a string.
-
-A simple example program using the ``gettype`` function,
-::
-#include "../asteroid/test-suites/ref-programs/type.ast"
 
 util
 ^^^^
diff --git a/docs/User Guide.rst b/docs/User Guide.rst
index 8921f5aa..fea18faf 100644
--- a/docs/User Guide.rst
+++ b/docs/User Guide.rst
@@ -76,16 +76,6 @@ As with most programming languages we are familiar with, Asteroid has variables
 * ``string``, e.g. ``"Hello, World!"``
 * ``boolean``, e.g. ``true``
 
-Asteroid arranges these primitive data types in a type hierarchy,
-
-``boolean`` < ``integer`` < ``real`` < ``string``
-
-Type hierarchies facilitate automatic type promotion.  Here is an example
-where automatic type promotion is used to put together a string from different data types,
-::
-    let x:%string = "value: " + 1.
-Here we associate the string ``"value: 1"`` with the variable ``x`` by first promoting the integer value ``1`` to the string ``"1"`` using the fact that ``integer`` < ``string``  according to our type hierarchy  and then interpreting the ``+`` operator as a string concatenation operator.
-
 Asteroid also supports the built-in data types:
 
 * ``list``
@@ -99,16 +89,13 @@ 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.  Lists and tuples themselves are also embedded in type hierarchies, although very simple ones:
+Lists are mutable objects whereas tuples are immutable.
 
-* ``list`` < ``string``
-* ``tuple`` < ``string``
-
-That is, any list or tuple can be viewed as a string.  This is very convenient for printing lists and tuples,
+We can cast lists and tuples to strings for easy printing,
 ::
     load system io.
-    io @println ("this is my list: " + [1,2,3]).
-Here the ``+`` operator acts like a string concantenation operator with the list ``[1,2,3]`` promoted to a string according to the above type hierarchy.
+    io @println ("this is my list: " + tostring [1,2,3]).
+Here the ``+`` operator acts like a string concantenation operator with the list ``[1,2,3]`` promoted to a string.
 
 Asteroid supports the ``none`` type.  The ``none`` type has
 only one member: A constant named ``none``.  However, it turns out that the null-tuple, a tuple with no components
@@ -119,22 +106,22 @@ interchangeably.  That is, the following ``let`` statements will succeed,
     let none = ().
     let () = none.
 showing that ``()`` and ``none`` are equivalent and pattern-match each other.
-The ``none`` data type itself does not belong to any type hierarchy.
 
 We should mention here that because functions and patterns are both first-class citizens in Asteroid we
 also have the types ``function`` and ``pattern``,
 ::
-   load system type.
-
    -- define a function
    function inc with x do
       return x+1.
    end
 
    -- show that 'inc' is of type 'function'
-   assert (type @gettype(inc) == "function").
-Just like the ``none`` type, neither of these types are
-part of a type hierarchy but we can use them in type patterns (see below).
+   assert (gettype(inc) == "function").
+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,
+::
+   let x = 1.1 + toreal(1).
+Asteroid shares this view of data types with prgogramming languages like SML and Rust.
 
 By now you probably figured out that statements are terminated with a period and that comments start with a ``--`` symbol and continue till the end of the line.  You probably also figured out that the ``let`` statement is Asteroid's version of assignment even though the underlying mechanism is a bit different as we will see when we discuss pattern matching in more detail.
 
@@ -186,12 +173,12 @@ an optional step specifier allowing you to generate integer values within that r
 
     -- build a list of odd values
     let a = [1 to 10 step 2].  -- list comprehension
-    io @println ("list: " + a).
+    io @println ("list: " + tostring a).
 
     -- reverse the list using a slice computed as comprehension
     let slice = [4 to 0 step -1]. -- list comprehension
     let b = a@slice.
-    io @println ("reversed list: " + b).
+    io @println ("reversed list: " + tostring b).
 The output is,
 ::
 
@@ -206,7 +193,7 @@ a list of alternating 1 and -1,
     load system math.
 
     let a = [1 to 10] @map (lambda with x do math @mod (x,2))
-                      @map (lambda with x do 1 if x else -1).
+                      @map (lambda with x do 1 if x==1 else -1).
 
     io @println a.
 where the output is,
@@ -307,7 +294,7 @@ The following is a more involved example,
     let Person(name,age,gender) = people@1.
 
     -- print out the member values
-    io @println (name + " is " + age + " years old and is a " +  gender + ".").
+    io @println (name + " is " + tostring age + " years old and is a " +  gender + ".").
 The output is,
 ::
 
@@ -464,9 +451,8 @@ iterate pattern matching on each of the pairs on the list with the pattern ``(ix
 The following is a short program that demonstrates an ``if`` statement,
 ::
     load system io.
-    load system type.
 
-    let x = type @tointeger (io @input "Please enter an integer: ").
+    let x = tointeger (io @input "Please enter an integer: ").
 
     if x < 0 do
         let x = 0.
@@ -583,9 +569,9 @@ Consider the following example,
     let p = (1,2).
 
     if p is (x,y,z) do
-        io @println ("it's a triple with: "+x+","+y+","+z)
+        io @println ("it's a triple with: "+ tostring x +","+ tostring y +","+ tostring z)
     elif p is (x,y) do
-        io @println ("it's a pair with: "+x+","+y).
+        io @println ("it's a pair with: "+ tostring x +","+ tostring y).
     else do
         io @println "it's something else".
     end
@@ -681,7 +667,7 @@ the kind of values that are being passed to a particular function body,
             throw Error("factorial is not defined for "+n).
     end
 
-    io @println ("The factorial of 3 is: " + factorial 3).
+    io @println ("The factorial of 3 is: " + tostring (factorial 3)).
 Here we see that first, we make sure that we are being passed integers and second,
 that the integers are positive using the appropriate conditions on the input values. If
 we are being passed a negative integer, then we throw an error.
@@ -701,7 +687,7 @@ This gives us,
             throw Error("factorial is not defined for "+n).
     end
 
-    io @println ("The factorial of 3 is: " + factorial 3).
+    io @println ("The factorial of 3 is: " + tostring (factorial 3)).
 The parentheses as they appear in the conditional pattern expressions are necessary.
 
 Pattern Matching in For Loops
@@ -739,7 +725,6 @@ Exception handling in Asteroid is very similar to exception handling in many of
 ::
     load system io.
     load system random.
-    load system type.
 
     structure Head with
         data val.
@@ -757,9 +742,9 @@ Exception handling in Asteroid is very similar to exception handling in many of
             throw Tail i.
         end
     catch Head v do
-        io @println ("you win with "+type @tostring (v,type @stringformat (4,2))).
+        io @println ("you win with "+tostring (v,stringformat (4,2))).
     catch Tail v do
-        io @println ("you loose with "+type @tostring (v,type @stringformat (4,2))).
+        io @println ("you loose with "+tostring (v,stringformat (4,2))).
     end
 The ``Head`` and ``Tail`` exceptions are handled by their corresponding ``catch`` statements, respectively.  In both cases the exception object is unpacked using pattern matching and the unpacked value is used in the appropriate message printed to the screen.
 
@@ -844,7 +829,7 @@ data fields.  So even if we declare a structure like this,
 
     -- pattern matching ignores function definitions
     let Person(name,age) = Person("Scarlett",28).
-    io @println (name+" is "+age+" years old").
+    io @println (name+" is "+ tostring age+" years old").
 where the function ``hello`` is defined in the middle of the data fields,
 pattern matching simply ignores the function definition and pattern matches
 only on the data fields.  The output of the program is,
@@ -861,7 +846,6 @@ initializes the data members of the object.
 Here is the program listing for the example in Asteroid,
 ::
    load system io.
-   load system type.
 
    structure Dog with
       data name.
@@ -879,7 +863,7 @@ Here is the program listing for the example in Asteroid,
    let dogs = [fido,buddy,bella].
 
    -- print out all the dogs that know how to fetch
-   for (Dog(name,tricks) if type @tostring tricks is ".*fetch.*") in dogs do
+   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
@@ -1104,7 +1088,7 @@ I/O functions are defined as member functions of the ``io`` module. The ``printl
 
     let a = 1.
     let b = 2.
-    io @println ("a + b = " + (a + b)).
+    io @println ("a + b = " + tostring (a + b)).
 The output is
 ::
 
@@ -1121,24 +1105,23 @@ The width specifier tells the ``tostring`` function how many characters to reser
 Here is a program that exercises some of the string formatting options,
 ::
     load system io.
-    load system type.
     load system math.
 
     -- if the width specifier is larger than the length of the value
     -- then the value will be right justified
-    let b = type @tostring(true,type @stringformat(10)).
+    let b = tostring(true,stringformat(10)).
     io @println b.
 
-    let i = type @tostring(5,type @stringformat(5)).
+    let i = tostring(5,stringformat(5)).
     io @println i.
 
     -- we can format a string by applying tostring to the string
-    let s = type @tostring("hello there!",type @stringformat(30)).
+    let s = tostring("hello there!",stringformat(30)).
     io @println s.
 
     -- for floating point values: first value is width, second value precision.
     -- if precision is missing then value is left justified and zero padded on right.
-    let r = type @tostring(math @pi,type @stringformat(6,3)).
+    let r = tostring(math@pi,stringformat(6,3)).
     io @println r.
 The output of the program is,
 ::
@@ -1170,9 +1153,8 @@ We can use the type casting functions such as ``tointeger`` or ``toreal`` define
 ``type`` module to convert the string returned from ``input`` into a numeric value,
 ::
     load system io.
-    load system type.
 
-    let i if i > 0  = type @tointeger(io @input("Please enter a positive integer value: ")).
+    let i if i > 0  = tointeger(io @input("Please enter a positive integer value: ")).
 
     for k in 1 to i do
         io @println k.
@@ -1217,8 +1199,8 @@ Say that you wanted to load the ``math`` module so you could execute a certain t
     load system io.
     load system math.
 
-    let x = math @sin( math @pi / 2 ).
-    io @println("The sine of pi / 2 is " + x + ".").
+    let x = math @sin( math@pi / 2.0 ).
+    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>`_.
@@ -1318,12 +1300,11 @@ exception object itself.  Here is an example using a ``wildcard``,
 Here is an example using a variable,
 ::
     load system io.
-    load system type.
 
     try
         let (x,y) = (1,2,3).
     catch e do
-        io @println ("something happened: "+type @tostring(e)).
+        io @println ("something happened: "+ tostring e).
     end
 In this last example we simply convert the caught exception object into a string
 and print it,
@@ -1346,15 +1327,14 @@ In order to demonstrate this type of multi-dispatch, we show the example program
 written in Asteroid,
 ::
     load system io.
-    load system type.
 
-    let pos_num = pattern %[x if type @isscalar(x) and x > 0]%.
+    let pos_num = pattern %[x if isscalar(x) and x > 0]%.
 
     structure Asteroid with
        data size.
        function __init_
           with v:*pos_num do
-             let this @size = v.
+             let this@size = v.
           end
     end
 
@@ -1362,7 +1342,7 @@ written in Asteroid,
         data size.
        function __init_
           with v:*pos_num do
-             let this @size = v.
+             let this@size = v.
           end
     end
 
diff --git a/docs/User Guide.txt b/docs/User Guide.txt
index f7447f8f..351bbc69 100644
--- a/docs/User Guide.txt
+++ b/docs/User Guide.txt
@@ -65,17 +65,6 @@ As with most programming languages we are familiar with, Asteroid has variables
 * ``string``, e.g. ``"Hello, World!"``
 * ``boolean``, e.g. ``true``
 
-Asteroid arranges these primitive data types in a type hierarchy,
-
-``boolean`` < ``integer`` < ``real`` < ``string``
-
-Type hierarchies facilitate automatic type promotion.  Here is an example
-where automatic type promotion is used to put together a string from different data types,
-::
-#include "../asteroid/test-suites/ug-programs/prgm-004.ast"
-
-Here we associate the string ``"value: 1"`` with the variable ``x`` by first promoting the integer value ``1`` to the string ``"1"`` using the fact that ``integer`` < ``string``  according to our type hierarchy  and then interpreting the ``+`` operator as a string concatenation operator.
-
 Asteroid also supports the built-in data types:
 
 * ``list``
@@ -90,16 +79,13 @@ 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.  Lists and tuples themselves are also embedded in type hierarchies, although very simple ones:
-
-* ``list`` < ``string``
-* ``tuple`` < ``string``
+Lists are mutable objects whereas tuples are immutable.  
 
-That is, any list or tuple can be viewed as a string.  This is very convenient for printing lists and tuples,
+We can cast lists and tuples to strings for easy printing,
 ::
 #include "../asteroid/test-suites/ug-programs/prgm-007.ast"
 
-Here the ``+`` operator acts like a string concantenation operator with the list ``[1,2,3]`` promoted to a string according to the above type hierarchy.
+Here the ``+`` operator acts like a string concantenation operator with the list ``[1,2,3]`` promoted to a string. 
 
 Asteroid supports the ``none`` type.  The ``none`` type has
 only one member: A constant named ``none``.  However, it turns out that the null-tuple, a tuple with no components
@@ -110,15 +96,18 @@ interchangeably.  That is, the following ``let`` statements will succeed,
 #include "../asteroid/test-suites/ug-programs/prgm-008.ast"
 
 showing that ``()`` and ``none`` are equivalent and pattern-match each other.
-The ``none`` data type itself does not belong to any type hierarchy.
 
 We should mention here that because functions and patterns are both first-class citizens in Asteroid we 
 also have the types ``function`` and ``pattern``,
 ::
 #include "../asteroid/test-suites/ug-programs/prgm-008a.ast"
 
-Just like the ``none`` type, neither of these types are 
-part of a type hierarchy but we can use them in type patterns (see below).
+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,
+::
+#include "../asteroid/test-suites/ug-programs/prgm-008b.ast"
+
+Asteroid shares this view of data types with prgogramming languages like SML and Rust.  
 
 By now you probably figured out that statements are terminated with a period and that comments start with a ``--`` symbol and continue till the end of the line.  You probably also figured out that the ``let`` statement is Asteroid's version of assignment even though the underlying mechanism is a bit different as we will see when we discuss pattern matching in more detail.
 


Test patch:
diff --git a/asteroid/test-suites/action-tests/test012.ast b/asteroid/test-suites/action-tests/test012.ast
index 04121140..309a1e9b 100644
--- a/asteroid/test-suites/action-tests/test012.ast
+++ b/asteroid/test-suites/action-tests/test012.ast
@@ -4,5 +4,5 @@
   let ext = ".txt".
 
   for i in 1 to 5 do
-      io @println (root+i+ext).
+      io @println (root + tostring i + ext).
   end
diff --git a/asteroid/test-suites/action-tests/test013.ast b/asteroid/test-suites/action-tests/test013.ast
index 3cea1353..0de780b0 100644
--- a/asteroid/test-suites/action-tests/test013.ast
+++ b/asteroid/test-suites/action-tests/test013.ast
@@ -1,5 +1,4 @@
   load system io.
-  load system type.
   load system util.
   load system pick.
   load system random.
@@ -7,7 +6,7 @@
   random @seed(42).
 
   -- make up lists of symbols useful for password construction
-  let int_list = [0 to 9] @map(type @tostring).
+  let int_list = [0 to 9] @map(tostring).
   let lc_list = [97 to 122] @map(util @achar). -- lower case characters
   let uc_list = [65 to 90] @map(util @achar). --upper case characters
   let sp_list = ["!","_","#","$","%","*"].
diff --git a/asteroid/test-suites/action-tests/test016.ast b/asteroid/test-suites/action-tests/test016.ast
index 40abab14..e7bc4ca7 100644
--- a/asteroid/test-suites/action-tests/test016.ast
+++ b/asteroid/test-suites/action-tests/test016.ast
@@ -1,5 +1,5 @@
   load system io.
 
   for n in 0 to 5 do
-      io @println (n+" file"+("s " if n>1 or n==0 else " ")+"found").
+      io @println (tostring n + " file" + ("s " if n>1 or n==0 else " ") + "found").
   end
diff --git a/asteroid/test-suites/action-tests/test017.ast b/asteroid/test-suites/action-tests/test017.ast
index bfca622a..3a600062 100644
--- a/asteroid/test-suites/action-tests/test017.ast
+++ b/asteroid/test-suites/action-tests/test017.ast
@@ -41,7 +41,7 @@
   -- put the words into a hash table, the value is the count of the words
   let ht = hash @hash().
   for w in wl do
-      if not ht @get(w) do
+      if ht @get(w) is none do
           ht @insert(w,1).
       else do
           ht @insert(w,ht @get(w)+1).
diff --git a/asteroid/test-suites/action-tests/test018.ast b/asteroid/test-suites/action-tests/test018.ast
index b527952a..45a77afa 100644
--- a/asteroid/test-suites/action-tests/test018.ast
+++ b/asteroid/test-suites/action-tests/test018.ast
@@ -7,13 +7,13 @@
   for startix in 0 to stra @length()-1 do
       for endix in startix to stra @length()-1 do
           let s = stra @[startix to endix].
-          if strb @index(s) and s @length() > common @length() do
+          if strb @index(s) =/= -1 and s @length() > common @length() do
               let common = s.
           end
       end
   end
 
-  if common do
+  if common =/= "" do
       io @println ("The longest common substring is '"+common+"'.").
   else do
       io @println ("There are no common substrings.").
diff --git a/asteroid/test-suites/action-tests/test022.ast b/asteroid/test-suites/action-tests/test022.ast
index b90110c8..398cfa36 100644
--- a/asteroid/test-suites/action-tests/test022.ast
+++ b/asteroid/test-suites/action-tests/test022.ast
@@ -104,7 +104,7 @@
       -- Note: make this code more general
       let n_gram = [word_list@i, word_list@(i+1), word_list @(i+2)] @join(" ").
       -- put the N-gram into a hash table, the value is the count of the N-gram in the text.
-      if not ht @get(n_gram) do
+      if ht @get(n_gram) is none do
           ht @insert(n_gram,1).
       else do
           ht @insert(n_gram,ht @get(n_gram)+1).
@@ -112,5 +112,5 @@
   end
 
   for ((n_gram,cnt) if cnt > 1) in ht @aslist() do
-      io @println (n_gram+": "+cnt).
+      io @println (n_gram+": "+ tostring cnt).
   end
diff --git a/asteroid/test-suites/action-tests/test024.ast b/asteroid/test-suites/action-tests/test024.ast
index f8e3dbfe..fbd155fa 100644
--- a/asteroid/test-suites/action-tests/test024.ast
+++ b/asteroid/test-suites/action-tests/test024.ast
@@ -1,7 +1,7 @@
   load system io.
   load system math.
 
-  let tau = 2 * math @pi.
+  let tau = 2.0 * math @pi.
 
   io @println (math @e).
   io @println tau.
diff --git a/asteroid/test-suites/action-tests/test026.ast b/asteroid/test-suites/action-tests/test026.ast
index 74f53e4b..606a57d8 100644
--- a/asteroid/test-suites/action-tests/test026.ast
+++ b/asteroid/test-suites/action-tests/test026.ast
@@ -12,5 +12,5 @@
           throw Error("factorial is not defined for "+n).
       end
 
-  io @println ("The factorial of 3 is: " + fact (3)).
+  io @println ("The factorial of 3 is: " + tostring(fact 3)).
   assert (fact(3) == 6).
diff --git a/asteroid/test-suites/action-tests/test033.ast b/asteroid/test-suites/action-tests/test033.ast
index 4f14055b..f676e4eb 100644
--- a/asteroid/test-suites/action-tests/test033.ast
+++ b/asteroid/test-suites/action-tests/test033.ast
@@ -4,7 +4,7 @@
   function isprime with x do
       if x >= 2 do
           for y in range(2,x) do
-              if not math @mod(x,y) do
+              if math @mod(x,y) == 0 do
                   return false.
               end
           end
diff --git a/asteroid/test-suites/action-tests/test034.ast b/asteroid/test-suites/action-tests/test034.ast
index e739bf6b..5db7e783 100644
--- a/asteroid/test-suites/action-tests/test034.ast
+++ b/asteroid/test-suites/action-tests/test034.ast
@@ -4,7 +4,7 @@
   function isprime with x do
       if x >= 2 do
           for y in range(2,x) do
-              if not math @mod(x,y) do
+              if math @mod(x,y) == 0 do
                   return false.
               end
           end
diff --git a/asteroid/test-suites/action-tests/test035.ast b/asteroid/test-suites/action-tests/test035.ast
index f5951893..62687fe3 100644
--- a/asteroid/test-suites/action-tests/test035.ast
+++ b/asteroid/test-suites/action-tests/test035.ast
@@ -4,7 +4,7 @@
   function isprime with x do
       if x >= 2 do
           for y in range(2,x) do
-              if not math @mod(x,y) do
+              if math @mod(x,y) == 0 do
                   return false.
               end
           end
@@ -30,7 +30,7 @@
   while n > 1 do
       let factor = primes_list @ix.
       let ix = ix+1.
-      if not math @mod(n,factor) do
+      if math @mod(n,factor) == 0 do
           let ix = 0.
           let n = n/factor.
           let factors = factors+[factor].
diff --git a/asteroid/test-suites/action-tests/test038.ast b/asteroid/test-suites/action-tests/test038.ast
index 9ba4e8b0..6d4e5eec 100644
--- a/asteroid/test-suites/action-tests/test038.ast
+++ b/asteroid/test-suites/action-tests/test038.ast
@@ -1,7 +1,6 @@
   load system io.
   load system random.
   load system util.
-  load system type.
 
   let randint = random @randint.
 
@@ -13,5 +12,5 @@
 
   -- generating a random number in the appropriate interval
   let n = 10.
-  io @println (randint(0.0,type @toreal(n))).
+  io @println (randint(0.0, toreal n)).
   io @println (randint(0,n)).
diff --git a/asteroid/test-suites/action-tests/test039.ast b/asteroid/test-suites/action-tests/test039.ast
index ff6e72b8..ef8ccb11 100644
--- a/asteroid/test-suites/action-tests/test039.ast
+++ b/asteroid/test-suites/action-tests/test039.ast
@@ -1,17 +1,16 @@
   load system io.
   load system util.
-  load system type.
 
   let n = 1234.
   let sq = n*n.
-  let sq_str = type @tostring(sq).
+  let sq_str = tostring sq.
   if sq_str @length() < 8 do
       let prefix = [1 to 8-sq_str@length()] @map(lambda with _ do return "0")
                                             @join("").
       let sq_str = prefix + sq_str.
   end
   let rstr = sq_str @[2 to 5].
-  let rval = type @tointeger(rstr).
+  let rval = tointeger rstr.
   io @println rval.
 
   assert (rval == 5227)
diff --git a/asteroid/test-suites/action-tests/test043.ast b/asteroid/test-suites/action-tests/test043.ast
index 65d1b8f7..1c4359a4 100644
--- a/asteroid/test-suites/action-tests/test043.ast
+++ b/asteroid/test-suites/action-tests/test043.ast
@@ -3,11 +3,11 @@
 
   let values = [727.7, 1086.5, 1091.0, 1361.3, 1490.5, 1956.1].
 
-  let avg = values @reduce(lambda with (x,y) do return x+y) / values @length().
+  let avg = values @reduce(lambda with (x,y) do return x+y) / toreal(values @length()).
   let diff_sq = values @map(lambda with x do return math @pow(x-avg,2)).
   let numerator = diff_sq @reduce(lambda with (x,y) do return x+y).
   let denominator = values @length() -1.
-  let sigma = math @sqrt(numerator/denominator).
+  let sigma = math @sqrt(numerator/toreal denominator).
   io @println sigma.
 
   assert (sigma == 420.96248961952256)
diff --git a/asteroid/test-suites/action-tests/test045.ast b/asteroid/test-suites/action-tests/test045.ast
index 3f23b73c..d115c8a6 100644
--- a/asteroid/test-suites/action-tests/test045.ast
+++ b/asteroid/test-suites/action-tests/test045.ast
@@ -1,7 +1,6 @@
   load system io.
   load system math.
   load system util.
-  load system type.
 
   -- define common math functions locally so the
   -- formulas are easy to read
@@ -11,7 +10,6 @@
   let pow = math @pow.
   let atan = math @atan.
   let pi = math @pi.
-  let toreal = type @toreal.
 
   function polar_to_cartesian with (r,psi) do
       -- return a tuple: (x,y)
@@ -24,11 +22,11 @@
 
   function cartesian_to_psi
       with (x,y) if x > 0  do
-          return atan(toreal(y)/x).
+          return atan(toreal y/toreal x).
       with (x,y) if x < 0 and y >= 0 do
-          return atan(toreal(y)/x)+pi.
+          return atan(toreal y/toreal x)+pi.
       with (x,y) if x < 0 and y < 0 do
-          return atan(toreal(y)/x)-pi.
+          return atan(toreal y/toreal x)-pi.
       with (x,y) if x == 0 and y > 0 do
           return pi/2.
       with (x,y) if x == 0 and y < 0 do
diff --git a/asteroid/test-suites/action-tests/test046.ast b/asteroid/test-suites/action-tests/test046.ast
index 0876a4eb..ce312a4d 100644
--- a/asteroid/test-suites/action-tests/test046.ast
+++ b/asteroid/test-suites/action-tests/test046.ast
@@ -16,7 +16,7 @@
           let inside = inside+1.
       end
   end
-  let area = 4.0 * inside / n.
+  let area = 4.0 * toreal inside / toreal n.
   io @println area.
 
   assert (area == 3.1392).
diff --git a/asteroid/test-suites/action-tests/test047.ast b/asteroid/test-suites/action-tests/test047.ast
index b04b5155..5ef4b4ad 100644
--- a/asteroid/test-suites/action-tests/test047.ast
+++ b/asteroid/test-suites/action-tests/test047.ast
@@ -1,18 +1,17 @@
   load system io.
   load system random.
   load system util.
-  load system type.
 
   random @seed(42).
 
   let n = random @randint(0,10).
-  let guess = type @tointeger(io @input("Guess my number between 0 and 10: ")).
+  let guess = tointeger(io @input("Guess my number between 0 and 10: ")).
   while guess =/= n do
       if guess < n do
           io @println "Too small.".
       elif guess > n  do
            io @println "Too big.".
       end
-      let guess = type @tointeger(io @input("Try again: ")).
+      let guess = tointeger(io @input("Try again: ")).
   end
   io @println "Yes, this is it!".
diff --git a/asteroid/test-suites/action-tests/test048.ast b/asteroid/test-suites/action-tests/test048.ast
index 0984ee04..4b23dc88 100644
--- a/asteroid/test-suites/action-tests/test048.ast
+++ b/asteroid/test-suites/action-tests/test048.ast
@@ -1,8 +1,7 @@
   load system io.
-  load system type.
 
   let bin = "101101".
-  let int = type @tointeger(bin,2).
+  let int = tointeger(bin,2).
   io @println int.
 
   assert (int == 45).
diff --git a/asteroid/test-suites/action-tests/test049.ast b/asteroid/test-suites/action-tests/test049.ast
index fd0656c3..a4dd8fab 100644
--- a/asteroid/test-suites/action-tests/test049.ast
+++ b/asteroid/test-suites/action-tests/test049.ast
@@ -1,8 +1,4 @@
   load system io.
-  load system type.
-
-  let tobase = type @tobase.
-  let tointeger = type @tointeger.
 
   let val = 42.
 
diff --git a/asteroid/test-suites/action-tests/test050.ast b/asteroid/test-suites/action-tests/test050.ast
index 4b3838b0..9fd6f182 100644
--- a/asteroid/test-suites/action-tests/test050.ast
+++ b/asteroid/test-suites/action-tests/test050.ast
@@ -1,12 +1,11 @@
   load system io.
-  load system type.
 
   let number = 139487854.
 
 
-  let s = type @tostring number @explode()
-                                @map(type @tointeger)
-                                @reduce(lambda with (x,y) do return x+y).
+  let s = tostring number @explode()
+                          @map tointeger
+                          @reduce (lambda with (x,y) do x+y).
   io @println s.
 
   assert (s == 49).
diff --git a/asteroid/test-suites/action-tests/test052.ast b/asteroid/test-suites/action-tests/test052.ast
index 5d41c460..589de576 100644
--- a/asteroid/test-suites/action-tests/test052.ast
+++ b/asteroid/test-suites/action-tests/test052.ast
@@ -1,7 +1,6 @@
   load system io.
-  load system type.
 
-  let a = type @tointeger([67, 8, 1, 5, 45] @map(type @tostring) @sort(true) @join("")).
+  let a = tointeger ([67, 8, 1, 5, 45] @map tostring @sort true @join "").
   io @println a.
 
   assert (a == 8675451).
diff --git a/asteroid/test-suites/action-tests/test053.ast b/asteroid/test-suites/action-tests/test053.ast
index 4f35a8de..6179dc9d 100644
--- a/asteroid/test-suites/action-tests/test053.ast
+++ b/asteroid/test-suites/action-tests/test053.ast
@@ -2,7 +2,6 @@
   load system math.
   load system util.
   load system hash.
-  load system type.
 
   let roman_hash = hash @hash().
   roman_hash @insert(1000,["","M","MM","MMM"]).
@@ -11,11 +10,11 @@
   roman_hash @insert(1,["","I","II","III","IV","V","VI","VII","VIII","IX"]).
 
   let n = 2018.
-  let p10 = range(type @tostring n @length()) @map(lambda with x do return math @pow(10,x))
-                                              @reverse().
-  let digits = type @tostring n @explode()
-                                @map(type @tointeger).
-  let z = util @zip(digits, p10).
+  let p10 = range(tostring n @length()) @map(lambda with x do math @pow (10,x))
+                                        @reverse().
+  let digits = tostring n @explode ()
+                          @map tointeger.
+  let z = util @zip (digits, p10).
   io @println z.
   let roman = "".
   for (d,p) in z do
diff --git a/asteroid/test-suites/action-tests/test054.ast b/asteroid/test-suites/action-tests/test054.ast
index 9a12bd9d..48745b41 100644
--- a/asteroid/test-suites/action-tests/test054.ast
+++ b/asteroid/test-suites/action-tests/test054.ast
@@ -13,7 +13,7 @@
           return names @n.
       with (n:%integer) if n < 100 do
           let r = names @(n / 10 + 18).
-          let r = r + ("-" + names @(mod(n,10))) if mod(n,10) else "".
+          let r = r + ("-" + names @(mod(n,10))) if mod(n,10) =/= 0 else "".
           return r.
       with (n:%integer) if n < 1000 do
           return spell_part(n,100,"hundred").
@@ -24,7 +24,7 @@
   function spell_part
       with (n:%integer,base:%integer,name:%string) do
           let r = spell_number(n/base) + " " + name.
-          return r + " " + spell_number(mod(n,base)) if mod(n,base) else r.
+          return r + " " + spell_number(mod(n,base)) if mod(n,base) =/= 0 else r.
       end
 
   io @println (spell_number 15).
diff --git a/asteroid/test-suites/action-tests/test055.ast b/asteroid/test-suites/action-tests/test055.ast
index 09efbd39..6bcb712d 100644
--- a/asteroid/test-suites/action-tests/test055.ast
+++ b/asteroid/test-suites/action-tests/test055.ast
@@ -2,6 +2,6 @@
 
   let (a,b) = (10,20).
   let (b,a) = (a,b).
-  io @println ("a = "+a,"b = "+b).
+  io @println ("a = "+ tostring a,"b = "+ tostring b).
 
   assert ((a,b) is (20,10)).
diff --git a/asteroid/test-suites/action-tests/test068.ast b/asteroid/test-suites/action-tests/test068.ast
index 4441301e..350cd555 100644
--- a/asteroid/test-suites/action-tests/test068.ast
+++ b/asteroid/test-suites/action-tests/test068.ast
@@ -59,6 +59,6 @@ function sum with lst:%list do
 end
 
 let dt = [1 to 100] @map(lambda with _ do return random @random()).
-let mavg = [3 to 96] @map(lambda with i do return sum(window(dt,i))/7).
+let mavg = [3 to 96] @map(lambda with i do return sum(window(dt,i))/toreal 7).
 
 plot(dt @[3 to 96],mavg).
diff --git a/asteroid/test-suites/action-tests/test069.ast b/asteroid/test-suites/action-tests/test069.ast
index 8a1c090f..bbb2275a 100644
--- a/asteroid/test-suites/action-tests/test069.ast
+++ b/asteroid/test-suites/action-tests/test069.ast
@@ -2,4 +2,6 @@
 
   let array = [10, 14, 0, 15, 17, 20, 30, 35].
   let x = 17.
-  io @println ((x+" is in the list") if array @member(x) else (x+" is not in the list")).
+  io @println ((tostring x +" is in the list") 
+          if array @member x 
+          else (tostring x + " is not in the list")).
diff --git a/asteroid/test-suites/action-tests/test070.ast b/asteroid/test-suites/action-tests/test070.ast
index 779bb07e..9f407eb0 100644
--- a/asteroid/test-suites/action-tests/test070.ast
+++ b/asteroid/test-suites/action-tests/test070.ast
@@ -3,8 +3,8 @@
   let array = [10, 14, 0, 15, 17, 20, 30, 35].
   let x = 17.
 
-  if array @reduce(lambda with (acc,i) do return true if i==x else acc,false) do
-      io @println (x+" is in the list").
+  if array @reduce(lambda with (acc,i) do true if i==x else acc,false) do
+      io @println (tostring x + " is in the list").
   else
-      io @println (x+" is not in the list").
+      io @println (tostring x + " is not in the list").
   end
diff --git a/asteroid/test-suites/action-tests/test071.ast b/asteroid/test-suites/action-tests/test071.ast
index a8127013..b67a2ca2 100644
--- a/asteroid/test-suites/action-tests/test071.ast
+++ b/asteroid/test-suites/action-tests/test071.ast
@@ -1,10 +1,9 @@
   load system io.
   load system math.
   load system util.
-  load system type.
 
   let mod = math @mod.
 
   let array = [2, 4, 18, 9, 16, 7, 10].
-  let odd = array @reduce(lambda with (acc,i) do return i if type @isnone(acc) and mod(i,2) else acc,none).
+  let odd = array @reduce (lambda with (acc,i) do i if isnone acc and mod(i,2) =/= 0 else acc,none).
   io @println odd.
diff --git a/asteroid/test-suites/action-tests/test072.ast b/asteroid/test-suites/action-tests/test072.ast
index 2d5b867d..a9c0b57c 100644
--- a/asteroid/test-suites/action-tests/test072.ast
+++ b/asteroid/test-suites/action-tests/test072.ast
@@ -1,7 +1,7 @@
   load system io.
   load system math.
 
-  let array = [20 to 30] @filter(lambda with x do return math @mod(x,2)).
+  let array = [20 to 30] @filter(lambda with x do math @mod(x,2)=/=0).
   io @println array.
 
   assert (array == [21,23,25,27,29]).
diff --git a/asteroid/test-suites/action-tests/test077.ast b/asteroid/test-suites/action-tests/test077.ast
index 8581896a..a7ff9e5b 100644
--- a/asteroid/test-suites/action-tests/test077.ast
+++ b/asteroid/test-suites/action-tests/test077.ast
@@ -1,9 +1,8 @@
   load system io.
-  load system type.
 
   let a = [3, 7, 19, 20, 34].
-  let b = type @toboolean(a @reduce(lambda with (x,y) do return y if x<y else false)).
+  let b = a @reduce(lambda with ((_,x),y) do (true,y) if x<=y else (false,y),(true,a@0)).
 
-  io @println b.
+  io @println (b@0).
 
-  assert (b).
+  assert (b@0).
diff --git a/asteroid/test-suites/action-tests/test078.ast b/asteroid/test-suites/action-tests/test078.ast
index e7863b20..8d706304 100644
--- a/asteroid/test-suites/action-tests/test078.ast
+++ b/asteroid/test-suites/action-tests/test078.ast
@@ -26,7 +26,7 @@
       io @println "".
       for r in m do
           for e in r do
-              io @print (e + " ").
+              io @print (tostring e + " ").
           end
           io @println ("").
       end
diff --git a/asteroid/test-suites/action-tests/test080.ast b/asteroid/test-suites/action-tests/test080.ast
index d5a245c8..0608e4bc 100644
--- a/asteroid/test-suites/action-tests/test080.ast
+++ b/asteroid/test-suites/action-tests/test080.ast
@@ -18,7 +18,7 @@
 
   let color_hash = hash @hash().
   for (_,color) in fruit_lst do
-      if not color_hash @get(color) do
+      if color_hash @get(color) is none do
           color_hash @insert(color,1).
       else
           color_hash @insert(color, color_hash @get(color) +1).
diff --git a/asteroid/test-suites/action-tests/test081.ast b/asteroid/test-suites/action-tests/test081.ast
index 403b2f71..30050235 100644
--- a/asteroid/test-suites/action-tests/test081.ast
+++ b/asteroid/test-suites/action-tests/test081.ast
@@ -1,12 +1,11 @@
   load system io.
-  load system type.
 
   function format with v do
       let maxlen = 3.
-      let vstr = type @tostring v.
-      return [1 to maxlen-len(vstr)] @map(lambda with _ do return " ") @join("") + vstr.
+      let vstr = tostring v.
+      return [1 to maxlen-len(vstr)] @map(lambda with _ do " ") @join("") + vstr.
   end
 
   for i in 1 to 10 do
-      io @println ([1 to 10] @map(lambda with x do return format(i*x)) @join(" ")).
+      io @println ([1 to 10] @map(lambda with x do format(i*x)) @join(" ")).
   end
diff --git a/asteroid/test-suites/action-tests/test082.ast b/asteroid/test-suites/action-tests/test082.ast
index 009dcdb9..218ce827 100644
--- a/asteroid/test-suites/action-tests/test082.ast
+++ b/asteroid/test-suites/action-tests/test082.ast
@@ -1,7 +1,6 @@
   load system io.
   load system vector.
   load system util.
-  load system type.
 
   let triangle = [[1]].
   let ix = 0.
@@ -16,5 +15,5 @@
   end
 
   for r in triangle do
-      io @println (r @map(lambda with v do return type @tostring v) @join(" ")).
+      io @println (r @map(lambda with v do tostring v) @join(" ")).
   end
diff --git a/asteroid/test-suites/ref-programs/format.ast b/asteroid/test-suites/ref-programs/format.ast
index 98c5d197..2f5e6bd3 100644
--- a/asteroid/test-suites/ref-programs/format.ast
+++ b/asteroid/test-suites/ref-programs/format.ast
@@ -1,20 +1,19 @@
     load system io.
-    load system type.
     load system math.
 
     -- if the width specifier is larger than the length of the value
     -- then the value will be right justified
-    let b = type @tostring(true,type @stringformat(10)).
+    let b = tostring(true,stringformat(10)).
     io @println b.
 
-    let i = type @tostring(5,type @stringformat(5)).
+    let i = tostring(5,stringformat(5)).
     io @println i.
 
     -- we can format a string by applying tostring to the string
-    let s = type @tostring("hello there!",type @stringformat(30)).
+    let s = tostring("hello there!",stringformat(30)).
     io @println s.
 
     -- for floating point values: first value is width, second value precision.
     -- if precision is missing then value is left justified and zero padded on right.
-    let r = type @tostring(math @pi,type @stringformat(6,3)).
+    let r = tostring(math@pi,stringformat(6,3)).
     io @println r.
diff --git a/asteroid/test-suites/ref-programs/math.ast b/asteroid/test-suites/ref-programs/math.ast
index ff4e64c2..bd419bb4 100644
--- a/asteroid/test-suites/ref-programs/math.ast
+++ b/asteroid/test-suites/ref-programs/math.ast
@@ -1,5 +1,5 @@
     load system io.
     load system math.
 
-    let x = math @sin( math @pi / 2 ).
-    io @println("The sine of pi / 2 is " + x + ".").
+    let x = math @sin( math @pi / 2.0 ).
+    io @println("The sine of pi / 2 is " + tostring x + ".").
diff --git a/asteroid/test-suites/ref-programs/stream.ast b/asteroid/test-suites/ref-programs/stream.ast
index 41971f97..5ee8272c 100644
--- a/asteroid/test-suites/ref-programs/stream.ast
+++ b/asteroid/test-suites/ref-programs/stream.ast
@@ -3,7 +3,7 @@
 
    let s = stream @stream [1 to 10].
    while not s @eof() do
-      io @print (s @get() + " ").
+      io @print (tostring (s @get()) + " ").
    end
    io @println "".
    
\ No newline at end of file
diff --git a/asteroid/test-suites/ref-programs/type.ast b/asteroid/test-suites/ref-programs/type.ast
index 28b79870..82fc6335 100644
--- a/asteroid/test-suites/ref-programs/type.ast
+++ b/asteroid/test-suites/ref-programs/type.ast
@@ -1,5 +1,4 @@
-   load system type.
 
    let i = 1.
-   assert(type @gettype(i) == "integer").
+   assert(gettype(i) == "integer").
    
\ No newline at end of file
diff --git a/asteroid/test-suites/regression-tests/test002.ast b/asteroid/test-suites/regression-tests/test002.ast
index a8f98724..61532d69 100644
--- a/asteroid/test-suites/regression-tests/test002.ast
+++ b/asteroid/test-suites/regression-tests/test002.ast
@@ -1,9 +1,7 @@
 
 load system io.
 load system util.
-load system type.
 
-let isnone = type @isnone.
 
 -----------------------------------------------------------------------
 let x = [1,2].
diff --git a/asteroid/test-suites/regression-tests/test004.ast b/asteroid/test-suites/regression-tests/test004.ast
index 1a7c7ee7..a25cdabf 100644
--- a/asteroid/test-suites/regression-tests/test004.ast
+++ b/asteroid/test-suites/regression-tests/test004.ast
@@ -1,5 +1,4 @@
 
 load system io.
-load system type.
-let l if type @tostring l is "\[.*\]" = [1,2,3].
+let l if tostring l is "\[.*\]" = [1,2,3].
 io @println l.
diff --git a/asteroid/test-suites/regression-tests/test017.ast b/asteroid/test-suites/regression-tests/test017.ast
index 3e412235..c845a4ae 100644
--- a/asteroid/test-suites/regression-tests/test017.ast
+++ b/asteroid/test-suites/regression-tests/test017.ast
@@ -1,6 +1,5 @@
 
 load system io.
-load system type.
 
-let (l:%list) if type @tostring l is "\[.*2.*\]" = [1,2,3].
+let (l:%list) if tostring l is "\[.*2.*\]" = [1,2,3].
 assert(l == [1,2,3]).
\ No newline at end of file
diff --git a/asteroid/test-suites/regression-tests/test019.ast b/asteroid/test-suites/regression-tests/test019.ast
index ac1342b7..2c05a1a6 100644
--- a/asteroid/test-suites/regression-tests/test019.ast
+++ b/asteroid/test-suites/regression-tests/test019.ast
@@ -2,7 +2,7 @@
 -- Factorial
 
 load system io.
-load "util".
+load system util.
 
 function fact 
     with 0 do
@@ -13,6 +13,6 @@ function fact
         throw Error("factorial is not defined for "+n).
     end 
 
-io @println ("The factorial of 3 is: " + fact (3)).
+io @println ("The factorial of 3 is: " + tostring (fact (3))).
 assert (fact(3) == 6).
 
diff --git a/asteroid/test-suites/regression-tests/test027.ast b/asteroid/test-suites/regression-tests/test027.ast
index 3b53c07b..68cc3ab1 100644
--- a/asteroid/test-suites/regression-tests/test027.ast
+++ b/asteroid/test-suites/regression-tests/test027.ast
@@ -3,7 +3,7 @@ load system io.
 
 structure A with
     data a.
-    function hello with none do return "hello: "+ this @a end.
+    function hello with none do  "hello: "+ tostring (this@a) end.
     end
     
 structure B with
diff --git a/asteroid/test-suites/regression-tests/test038.ast b/asteroid/test-suites/regression-tests/test038.ast
index 6ab55e07..3ad23a81 100644
--- a/asteroid/test-suites/regression-tests/test038.ast
+++ b/asteroid/test-suites/regression-tests/test038.ast
@@ -1,4 +1,4 @@
 
 load system io.
 let t = (1,2).
-io @println ("tuple = " + t).
+io @println ("tuple = " + tostring t).
diff --git a/asteroid/test-suites/regression-tests/test040.ast b/asteroid/test-suites/regression-tests/test040.ast
index cd5b92ea..72558b23 100644
--- a/asteroid/test-suites/regression-tests/test040.ast
+++ b/asteroid/test-suites/regression-tests/test040.ast
@@ -1,6 +1,6 @@
 
 load system io.
-load "util".
+load system util.
 
 structure Dog with
 
@@ -33,8 +33,8 @@ buddy @add_trick("roll over").
 buddy @add_trick("sit stay").
 
 -- io @println out the tricks
-io @println ("Fido: " + fido @tricks).
-io @println ("Buddy: " + buddy @tricks).
+io @println ("Fido: " + tostring (fido@tricks)).
+io @println ("Buddy: " + tostring (buddy@tricks)).
 
 assert(fido @tricks is ["roll over", "play dead"]).
 assert(buddy @tricks is ["roll over", "sit stay"]).
diff --git a/asteroid/test-suites/regression-tests/test043.ast b/asteroid/test-suites/regression-tests/test043.ast
index 23eba019..b8172490 100644
--- a/asteroid/test-suites/regression-tests/test043.ast
+++ b/asteroid/test-suites/regression-tests/test043.ast
@@ -15,6 +15,6 @@ let people = [
     ].
     
 let Person(name,age,sex) = people @1.
-let output_str = name + " is " + age + " years old and is " + ("male" if sex is "M" else "female") + ".".
+let output_str = name + " is " + tostring age + " years old and is " + ("male" if sex is "M" else "female") + ".".
 io @println output_str.
 assert(output_str is "Sophie is 46 years old and is female.")
diff --git a/asteroid/test-suites/regression-tests/test060.ast b/asteroid/test-suites/regression-tests/test060.ast
index 947e5bf8..2860ef1e 100644
--- a/asteroid/test-suites/regression-tests/test060.ast
+++ b/asteroid/test-suites/regression-tests/test060.ast
@@ -1,6 +1,6 @@
 
 load system io.
-load "util".
+load system util.
 
 structure Person with
     data name.
@@ -21,7 +21,7 @@ for Person(_,age,_) in people do
     let sum = sum + age.
 end 
 
-io @println ("Average Age: " + (sum/n)).
+io @println ("Average Age: " + tostring (sum/n)).
 assert ((sum/n) == 33).
 
 for Person(name,_,"M") in people do
diff --git a/asteroid/test-suites/regression-tests/test067.ast b/asteroid/test-suites/regression-tests/test067.ast
index c5edecd9..a0224dad 100644
--- a/asteroid/test-suites/regression-tests/test067.ast
+++ b/asteroid/test-suites/regression-tests/test067.ast
@@ -1,8 +1,7 @@
 
-load system type.
 load system io.
 
-let cnt = type @tointeger(io @input("Please enter an integer value: ")).
+let cnt = tointeger(io @input("Please enter an integer value: ")).
 
 for i in 1 to cnt do
     io @println i.
diff --git a/asteroid/test-suites/regression-tests/test072.ast b/asteroid/test-suites/regression-tests/test072.ast
index 8bb43baa..90cfbea8 100644
--- a/asteroid/test-suites/regression-tests/test072.ast
+++ b/asteroid/test-suites/regression-tests/test072.ast
@@ -2,7 +2,7 @@
 -- Factorial
 
 load system io.
-load "util".
+load system util.
 
 function fact 
     with 0 do
@@ -11,5 +11,5 @@ function fact
         return n * fact (n-1).
     end 
 
-io @println ("The factorial of 3 is: " + fact (3)).
+io @println ("The factorial of 3 is: " + tostring (fact 3)).
 assert (fact(3) == 6).
diff --git a/asteroid/test-suites/regression-tests/test075.ast b/asteroid/test-suites/regression-tests/test075.ast
index 95b4ff34..de8daf41 100644
--- a/asteroid/test-suites/regression-tests/test075.ast
+++ b/asteroid/test-suites/regression-tests/test075.ast
@@ -1,7 +1,7 @@
 
 load system io.
-load "util".
+load system util.
 
 let [h|t] = [1,2,3].
-io @println ("head: " + h + " tail: " + t).
+io @println ("head: " + tostring h + " tail: " + tostring t).
 assert(h == 1 and t == [2,3]).
diff --git a/asteroid/test-suites/regression-tests/test085.ast b/asteroid/test-suites/regression-tests/test085.ast
index b34cb522..50bb0f4c 100644
--- a/asteroid/test-suites/regression-tests/test085.ast
+++ b/asteroid/test-suites/regression-tests/test085.ast
@@ -1,14 +1,13 @@
 
 load system io.
-load "util".
 
 structure A with
     data x.
     data y.
     end 
 
-let a = A(999, (lambda with none do return "Hello World!"+this@x)).
-io @println (a@1()).
+let a = A(999, (lambda with none do return "Hello World!"+ tostring (this@x))).
+io @println (tostring (a@1 ())).
 
 assert(a@1() is "Hello World!999").
 
diff --git a/asteroid/test-suites/regression-tests/test114.ast b/asteroid/test-suites/regression-tests/test114.ast
index d11d40f9..80d1af3e 100644
--- a/asteroid/test-suites/regression-tests/test114.ast
+++ b/asteroid/test-suites/regression-tests/test114.ast
@@ -1,11 +1,8 @@
 -- tests for formatting
 
 load system io.
-load system type.
 load system math.
 
-let tostring = type @tostring.
-let stringformat = type @stringformat.
 
 let b = tostring(true,stringformat(10)).
 io @println b.
diff --git a/asteroid/test-suites/regression-tests/test115.ast b/asteroid/test-suites/regression-tests/test115.ast
index 4a1dede9..ab309d56 100644
--- a/asteroid/test-suites/regression-tests/test115.ast
+++ b/asteroid/test-suites/regression-tests/test115.ast
@@ -1,9 +1,6 @@
 -- testing the builtin 'len' function
 
 load system io.
-load system type.
-
-let tostring = type @tostring.
 
 structure Foo with
    data one.
@@ -11,9 +8,9 @@ structure Foo with
    data three.
    function hello
       with none do
-        io @println (tostring(this @one)+
-                 tostring(this @two)+
-                 tostring(this @three)).
+        io @println (tostring(this@one)+
+                 tostring(this@two)+
+                 tostring(this@three)).
       end
    end
 
diff --git a/asteroid/test-suites/regression-tests/test120.ast b/asteroid/test-suites/regression-tests/test120.ast
index 2deee960..5aa48237 100644
--- a/asteroid/test-suites/regression-tests/test120.ast
+++ b/asteroid/test-suites/regression-tests/test120.ast
@@ -6,7 +6,7 @@ assert(x == 2).
 let y = +3.0.
 assert(y == 3.0).
 
-let z = +x + +y - +x * +-x.
+let z = toreal(+x) + +y - toreal(+x) * + toreal(-x).
 assert(z == 9.0).
 
 assert(+12 == 12).
diff --git a/asteroid/test-suites/regression-tests/test127.ast b/asteroid/test-suites/regression-tests/test127.ast
index 02b8f27f..c4735f84 100644
--- a/asteroid/test-suites/regression-tests/test127.ast
+++ b/asteroid/test-suites/regression-tests/test127.ast
@@ -7,6 +7,8 @@ escape
 from asteroid.interp import interp
 from asteroid.state import state
 
+print(1)
+
 program = ''
 program += 'let x = 1.\n'
 program += 'let y = 0.\n'
@@ -24,6 +26,8 @@ except:
 
 assert( state.lineinfo[1] == 6)
 
+print(2)
+
 program = ''
 program += 'let x = 1.\n'
 program += 'let y = 0.\n'
@@ -46,6 +50,8 @@ except:
 
 assert( state.lineinfo[1] == 8)
 
+print(3)
+
 program = ''
 program += 'let x = 1.\n'
 program += 'let y = 0.\n'
@@ -74,11 +80,13 @@ except:
 
 assert( state.lineinfo[1] == 12)
 
+print(4)
+
 program = ''
 program += 'let x = 1.\n'
 program += 'let y = 0.\n'
 program += '\n'
-program += 'while (1) do\n'
+program += 'while (true) do\n'
 program += '    if ( x < 0) do\n'
 program += '        ...\n'
 program += '    elif ( x < 1 ) do\n'
@@ -100,6 +108,6 @@ try:
     interp(program,exceptions=True)
 except:
     pass
-
+    
 assert( state.lineinfo[1] == 13 )
 "
diff --git a/asteroid/test-suites/regression-tests/test129.ast b/asteroid/test-suites/regression-tests/test129.ast
index 4baa699a..527df49e 100644
--- a/asteroid/test-suites/regression-tests/test129.ast
+++ b/asteroid/test-suites/regression-tests/test129.ast
@@ -6,18 +6,18 @@ let n = E + e - 4.00e01 + 0.1.
 io @println(n).
 assert(n == -69.8999999999897).
 
-let s = type @tostring(n,type @stringformat(10,10,true)).
+let s = tostring(n,stringformat(10,10,true)).
 io @println(s).
 assert(s == "-6.9900000000e+01").
 
-let s = type @tostring(n,type @stringformat(10,10,false)).
+let s = tostring(n,stringformat(10,10,false)).
 io @println(s).
 assert(s == "-69.9000000000").
 
 let y = 1.
-io @println(type @gettype(y)).
-assert(type @gettype(y) == "integer").
+io @println(gettype(y)).
+assert(gettype(y) == "integer").
 
 let z = 1.0.
-io @println(type @gettype(z)).
-assert(type @gettype(z) == "real").
\ No newline at end of file
+io @println(gettype(z)).
+assert(gettype(z) == "real").
\ No newline at end of file
diff --git a/asteroid/test-suites/regression-tests/test133.ast b/asteroid/test-suites/regression-tests/test133.ast
index 643acb69..f3109235 100644
--- a/asteroid/test-suites/regression-tests/test133.ast
+++ b/asteroid/test-suites/regression-tests/test133.ast
@@ -2,7 +2,7 @@
 assert(lambda with x do return x+1).
 assert(pattern x).
 assert((1,2)).
-assert(not ()).
+-- assert(not ()).
 
 structure A with
    data a.
diff --git a/asteroid/test-suites/regression-tests/test143.ast b/asteroid/test-suites/regression-tests/test143.ast
index d6321277..57a8a823 100644
--- a/asteroid/test-suites/regression-tests/test143.ast
+++ b/asteroid/test-suites/regression-tests/test143.ast
@@ -7,7 +7,7 @@ structure Person with
          let this @age = age.
       end
       function __str__ with none do
-         return this@name+" is "+this@age+" years old".
+         this@name+" is "+ tostring (this@age) +" years old".
       end
 end
 
@@ -15,5 +15,4 @@ let betty = Person("Betty",21).  -- call constructor
 assert( betty @name == "Betty" ).
 assert( betty @age == 21 ).
 
-load system type.
-assert(type @tostring betty is "Betty is 21 years old").
+assert(tostring betty is "Betty is 21 years old").
diff --git a/asteroid/test-suites/run-tests.py b/asteroid/test-suites/run-tests.py
index cf403b50..6593e62a 100755
--- a/asteroid/test-suites/run-tests.py
+++ b/asteroid/test-suites/run-tests.py
@@ -74,3 +74,4 @@
                    exceptions=verbose_failure,
                    redundancy=redundancy)
             f.close()
+
diff --git a/asteroid/test-suites/ug-programs/prgm-004.ast b/asteroid/test-suites/ug-programs/prgm-004.ast
index 3e655040..a4f50663 100644
--- a/asteroid/test-suites/ug-programs/prgm-004.ast
+++ b/asteroid/test-suites/ug-programs/prgm-004.ast
@@ -1,1 +1,1 @@
-    let x:%string = "value: " + 1.
+    let x:%string = "value: " + tostring 1.
diff --git a/asteroid/test-suites/ug-programs/prgm-007.ast b/asteroid/test-suites/ug-programs/prgm-007.ast
index befc0059..3cec9b7f 100644
--- a/asteroid/test-suites/ug-programs/prgm-007.ast
+++ b/asteroid/test-suites/ug-programs/prgm-007.ast
@@ -1,2 +1,2 @@
     load system io.
-    io @println ("this is my list: " + [1,2,3]).
+    io @println ("this is my list: " + tostring [1,2,3]).
diff --git a/asteroid/test-suites/ug-programs/prgm-008a.ast b/asteroid/test-suites/ug-programs/prgm-008a.ast
index f4337f67..14f5ec7b 100644
--- a/asteroid/test-suites/ug-programs/prgm-008a.ast
+++ b/asteroid/test-suites/ug-programs/prgm-008a.ast
@@ -1,4 +1,3 @@
-   load system type.
 
    -- define a function
    function inc with x do
@@ -6,4 +5,4 @@
    end
 
    -- show that 'inc' is of type 'function'
-   assert (type @gettype(inc) == "function").
\ No newline at end of file
+   assert (gettype(inc) == "function").
\ No newline at end of file
diff --git a/asteroid/test-suites/ug-programs/prgm-008b.ast b/asteroid/test-suites/ug-programs/prgm-008b.ast
new file mode 100644
index 00000000..254e60a3
--- /dev/null
+++ b/asteroid/test-suites/ug-programs/prgm-008b.ast
@@ -0,0 +1,1 @@
+   let x = 1.1 + toreal(1).
\ No newline at end of file
diff --git a/asteroid/test-suites/ug-programs/prgm-011.ast b/asteroid/test-suites/ug-programs/prgm-011.ast
index 2b1a2671..0e1facec 100644
--- a/asteroid/test-suites/ug-programs/prgm-011.ast
+++ b/asteroid/test-suites/ug-programs/prgm-011.ast
@@ -2,9 +2,9 @@
 
     -- build a list of odd values
     let a = [1 to 10 step 2].  -- list comprehension
-    io @println ("list: " + a).
+    io @println ("list: " + tostring a).
 
     -- reverse the list using a slice computed as comprehension
     let slice = [4 to 0 step -1]. -- list comprehension
     let b = a@slice.
-    io @println ("reversed list: " + b).
+    io @println ("reversed list: " + tostring b).
diff --git a/asteroid/test-suites/ug-programs/prgm-012.ast b/asteroid/test-suites/ug-programs/prgm-012.ast
index e44c738a..faf1b452 100644
--- a/asteroid/test-suites/ug-programs/prgm-012.ast
+++ b/asteroid/test-suites/ug-programs/prgm-012.ast
@@ -2,6 +2,6 @@
     load system math.
 
     let a = [1 to 10] @map (lambda with x do math @mod (x,2))
-                      @map (lambda with x do 1 if x else -1).
+                      @map (lambda with x do 1 if x==1 else -1).
 
     io @println a.
diff --git a/asteroid/test-suites/ug-programs/prgm-017.ast b/asteroid/test-suites/ug-programs/prgm-017.ast
index e3683a34..0997f349 100644
--- a/asteroid/test-suites/ug-programs/prgm-017.ast
+++ b/asteroid/test-suites/ug-programs/prgm-017.ast
@@ -19,4 +19,4 @@
     let Person(name,age,gender) = people@1.
 
     -- print out the member values
-    io @println (name + " is " + age + " years old and is a " +  gender + ".").
+    io @println (name + " is " + tostring age + " years old and is a " +  gender + ".").
diff --git a/asteroid/test-suites/ug-programs/prgm-024.ast b/asteroid/test-suites/ug-programs/prgm-024.ast
index bb610428..4a00d07e 100644
--- a/asteroid/test-suites/ug-programs/prgm-024.ast
+++ b/asteroid/test-suites/ug-programs/prgm-024.ast
@@ -1,7 +1,6 @@
     load system io.
-    load system type.
 
-    let x = type @tointeger (io @input "Please enter an integer: ").
+    let x = tointeger (io @input "Please enter an integer: ").
 
     if x < 0 do
         let x = 0.
diff --git a/asteroid/test-suites/ug-programs/prgm-028.ast b/asteroid/test-suites/ug-programs/prgm-028.ast
index 3660b923..4cb4297b 100644
--- a/asteroid/test-suites/ug-programs/prgm-028.ast
+++ b/asteroid/test-suites/ug-programs/prgm-028.ast
@@ -3,9 +3,9 @@
     let p = (1,2).
 
     if p is (x,y,z) do
-        io @println ("it's a triple with: "+x+","+y+","+z)
+        io @println ("it's a triple with: "+ tostring x +","+ tostring y +","+ tostring z)
     elif p is (x,y) do
-        io @println ("it's a pair with: "+x+","+y).
+        io @println ("it's a pair with: "+ tostring x +","+ tostring y).
     else do
         io @println "it's something else".
     end
diff --git a/asteroid/test-suites/ug-programs/prgm-031.ast b/asteroid/test-suites/ug-programs/prgm-031.ast
index ee7e2fcb..38ffb259 100644
--- a/asteroid/test-suites/ug-programs/prgm-031.ast
+++ b/asteroid/test-suites/ug-programs/prgm-031.ast
@@ -9,4 +9,4 @@
             throw Error("factorial is not defined for "+n).
     end
 
-    io @println ("The factorial of 3 is: " + factorial 3).
+    io @println ("The factorial of 3 is: " + tostring (factorial 3)).
diff --git a/asteroid/test-suites/ug-programs/prgm-031a.ast b/asteroid/test-suites/ug-programs/prgm-031a.ast
index 6bc53b22..c65ee0d0 100644
--- a/asteroid/test-suites/ug-programs/prgm-031a.ast
+++ b/asteroid/test-suites/ug-programs/prgm-031a.ast
@@ -9,4 +9,4 @@
             throw Error("factorial is not defined for "+n).
     end
 
-    io @println ("The factorial of 3 is: " + factorial 3).
+    io @println ("The factorial of 3 is: " + tostring (factorial 3)).
diff --git a/asteroid/test-suites/ug-programs/prgm-033.ast b/asteroid/test-suites/ug-programs/prgm-033.ast
index 8e7f52d5..d0b5ea7a 100644
--- a/asteroid/test-suites/ug-programs/prgm-033.ast
+++ b/asteroid/test-suites/ug-programs/prgm-033.ast
@@ -1,6 +1,5 @@
     load system io.
     load system random.
-    load system type.
 
     structure Head with
         data val.
@@ -18,7 +17,7 @@
             throw Tail i.
         end
     catch Head v do
-        io @println ("you win with "+type @tostring (v,type @stringformat (4,2))).
+        io @println ("you win with "+tostring (v,stringformat (4,2))).
     catch Tail v do
-        io @println ("you loose with "+type @tostring (v,type @stringformat (4,2))).
+        io @println ("you loose with "+tostring (v,stringformat (4,2))).
     end
diff --git a/asteroid/test-suites/ug-programs/prgm-036.ast b/asteroid/test-suites/ug-programs/prgm-036.ast
index 5a3a2f16..486c6093 100644
--- a/asteroid/test-suites/ug-programs/prgm-036.ast
+++ b/asteroid/test-suites/ug-programs/prgm-036.ast
@@ -11,4 +11,4 @@
 
     -- pattern matching ignores function definitions
     let Person(name,age) = Person("Scarlett",28).
-    io @println (name+" is "+age+" years old").
+    io @println (name+" is "+ tostring age+" years old").
diff --git a/asteroid/test-suites/ug-programs/prgm-037.ast b/asteroid/test-suites/ug-programs/prgm-037.ast
index 7784cc17..84d5e39e 100644
--- a/asteroid/test-suites/ug-programs/prgm-037.ast
+++ b/asteroid/test-suites/ug-programs/prgm-037.ast
@@ -1,5 +1,4 @@
    load system io.
-   load system type.
 
    structure Dog with
       data name.
@@ -17,6 +16,6 @@
    let dogs = [fido,buddy,bella].
 
    -- print out all the dogs that know how to fetch
-   for (Dog(name,tricks) if type @tostring tricks is ".*fetch.*") in dogs do
+   for (Dog(name,tricks) if tostring tricks is ".*fetch.*") in dogs do
       io @println (name+" knows how to fetch").
    end
diff --git a/asteroid/test-suites/ug-programs/prgm-044.ast b/asteroid/test-suites/ug-programs/prgm-044.ast
index dc29d9f8..35324afb 100644
--- a/asteroid/test-suites/ug-programs/prgm-044.ast
+++ b/asteroid/test-suites/ug-programs/prgm-044.ast
@@ -1,13 +1,12 @@
     load system io.
-    load system type.
 
-    let pos_num = pattern %[x if type @isscalar(x) and x > 0]%.
+    let pos_num = pattern %[x if isscalar(x) and x > 0]%.
    
     structure Asteroid with
        data size.
        function __init_
           with v:*pos_num do
-             let this @size = v.
+             let this@size = v.
           end
     end
 
@@ -15,7 +14,7 @@
         data size.
        function __init_
           with v:*pos_num do
-             let this @size = v.
+             let this@size = v.
           end
     end
 
diff --git a/asteroid/test-suites/ug-programs/prgm-050.ast b/asteroid/test-suites/ug-programs/prgm-050.ast
index 7e2d67f1..8f2392a2 100644
--- a/asteroid/test-suites/ug-programs/prgm-050.ast
+++ b/asteroid/test-suites/ug-programs/prgm-050.ast
@@ -1,8 +1,7 @@
     load system io.
-    load system type.
 
     try
         let (x,y) = (1,2,3).
     catch e do
-        io @println ("something happened: "+type @tostring(e)).
+        io @println ("something happened: "+ tostring e).
     end
diff --git a/asteroid/test-suites/ug-programs/prgm-051.ast b/asteroid/test-suites/ug-programs/prgm-051.ast
index 9b8599c0..ff4c31cc 100644
--- a/asteroid/test-suites/ug-programs/prgm-051.ast
+++ b/asteroid/test-suites/ug-programs/prgm-051.ast
@@ -2,4 +2,4 @@
 
     let a = 1.
     let b = 2.
-    io @println ("a + b = " + (a + b)).
+    io @println ("a + b = " + tostring (a + b)).
diff --git a/asteroid/test-suites/ug-programs/prgm-052.ast b/asteroid/test-suites/ug-programs/prgm-052.ast
index 98c5d197..2f5e6bd3 100644
--- a/asteroid/test-suites/ug-programs/prgm-052.ast
+++ b/asteroid/test-suites/ug-programs/prgm-052.ast
@@ -1,20 +1,19 @@
     load system io.
-    load system type.
     load system math.
 
     -- if the width specifier is larger than the length of the value
     -- then the value will be right justified
-    let b = type @tostring(true,type @stringformat(10)).
+    let b = tostring(true,stringformat(10)).
     io @println b.
 
-    let i = type @tostring(5,type @stringformat(5)).
+    let i = tostring(5,stringformat(5)).
     io @println i.
 
     -- we can format a string by applying tostring to the string
-    let s = type @tostring("hello there!",type @stringformat(30)).
+    let s = tostring("hello there!",stringformat(30)).
     io @println s.
 
     -- for floating point values: first value is width, second value precision.
     -- if precision is missing then value is left justified and zero padded on right.
-    let r = type @tostring(math @pi,type @stringformat(6,3)).
+    let r = tostring(math@pi,stringformat(6,3)).
     io @println r.
diff --git a/asteroid/test-suites/ug-programs/prgm-054.ast b/asteroid/test-suites/ug-programs/prgm-054.ast
index bac775a6..a988fd08 100644
--- a/asteroid/test-suites/ug-programs/prgm-054.ast
+++ b/asteroid/test-suites/ug-programs/prgm-054.ast
@@ -1,7 +1,6 @@
     load system io.
-    load system type.
 
-    let i if i > 0  = type @tointeger(io @input("Please enter a positive integer value: ")).
+    let i if i > 0  = tointeger(io @input("Please enter a positive integer value: ")).
 
     for k in 1 to i do
         io @println k.
diff --git a/asteroid/test-suites/ug-programs/prgm-055.ast b/asteroid/test-suites/ug-programs/prgm-055.ast
index ff4e64c2..c6d3dddd 100644
--- a/asteroid/test-suites/ug-programs/prgm-055.ast
+++ b/asteroid/test-suites/ug-programs/prgm-055.ast
@@ -1,5 +1,5 @@
     load system io.
     load system math.
 
-    let x = math @sin( math @pi / 2 ).
-    io @println("The sine of pi / 2 is " + x + ".").
+    let x = math @sin( math@pi / 2.0 ).
+    io @println("The sine of pi / 2 is " + tostring x + ".").