diff --git a/HISTORY.md b/HISTORY.md
index 0fe64ef..5f90f6c 100644
--- a/HISTORY.md
+++ b/HISTORY.md
@@ -12,11 +12,18 @@
     the macro itself as the first argument to the macro.)
     The Robin definitions of macros in the standard library
     such as `let` and `list` have been rewritten this way.
+*   The object that a `macro` form evaluates to is no
+    longer called a "macro".  It is an "operator".  There
+    there are other ways to obtain an operator than applying
+    a `macro` form (for instance there have always been
+    intrinsic operators; it's not fair to call them "macros".)
 
 For the reference implementation,
 
 *   Fixed recent import changes which prevented it from
     running under Hugs.
+*   The `Macro` type of expressions has been removed,
+    and `Builtin` renamed `Operator`.
 
 Robin 0.7
 ---------
diff --git a/build-packages.sh b/build-packages.sh
index 8ecb8e6..844f8b0 100755
--- a/build-packages.sh
+++ b/build-packages.sh
@@ -5,7 +5,7 @@
 mkdir -p pkg
 
 cat stdlib/abort.robin stdlib/equal-p.robin stdlib/eval.robin stdlib/head.robin \
-    stdlib/if.robin stdlib/list-p.robin stdlib/macro-p.robin stdlib/macro.robin \
+    stdlib/if.robin stdlib/list-p.robin stdlib/operator-p.robin stdlib/macro.robin \
     stdlib/number-p.robin stdlib/prepend.robin stdlib/recover.robin stdlib/sign.robin \
     stdlib/subtract.robin stdlib/symbol-p.robin stdlib/tail.robin \
     > pkg/intrinsics.robin
diff --git a/doc/Robin.md b/doc/Robin.md
index 5c688c4..7c4169a 100644
--- a/doc/Robin.md
+++ b/doc/Robin.md
@@ -314,6 +314,8 @@
 
 ### Macros ###
 
+TODO rewrite this section
+
 A macro is a term which, in an environment, describes how to
 translate one S-expression to another.
 
@@ -344,13 +346,13 @@
 
 Macros evaluate to themselves.
 
-Macros are represented as the S-expression expansion of their
-implementation.
+Operators are represented as an opaque descriptor (TODO this should be the
+metadata of the operator.)
 
     | (macro (args env) args)
-    = (macro (args env) args)
-
-Macros can be applied, and that is the typical use of them.
+    = <macro>
+
+Operators can be applied, and that is the typical use of them.
 
     | ((macro (args env) args) 1)
     = (1)
diff --git a/src/Language/Robin/Eval.hs b/src/Language/Robin/Eval.hs
index 60f0e70..c0ef552 100644
--- a/src/Language/Robin/Eval.hs
+++ b/src/Language/Robin/Eval.hs
@@ -39,16 +39,13 @@
 --
 -- Evaluating a list means we must make several evaluations.  We
 -- evaluate the head to obtain something to apply (which must be a
--- macro or intrinsic.)  We then apply the body of the macro,
--- passing it the tail of the list.
+-- "builtin".)  We then apply the "builtin", passing it the tail of the list.
 --
 
 eval env (List (applierExpr:actuals)) cc =
     eval env applierExpr (\applier ->
         case applier of
-            m@(Macro _ _ body) ->
-                eval (makeMacroEnv env (List actuals) m) body cc
-            b@(Builtin _ fun) ->
+            Builtin _ fun ->
                 fun env (List actuals) cc
             other ->
                 errMsg "inapplicable-object" other)
@@ -68,14 +65,22 @@
 errMsg msg term =
     Abort (List [(Symbol msg), term])
 
-makeMacroEnv :: Env -> Expr -> Expr -> Env
-makeMacroEnv env actuals m@(Macro closedEnv argList _)  =
+makeMacro :: Expr -> Expr -> Expr -> Evaluable
+makeMacro defineTimeEnv formals body =
+    \callTimeEnv actuals cc ->
+        let
+            env = makeMacroEnv callTimeEnv actuals defineTimeEnv formals
+        in
+            eval env body cc
+
+makeMacroEnv callTimeEnv actuals defineTimeEnv argList =
     let
         (List [(Symbol argFormal), (Symbol envFormal)]) = argList
-        newEnv' = insert argFormal actuals closedEnv
-        newEnv'' = insert envFormal env newEnv'
+        newEnv' = insert argFormal actuals defineTimeEnv
+        newEnv'' = insert envFormal callTimeEnv newEnv'
     in
         newEnv''
+
 
 --
 -- Assertions
@@ -90,4 +95,4 @@
 assertBoolean env = assert env (isBoolean) "expected-boolean"
 assertList env = assert env (isList) "expected-list"
 assertNumber env = assert env (isNumber) "expected-number"
-assertMacro env = assert env (isMacro) "expected-macro"
+assertOperator env = assert env (isOperator) "expected-operator"
diff --git a/src/Language/Robin/Expr.hs b/src/Language/Robin/Expr.hs
index ab2ef42..2bf6a55 100644
--- a/src/Language/Robin/Expr.hs
+++ b/src/Language/Robin/Expr.hs
@@ -20,7 +20,6 @@
 data Expr = Symbol String
           | Boolean Bool
           | Number Int32
-          | Macro Expr Expr Expr      -- the 1st Expr is actually an Env
           | Builtin String Evaluable
           | List [Expr]
           | Abort Expr
