Index: src/ResolvExpr/AlternativeFinder.cc
===================================================================
--- src/ResolvExpr/AlternativeFinder.cc	(revision 02cea2d984751c7c758ec159716a71562ab4c9f7)
+++ src/ResolvExpr/AlternativeFinder.cc	(revision 4e7f0f12366b17b64027e4a7f35e202a91eb6c12)
@@ -174,4 +174,16 @@
 			}
 		}
+
+		// flatten tuple type into list of types
+		template< typename OutputIterator >
+		void flatten( Type * type, OutputIterator out ) {
+			if ( TupleType * tupleType = dynamic_cast< TupleType * >( type ) ) {
+				for ( Type * t : *tupleType ) {
+					flatten( t, out );
+				}
+			} else {
+				*out++ = type;
+			}
+		}
 	}
 
@@ -268,5 +280,10 @@
 		std::list< DeclarationWithType* >::iterator formal = formals.begin();
 		std::list< Expression* >& actuals = appExpr->get_args();
+
+		std::list< Type * > formalTypes;
+		std::list< Type * >::iterator formalType = formalTypes.end();
+
 		for ( std::list< Expression* >::iterator actualExpr = actuals.begin(); actualExpr != actuals.end(); ++actualExpr ) {
+
 			PRINT(
 				std::cerr << "actual expression:" << std::endl;
@@ -277,20 +294,33 @@
 			std::list< DeclarationWithType* >::iterator startFormal = formal;
 			Cost actualCost;
-			for ( std::list< Type* >::iterator actual = (*actualExpr)->get_results().begin(); actual != (*actualExpr)->get_results().end(); ++actual ) {
-				if ( formal == formals.end() ) {
-					if ( function->get_isVarArgs() ) {
-						convCost += Cost( 1, 0, 0 );
-						break;
-					} else {
-						return Cost::infinity;
+			for ( std::list< Type* >::iterator actualType = (*actualExpr)->get_results().begin(); actualType != (*actualExpr)->get_results().end(); ++actualType ) {
+
+				// tuple handling code
+				if ( formalType == formalTypes.end() ) {
+					// the type of the formal parameter may be a tuple type. To make this easier to work with,
+					// flatten the tuple type and traverse the resulting list of types, incrementing the formal
+					// iterator once its types have been extracted. Once a particular formal parameter's type has
+					// been exhausted load the next formal parameter's type.
+					if ( formal == formals.end() ) {
+						if ( function->get_isVarArgs() ) {
+							convCost += Cost( 1, 0, 0 );
+							break;
+						} else {
+							return Cost::infinity;
+						}
 					}
+					formalTypes.clear();
+					flatten( (*formal)->get_type(), back_inserter( formalTypes ) );
+					formalType = formalTypes.begin();
+					++formal;
 				}
+
 				PRINT(
 					std::cerr << std::endl << "converting ";
-					(*actual)->print( std::cerr, 8 );
+					(*actualType)->print( std::cerr, 8 );
 					std::cerr << std::endl << " to ";
 					(*formal)->get_type()->print( std::cerr, 8 );
 				)
-				Cost newCost = conversionCost( *actual, (*formal)->get_type(), indexer, alt.env );
+				Cost newCost = conversionCost( *actualType, *formalType, indexer, alt.env );
 				PRINT(
 					std::cerr << std::endl << "cost is" << newCost << std::endl;
@@ -303,7 +333,7 @@
 				actualCost += newCost;
 
-				convCost += Cost( 0, polyCost( (*formal)->get_type(), alt.env, indexer ) + polyCost( *actual, alt.env, indexer ), 0 );
-
-				formal++;
+				convCost += Cost( 0, polyCost( *formalType, alt.env, indexer ) + polyCost( *actualType, alt.env, indexer ), 0 );
+
+				formalType++;
 			}
 			if ( actualCost != Cost( 0, 0, 0 ) ) {
@@ -380,8 +410,23 @@
 		*/
 		std::list< DeclarationWithType* >::iterator formal = formals.begin();
+
+		std::list< Type * > formalTypes;
+		std::list< Type * >::iterator formalType = formalTypes.end();
+
 		for ( AltList::const_iterator actualExpr = actuals.begin(); actualExpr != actuals.end(); ++actualExpr ) {
-			for ( std::list< Type* >::iterator actual = actualExpr->expr->get_results().begin(); actual != actualExpr->expr->get_results().end(); ++actual ) {
-				if ( formal == formals.end() ) {
-					return isVarArgs;
+			std::list< Type* > & actualTypes = actualExpr->expr->get_results();
+			for ( std::list< Type* >::iterator actualType = actualTypes.begin(); actualType != actualTypes.end(); ++actualType ) {
+				if ( formalType == formalTypes.end() ) {
+					// the type of the formal parameter may be a tuple type. To make this easier to work with,
+					// flatten the tuple type and traverse the resulting list of types, incrementing the formal
+					// iterator once its types have been extracted. Once a particular formal parameter's type has
+					// been exhausted load the next formal parameter's type.
+					if ( formal == formals.end() ) {
+						return isVarArgs;
+					}
+					formalTypes.clear();
+					flatten( (*formal)->get_type(), back_inserter( formalTypes ) );
+					formalType = formalTypes.begin();
+					++formal;
 				}
 				PRINT(
@@ -389,13 +434,18 @@
 					(*formal)->get_type()->print( std::cerr );
 					std::cerr << std::endl << "actual type is ";
-					(*actual)->print( std::cerr );
+					(*actualType)->print( std::cerr );
 					std::cerr << std::endl;
 				)
-				if ( ! unify( (*formal)->get_type(), *actual, resultEnv, resultNeed, resultHave, openVars, indexer ) ) {
+				if ( ! unify( *formalType, *actualType, resultEnv, resultNeed, resultHave, openVars, indexer ) ) {
 					return false;
 				}
-				formal++;
-			}
-		}
+				++formalType;
+			}
+		}
+
+		// xxx - a tuple type was not completely matched
+		// partially handle the tuple with default arguments??
+		if ( formalType != formalTypes.end() ) return false;
+
 		// Handling of default values
 		while ( formal != formals.end() ) {
Index: src/ResolvExpr/AlternativeFinder.h
===================================================================
--- src/ResolvExpr/AlternativeFinder.h	(revision 02cea2d984751c7c758ec159716a71562ab4c9f7)
+++ src/ResolvExpr/AlternativeFinder.h	(revision 4e7f0f12366b17b64027e4a7f35e202a91eb6c12)
@@ -67,4 +67,6 @@
 		virtual void visit( ImplicitCopyCtorExpr * impCpCtorExpr );
 	  public:  // xxx - temporary hack - should make Tuples::TupleAssignment a friend
+	  /// Runs a new alternative finder on each element in [begin, end)
+	  /// and writes each alternative finder to out.
 		template< typename InputIterator, typename OutputIterator >
 		void findSubExprs( InputIterator begin, InputIterator end, OutputIterator out );
