   return if set.values[key]
   set.size += 1
   set.values[key] = value
+  set
 
 removeFromSet =
 removeFromMap = (set, key) ->

  clone = newSet()
  addAllToSet clone, setToArray set

inSet = (set, name) ->
  set.values[name]

isSetEmpty = (set) ->
  set.size is 0

lookupInMap = (set, key) ->
  set.values[key]

unionMaps = (first, second) ->
  union = (cloneSet first)


infer = (context, expression, nameIndex) ->
  switch expression.label
    when 'numerical' then [newMap(), 'Num']
    when 'string' then [newMap(), 'Text']
    else
      # Reference
      if isReference expression
        # TODO: replace free type variables with new unused names
        [newMap(), lookupInMap context, expression.token]
      # Lambda
      else if expression.type is 'function'
        {params, body, wheres} = fnDefinition expression
