Index: src/ResolvExpr/Alternative.h
===================================================================
--- src/ResolvExpr/Alternative.h	(revision a8b27c63155718a34534b0647bd76f979bc66cdf)
+++ src/ResolvExpr/Alternative.h	(revision 62194cbf579b5084c2ebfafd9003eb7b9cb0fa7b)
@@ -37,4 +37,11 @@
 		void print( std::ostream &os, Indenter indent = {} ) const;
 
+		/// Returns the stored expression, but released from management of this Alternative
+		Expression* release_expr() {
+			Expression* tmp = expr;
+			expr = nullptr;
+			return tmp;
+		}
+
 		Cost cost;
 		Cost cvtCost;
Index: src/ResolvExpr/AlternativeFinder.cc
===================================================================
--- src/ResolvExpr/AlternativeFinder.cc	(revision a8b27c63155718a34534b0647bd76f979bc66cdf)
+++ src/ResolvExpr/AlternativeFinder.cc	(revision 62194cbf579b5084c2ebfafd9003eb7b9cb0fa7b)
@@ -676,23 +676,18 @@
 					auto nextArg = results[i].nextArg;
 
-					// use remainder of exploded tuple if present
+					// use next element of exploded tuple if present
 					if ( results[i].hasExpl() ) {
 						const ExplodedActual& expl = results[i].getExpl( args );
-						const Alternative& actual = expl.alts[results[i].nextExpl];
 						
-						TypeEnvironment env = results[i].env;
-						OpenVarSet openVars = results[i].openVars;
-
-						env.addActual( actual.env, openVars );
-
 						unsigned nextExpl = results[i].nextExpl + 1;
-						if ( nextExpl == expl.alts.size() ) {
+						if ( nextExpl == expl.exprs.size() ) {
 							nextExpl = 0;
 						}
 
 						results.emplace_back(
-							i, actual.expr, move(env), copy(results[i].need), 
-							copy(results[i].have), move(openVars), nextArg, nTuples, 
-							Cost::zero, nextExpl, results[i].explAlt );
+							i, expl.exprs[results[i].nextExpl].get(), copy(results[i].env), 
+							copy(results[i].need), copy(results[i].have), 
+							copy(results[i].openVars), nextArg, nTuples, Cost::zero, nextExpl, 
+							results[i].explAlt );
 						
 						continue;
@@ -758,5 +753,5 @@
 
 						// skip empty tuple arguments by (near-)cloning parent into next gen
-						if ( expl.alts.empty() ) {
+						if ( expl.exprs.empty() ) {
 							results.emplace_back(
 								results[i], move(env), copy(results[i].need), 
@@ -768,7 +763,7 @@
 						// add new result
 						results.emplace_back(
-							i, expl.alts.front().expr, move(env), copy(results[i].need), 
+							i, expl.exprs.front().get(), move(env), copy(results[i].need), 
 							copy(results[i].have), move(openVars), nextArg + 1, 
-							nTuples, expl.cost, expl.alts.size() == 1 ? 0 : 1, j );
+							nTuples, expl.cost, expl.exprs.size() == 1 ? 0 : 1, j );
 					}
 				}
@@ -794,5 +789,5 @@
 			if ( results[i].hasExpl() ) {
 				const ExplodedActual& expl = results[i].getExpl( args );
-				const Alternative& actual = expl.alts[results[i].nextExpl];
+				Expression* expr = expl.exprs[results[i].nextExpl].get();
 				
 				TypeEnvironment env = results[i].env;
@@ -800,6 +795,5 @@
 				OpenVarSet openVars = results[i].openVars;
 
-				env.addActual( actual.env, openVars );
-				Type* actualType = actual.expr->get_result();
+				Type* actualType = expr->get_result();
 
 				PRINT(
@@ -813,11 +807,11 @@
 				if ( unify( formalType, actualType, env, need, have, openVars, indexer ) ) {
 					unsigned nextExpl = results[i].nextExpl + 1;
-					if ( nextExpl == expl.alts.size() ) {
+					if ( nextExpl == expl.exprs.size() ) {
 						nextExpl = 0;
 					}
 					
 					results.emplace_back( 
-						i, actual.expr, move(env), move(need), move(have), move(openVars), 
-						nextArg, nTuples, Cost::zero, nextExpl, results[i].explAlt );
+						i, expr, move(env), move(need), move(have), move(openVars), nextArg, 
+						nTuples, Cost::zero, nextExpl, results[i].explAlt );
 				}
 
@@ -857,5 +851,5 @@
 				
 				// skip empty tuple arguments by (near-)cloning parent into next gen
-				if ( expl.alts.empty() ) {
+				if ( expl.exprs.empty() ) {
 					results.emplace_back(
 						results[i], move(env), move(need), move(have), move(openVars), 
@@ -866,6 +860,6 @@
 
 				// consider only first exploded actual
-				const Alternative& actual = expl.alts.front();
-				Type* actualType = actual.expr->get_result()->clone();
+				Expression* expr = expl.exprs.front().get();
+				Type* actualType = expr->get_result()->clone();
 
 				PRINT(
@@ -881,6 +875,6 @@
 					// add new result
 					results.emplace_back(
-						i, actual.expr, move(env), move(need), move(have), move(openVars),
-						nextArg + 1, nTuples, expl.cost, expl.alts.size() == 1 ? 0 : 1, j );
+						i, expr, move(env), move(need), move(have), move(openVars), nextArg + 1, 
+						nTuples, expl.cost, expl.exprs.size() == 1 ? 0 : 1, j );
 				}
 			}
@@ -962,20 +956,15 @@
 					if ( results[i].hasExpl() ) {
 						const ExplodedActual& expl = results[i].getExpl( args );
-						const Alternative& actual = expl.alts[results[i].nextExpl];
 						
-						TypeEnvironment env = results[i].env;
-						OpenVarSet openVars = results[i].openVars;
-
-						env.addActual( actual.env, openVars );
-
 						unsigned nextExpl = results[i].nextExpl + 1;
-						if ( nextExpl == expl.alts.size() ) {
+						if ( nextExpl == expl.exprs.size() ) {
 							nextExpl = 0;
 						}
 
 						results.emplace_back(
-							i, actual.expr, move(env), copy(results[i].need), 
-							copy(results[i].have), move(openVars), nextArg, 0, 
-							Cost::zero, nextExpl, results[i].explAlt );
+							i, expl.exprs[results[i].nextExpl].get(), copy(results[i].env), 
+							copy(results[i].need), copy(results[i].have), 
+							copy(results[i].openVars), nextArg, 0, Cost::zero, nextExpl, 
+							results[i].explAlt );
 						
 						continue;
@@ -1000,5 +989,5 @@
 
 						// skip empty tuple arguments by (near-)cloning parent into next gen
-						if ( expl.alts.empty() ) {
+						if ( expl.exprs.empty() ) {
 							results.emplace_back( 
 								results[i], move(env), copy(results[i].need), 
@@ -1010,7 +999,7 @@
 						// add new result
 						results.emplace_back(
-							i, expl.alts.front().expr, move(env), copy(results[i].need), 
+							i, expl.exprs.front().get(), move(env), copy(results[i].need), 
 							copy(results[i].have), move(openVars), nextArg + 1, 0, 
-							expl.cost, expl.alts.size() == 1 ? 0 : 1, j );
+							expl.cost, expl.exprs.size() == 1 ? 0 : 1, j );
 					}
 				}
Index: src/ResolvExpr/ExplodedActual.cc
===================================================================
--- src/ResolvExpr/ExplodedActual.cc	(revision a8b27c63155718a34534b0647bd76f979bc66cdf)
+++ src/ResolvExpr/ExplodedActual.cc	(revision 62194cbf579b5084c2ebfafd9003eb7b9cb0fa7b)
@@ -20,6 +20,6 @@
 namespace ResolvExpr {
 	ExplodedActual::ExplodedActual( const Alternative& actual, const SymTab::Indexer& indexer ) 
-			: env(actual.env), cost(actual.cost), alts() {
-		Tuples::explode( actual, indexer, back_inserter( alts ) );
+			: env(actual.env), cost(actual.cost), exprs() {
+		Tuples::explode( actual, indexer, *this );
 	}
 }
Index: src/ResolvExpr/ExplodedActual.h
===================================================================
--- src/ResolvExpr/ExplodedActual.h	(revision a8b27c63155718a34534b0647bd76f979bc66cdf)
+++ src/ResolvExpr/ExplodedActual.h	(revision 62194cbf579b5084c2ebfafd9003eb7b9cb0fa7b)
@@ -16,4 +16,7 @@
 #pragma once
 
+#include <memory>
+#include <vector>
+
 #include "Alternative.h"      // for Alternative, AltList
 #include "Cost.h"             // for Cost
@@ -26,9 +29,9 @@
 		TypeEnvironment env;
 		Cost cost;
-		AltList alts;  // TODO flatten this down to vector<unique_ptr<Expression>>
+		std::vector< std::unique_ptr<Expression> > exprs;
 
-		ExplodedActual() : env(), cost(Cost::zero), alts() {}
+		ExplodedActual() : env(), cost(Cost::zero), exprs() {}
 
-		ExplodedActual( const Alternative& actual, const SymTab::Indexer& indexer );	
+		ExplodedActual( const Alternative& actual, const SymTab::Indexer& indexer );
 	};
 }
