     funcName = @variable.unwrapAll().value
     funcVariable = o.namespace.find funcName
     throw SyntaxError "undefined variable \"#{funcName}\"" unless funcVariable?
-    unless funcVariable.type.basic is "func"
-      throw SyntaxError "can't call variable \"#{funcName}\" of type \"#{funcVariable.type.string}\""
-    unless funcVariable.type.args.length is @argNodes.length
-      throw SyntaxError "function \"#{funcName}\" takes #{funcVariable.type.args.length} argument, not #{@argNodes.length}"
+    funcType = funcVariable.type.findRoot()
+    unless funcType.basic is "func"
+      throw SyntaxError "can't call variable \"#{funcName}\" of type \"#{funcType.string}\""
+    unless funcType.args.length is @argNodes.length
+      throw SyntaxError "function \"#{funcName}\" takes #{funcType.args.length} argument, not #{@argNodes.length}"
     args = []
     for argNode in @argNodes
       arg = argNode.unwrapAll().compileExpression o
       forbidVoid arg
       args.push arg
-    callType = new Type "func", (arg.type for arg in args)
-    linkTypes funcVariable.type, callType
-
+    callType = new Type "func", (arg.type for arg in args), new Type
+    linkTypes funcType, callType
+    # good news, guys: you're parameter types are now known!
+    for codeNode in callType.findRoot().codeNodes
+      codeNode.compileFunc o
     codes = ("set push, #{arg.access}" for arg in args)
     codes.push "jsr #{funcVariable.label}"
     return codes.join("\n")

NEGATE  = -> @negated = not @negated; this

class Type
  constructor: (@basic, @args=[], @returnType) ->
    @synonym = this
    if @basic is "func" and not @returnType?
      @returnType = new Type
  findRoot: ->
    return this if this is @synonym
    return @synonym = @synonym.findRoot()
voidType = new Type "void"
intType = new Type "int"
stringType = new Type "string"

    linkTypes leftArg, rightArg
  linkTypes leftType.returnType, rightType.returnType
  # seems legit
  leftType.linkTo rightType

class Variable
  constructor: (@label, @type, @namespace) ->
