     else
       []
 
+  setDefer: (dependencyName) ->
+    @_defer = dependencyName
+
+  shouldDefer: ->
+    @_defer
+
+  addDeferred: (dependencyName, lhs, rhs) ->
+    @_scope().deferred.push [dependencyName, lhs, rhs]
+
+  deferred: ->
+    @_scope().deferred
+
 expressionCompile = (ctx, expression) ->
   throw "invalid expressionCompile args" unless ctx instanceof Context and expression
-  rememberCompiled expression,
-    if isAtom expression
-      atomCompile ctx, expression
-    else if _isTuple expression
-      tupleCompile ctx, expression
-    else if _isSeq expression
-      seqCompile ctx, expression
-    else if isCall expression
-        op = _operator expression
-        if isName op
-          (if op.token of ctx.macros()
-            macroCompile
-          else
-            callCompile) ctx, expression
-        else
-          expandedOp = termCompile ctx, op
-          if isTranslated expandedOp
-            callUnknownTranslate ctx, expandedOp, expression
-          else
-            expressionCompile replicate expression,
-              (call_ (join [expandedOp], (_arguments expression)))
-    else
-      log "Not handled", expression
-      throw "Not handled expression in expressionCompile"
-
-rememberCompiled = (expression, result) ->
-  expression.compiled = result
-
-_compiled = (expression) ->
-  expression.compiled
+  (if isAtom expression
+    atomCompile
+  else if _isTuple expression
+    tupleCompile
+  else if _isSeq expression
+    seqCompile
+  else if isCall expression
+    callCompile
+  else
+    log "Not handled", expression
+    throw "Not handled expression in expressionCompile"
+  ) ctx, expression
+
+# -- This was used to use compiled results from some parent macro while
+#    compiling as something else
+# rememberCompiled = (expression, result) ->
+#   expression.compiled = result
+
+# _compiled = (expression) ->
+#   expression.compiled
 
 callCompile = (ctx, call) ->
+  op = _operator call
+  if isName op
+    (if op.token of ctx.macros()
+      macroCompile
+    else
+      callKnownCompile) ctx, call
+  else
+    expandedOp = termCompile ctx, op
+    if isTranslated expandedOp
+      callUnknownTranslate ctx, expandedOp, call
+    else
+      expressionCompile replicate call,
+        (call_ (join [expandedOp], (_arguments call)))
+
+macroCompile = (ctx, call) ->
+  op = _operator call
+  op.label = 'keyword'
+  expanded = ctx.macros()[op.token] ctx, call
+  if not isWellformed expanded
+    'malformed'
+  else if isTranslated expanded
+    expanded
+  else
+    expressionCompile ctx, expanded
+
+isTranslated = (result) ->
+  typeof result is 'string' or result instanceof String
+
+callKnownCompile = (ctx, call) ->
   operator = _operator call
   args = _labeled _arguments call
   labeledArgs = labeledToMap args

# Type inference and checker ala Mark Jones

unify = (ctx, t1, t2) ->
  sub = ctx.substitution
  ctx.extendSubstitution findSubToMatch (substitute sub, t1), (substitute sub, t2)


    @cacheScopes = [[]]
    @_assignTos = []
    @scopes = [builtInContext this] # dangerous passing itself in constructor
    @_scope().deferred = []
    @_defer = undefined

  macros: ->
    @_macros
