   finalType = substitute ctx.substitution, type
   # log op, (printType type), printType finalType
   classParams =
-    if op.ir is irMethodTranslate
+    if op.ir is irReferenceTranslate and ctx.isMethod op.name, op.type
       []
     else
       dictsForConstraint ctx, finalType.constraints
-  (jsCall (translateIr ctx, op), (join classParams, (translateIr ctx, args)))
+  op =
+    if op.ir is irReferenceTranslate and not ctx.isMethod op.name, op.type
+      validIdentifier op.name
+    else
+      translateIr ctx, op
+  (jsCall op, (join classParams, (translateIr ctx, args)))
+
+
+irReference = (name, type, arity) ->
+  {ir: irReferenceTranslate, name, type, arity}
+
+irReferenceTranslate = (ctx, {name, type, arity}) ->
+  if ctx.isMethod name, type
+    translateIr ctx, (irMethod type, name)
+  else
+    finalType = substitute ctx.substitution, type
+    classParams = dictsForConstraint ctx, finalType.constraints
+    if classParams.length > 0
+      (irFunctionTranslate ctx,
+        params: arity
+        body: [(jsReturn (jsCall (validIdentifier name), (join classParams, arity)))])
+    else
+      validIdentifier name
+
 
 irMethod = (type, name) ->
   {ir: irMethodTranslate, type, name}

          # })"""
          (irFunction
            name: (ctx.definitionName() if ctx.isAtSimpleDefinition())
            type: call.tea
            params: paramNames
            body: (join compiledWheres, [(jsReturn compiledBody)]))
            # (jsCall "λ#{paramNames.length}", [

    [x y] (f ["A" "B"])
  """
  """x""", "A"

  'higher-order use of constrained function'
  """
    Show (class [a]
      show (fn [x] (: (Fn a String))))

    show-string (instance (Show String)
      show (fn [x] x))

    f (fn [pair]
      [(show a) (show b)]
      [a b] pair)

    apply (fn [m to]
      (m to))

    [x y] (apply f ["A" "B"])
  """
  """x""", "A"
  # The following doesn't work because the Collection type class specifies
  # that the constructor takes only one argument.
  #
