     node.tea = subExp s, node.tea if node.tea
 
 inferWheres = (context, pairs, nameIndex) ->
+  # 1st find all classes
+
+  # 2nd find all declarations
   for [name, def] in pairs
-    addToMap context, name.token, freshName nameIndex++
+    [nameIndex, type] = freshOrDeclared def, nameIndex
+    addToMap context, name.token, type
+
+  # 3rd type check
   for [name, def] in pairs
     [s1, nameIndex, def] = infer context, def, nameIndex
     s2 = unify (subExp s1, (inSet context, name.token)), def.tea

keywords = 'def defn data class fn proc match if type :: \\
            access call new
            require'.split ' '


  params = if Array.isArray(paramList) then paramList else undefined
  defs ?= []
  for def, i in defs
    if matchNode '->', def
      type = def
    else if matchNode '#', def
      doc = def
    if not matchAnyNode ['->', '#'], def
      implementation = defs[i...]
      break
  {body, wheres} = fnImplementation implementation ? []
  {params, type, doc, body, wheres}

classDefinition = (node) ->
  words = inside node
  [keyword, paramList, defs...] = words
  params = if Array.isArray(paramList) then paramList else undefined
  defs ?= []
  if defs.length > 0
    [first] = defs
    if Array.isArray first
      context = first
      defs = defs[1..]
  wheres = whereList defs
  {params, context, wheres}

instanceDefinition = (node) ->
  words = inside node
  [keyword, klass, defs...] = words
  wheres = whereList defs
  {klass, wheres}

fnImplementation = (defs) ->
  [body, where...] = defs
