   map.values[key] = value
   map
 
+lookupOrAdd = (map, key, value) ->
+  if existing = map.values[key]
+    existing
+  else
+    map.size++
+    map.values[key] = value
+    value
+
 removeFromSet =
 removeFromMap = (set, key) ->
   return if !set.values[key]?

      ctx.addToDeferred
        name: name
        type: currentType
        deps: (map (({name}) -> name), deps)
      for dep in deps
        ctx.addToDeferred {name: dep.name, type: dep.type, reversed: name}
      ctx.assignType name, (new TempType type)
    else
      # Ready for typing since there are no missing dependencies
      inferType ctx, name, type, matched.tea.constraints, polymorphic

  precs: precs ? []
  assigns: assigns ? []

      translateIr ctx, op
  (jsCall op, (join classParams, (translateIr ctx, args)))

addConstraintsFrom = (ctx, {name, type}, to) ->
  typed = ctx.type name
  if typed and _empty to.constraints
    inferredType = freshInstance ctx, typed
    sub = matchType inferredType.type, (substitute ctx.substitution, type).type
    addConstraints to, (substitute sub, inferredType).constraints
  else
    to

irReference = (name, type, arity) ->
  {ir: irReferenceTranslate, name, type, arity}