@@ -29,7 +28,6 @@
     (Symbol x) == (Symbol y)             = x == y
     (Boolean x) == (Boolean y)           = x == y
     (Number x) == (Number y)             = x == y
-    (Macro e1 a1 b1) == (Macro e2 a2 b2) = e1 == e2 && a1 == a2 && b1 == b2
     (Builtin x _) == (Builtin y _)       = x == y
     (List x) == (List y)                 = x == y
     (Abort x) == (Abort y)               = x == y
@@ -40,8 +38,6 @@
     show (Boolean True)        = "#t"
     show (Boolean False)       = "#f"
     show (Number n)            = show n
-    show (Macro env args body) = ("(macro " ++ (show args) ++
-                                  " " ++ (show body) ++ ")")
     show (Builtin name _)      = name
     show (Abort e)             = "(abort " ++ (show e) ++ ")"
     show (List exprs)          = "(" ++ (showl exprs) ++ ")" where
@@ -72,9 +68,8 @@
 isList (List _) = True
 isList _        = False
 
-isMacro (Macro _ _ _) = True
-isMacro (Builtin _ _) = True
-isMacro _             = False
-
 isAbort (Abort _) = True
 isAbort _         = False
+
+isOperator (Builtin _ _) = True
+isOperator _             = False
diff --git a/src/Language/Robin/Intrinsics.hs b/src/Language/Robin/Intrinsics.hs
index 0538be8..72b1d30 100644
--- a/src/Language/Robin/Intrinsics.hs
+++ b/src/Language/Robin/Intrinsics.hs
@@ -42,7 +42,7 @@
 
 symbolP = predP isSymbol
 listP = predP isList
-macroP = predP isMacro
+operatorP = predP isOperator
 numberP = predP isNumber
 
 subtract :: Evaluable
@@ -80,7 +80,7 @@
 
 macro :: Evaluable
 macro env (List [args@(List [(Symbol argsS), (Symbol envS)]), body]) cc =
-    cc $ Macro env args body
+    cc $ Builtin "<macro>" $ makeMacro env args body
 macro env other cc = errMsg "illegal-arguments" other
 
 abort :: Evaluable
@@ -106,7 +106,7 @@
         ("prepend",  prepend),
         ("list?",    listP),
         ("symbol?",  symbolP),
-        ("macro?",   macroP),
+        ("operator?",operatorP),
         ("number?",  numberP),
         ("equal?",   equalP),
         ("subtract", Language.Robin.Intrinsics.subtract),
diff --git a/src/QuickCheckTests.hs b/src/QuickCheckTests.hs
index 7635e5e..955346a 100644
--- a/src/QuickCheckTests.hs
+++ b/src/QuickCheckTests.hs
@@ -34,8 +34,8 @@
           let n' = n `div` (m + 1)
           oneof [
                    Abort <$> (arbExpr n'),
-                   List <$> (arbExprList n'),
-                   Macro <$> (arbExpr n') <*> (arbExpr n') <*> (arbExpr n')
+                   List <$> (arbExprList n')
+                   -- TODO Operator ??
                 ]
 
         arbExprList :: Int -> Gen [Expr]
diff --git a/stdlib/macro-p.robin b/stdlib/macro-p.robin
deleted file mode 100644
index 7227c1d..0000000
--- a/stdlib/macro-p.robin
+++ /dev/null
@@ -1,39 +0,0 @@
-;'<<SPEC'
-
-### `macro?` ###
-
-    -> Tests for functionality "Evaluate core Robin Expression"
-
-`macro?` evaluates its argument, then evaluates to `#t` if it is a macro,
-or `#f` if it is not.
-
-    | (macro? (macro (args env) args))
-    = #t
-
-Intrinsic macros are macros.
-
-    | (macro? macro)
-    = #t
-
-Literal symbols are not macros, even if they're the name of one.
-
-    | (macro? ((macro (args env) (head args)) macro))
-    = #f
-
-Numbers are not macros.
-
-    | (macro? 5)
-    = #f
-
-The argument to `macro?` may (naturally) be any type, but there must be
-exactly one argument.
-
-    | (macro? macro macro)
-    ? abort (illegal-arguments (macro macro))
-
-    | (macro?)
-    ? abort (illegal-arguments ())
-
-'<<SPEC'
-
-(require macro?)
diff --git a/stdlib/operator-p.robin b/stdlib/operator-p.robin
new file mode 100644
index 0000000..cfc39e7
--- /dev/null
+++ b/stdlib/operator-p.robin
@@ -0,0 +1,39 @@
+;'<<SPEC'
+
+### `operator?` ###
+
+    -> Tests for functionality "Evaluate core Robin Expression"
+
+`operator?` evaluates its argument, then evaluates to `#t` if it is an operator,
+or `#f` if it is not.
+
+    | (operator? (macro (args env) args))
+    = #t
+
+Intrinsic operators are operators.
+
+    | (operator? macro)
+    = #t
+
+Literal symbols are not operators, even if they're the name of one.
+
+    | (operator? ((macro (args env) (head args)) macro))
+    = #f
+
+Numbers are not operators.
+
+    | (operator? 5)
+    = #f
+
+The argument to `operator?` may (naturally) be any type, but there must be
+exactly one argument.
+
+    | (operator? macro macro)
+    ? abort (illegal-arguments (macro macro))
+
+    | (operator?)
+    ? abort (illegal-arguments ())
+
+'<<SPEC'
+
+(require operator?)