function applyEachOptimization(rel){

	var originalRel = rel
	rel = JSON.parse(JSON.stringify(rel))	
	
	//console.log('rel: ' + JSON.stringify(rel))
	try{
		var newImplicits = [rel.params[1].implicits[0]]
		var bindingsUsed = _.extend({}, rel.params[1].bindingsUsed)
		//1. extract macro params to one or more ~:property maps
		var maps = []
		var failed = false
		var newMacroExpr = replaceMacroPropertyExpressions(rel.params[1].expr, rel.params[1].implicits, function(macroPropertyExpr){
			if(macroPropertyExpr.schemaType.type === 'map'){
				failed = true
				return
			}
			var uid = 'extproperty_'+Math.random()
			var bu = {}
			bu[uid] = true
			var m = {
				type: 'view', 
				view: 'map', 
				params: [
					rel.params[0],
					{	
						type: 'macro', 
						manyImplicits: 1, 
						expr: {type: 'param', name: uid, schemaType: rel.params[0].schemaType.members}, 
						bindingsUsed: bu, 
						implicits: [uid], 
						schemaType: rel.params[0].schemaType.members,
						implicitTypes: [rel.params[0].schemaType.members]
					},{
						type: 'macro', 
						manyImplicits: 1, 
						expr: JSON.parse(JSON.stringify(macroPropertyExpr)), 
						bindingsUsed: bu, 
						implicits: [rel.params[1].implicits[0]], 
						schemaType: macroPropertyExpr.schemaType,
						implicitTypes: [rel.params[1].implicitTypes[0]]
					}
				], 
				willBeOptimized: true,
				uid: uid
			}
			m.schemaType = {type: 'map', key: m.params[1].schemaType, value: m.params[2].schemaType}
			maps.push(applyEachOptimizationToView(m))
			newImplicits.push(uid)
			bindingsUsed[uid] = true
			_.assertDefined(macroPropertyExpr.schemaType)
			return {type: 'param', name: uid, schemaType: macroPropertyExpr.schemaType}
		})
		if(failed) return originalRel
		var newMacro = {
			type: 'macro',
			expr: newMacroExpr,
			manyImplicits: newImplicits.length,
			implicits: newImplicits,
			implicitTypes: [rel.params[0].schemaType.members],
			bindingsUsed: bindingsUsed,//newImplicits
			schemaType: newMacroExpr.schemaType
		}
		//console.log('created m: ' + JSON.stringify(newMacro, null, 2))
		return {
			type: 'view',
			view: 'each-optimization',
			params: [rel.params[0], newMacro].concat(maps),
			schemaType: rel.schemaType,
			code: rel.code
		}
	}catch(e){
		//console.log('could not optimize each + e.stack)
		return originalRel
	}
}
function applyEachOptimization(rel){

	var originalRel = rel
	rel = JSON.parse(JSON.stringify(rel))	
	
	
	try{
		var newImplicits = [rel.params[1].implicits[0]]
		var bindingsUsed = _.extend({}, rel.params[1].bindingsUsed)
		
		var maps = []
		var failed = false
		var newMacroExpr = replaceMacroPropertyExpressions(rel.params[1].expr, rel.params[1].implicits, function(macroPropertyExpr){
			if(macroPropertyExpr.schemaType.type === 'map'){
				failed = true
				return
			}
			var uid = 'extproperty_'+Math.random()
			var bu = {}
			bu[uid] = true
			var m = {
				type: 'view', 
				view: 'map', 
				params: [
					rel.params[0],
					{	
						type: 'macro', 
						manyImplicits: 1, 
						expr: {type: 'param', name: uid, schemaType: rel.params[0].schemaType.members}, 
						bindingsUsed: bu, 
						implicits: [uid], 
						schemaType: rel.params[0].schemaType.members,
						implicitTypes: [rel.params[0].schemaType.members]
					},{
						type: 'macro', 
						manyImplicits: 1, 
						expr: JSON.parse(JSON.stringify(macroPropertyExpr)), 
						bindingsUsed: bu, 
						implicits: [rel.params[1].implicits[0]], 
						schemaType: macroPropertyExpr.schemaType,
						implicitTypes: [rel.params[1].implicitTypes[0]]
					}
				], 
				willBeOptimized: true,
				uid: uid
			}
			m.schemaType = {type: 'map', key: m.params[1].schemaType, value: m.params[2].schemaType}
			maps.push(applyEachOptimizationToView(m))
			newImplicits.push(uid)
			bindingsUsed[uid] = true
			_.assertDefined(macroPropertyExpr.schemaType)
			return {type: 'param', name: uid, schemaType: macroPropertyExpr.schemaType}
		})
		if(failed) return originalRel
		var newMacro = {
			type: 'macro',
			expr: newMacroExpr,
			manyImplicits: newImplicits.length,
			implicits: newImplicits,
			implicitTypes: [rel.params[0].schemaType.members],
			bindingsUsed: bindingsUsed,
			schemaType: newMacroExpr.schemaType
		}
		
		return {
			type: 'view',
			view: 'each-optimization',
			params: [rel.params[0], newMacro].concat(maps),
			schemaType: rel.schemaType,
			code: rel.code
		}
	}catch(e){
		
		return originalRel
	}
}
function applyEachOptimization ( rel ) { var originalRel = rel rel = JSON . parse ( JSON . stringify ( rel ) ) //console.log('rel: ' + JSON.stringify(rel)) try { var newImplicits = [ rel . params [ 1 ] . implicits [ 0 ] ] var bindingsUsed = _ . extend ( { } , rel . params [ 1 ] . bindingsUsed ) //1. extract macro params to one or more ~:property maps var maps = [ ] var failed = false var newMacroExpr = replaceMacroPropertyExpressions ( rel . params [ 1 ] . expr , rel . params [ 1 ] . implicits , function ( macroPropertyExpr ) { if ( macroPropertyExpr . schemaType . type === 'map' ) { failed = true return } var uid = 'extproperty_' + Math . random ( ) var bu = { } bu [ uid ] = true var m = { type : 'view' , view : 'map' , params : [ rel . params [ 0 ] , { type : 'macro' , manyImplicits : 1 , expr : { type : 'param' , name : uid , schemaType : rel . params [ 0 ] . schemaType . members } , bindingsUsed : bu , implicits : [ uid ] , schemaType : rel . params [ 0 ] . schemaType . members , implicitTypes : [ rel . params [ 0 ] . schemaType . members ] } , { type : 'macro' , manyImplicits : 1 , expr : JSON . parse ( JSON . stringify ( macroPropertyExpr ) ) , bindingsUsed : bu , implicits : [ rel . params [ 1 ] . implicits [ 0 ] ] , schemaType : macroPropertyExpr . schemaType , implicitTypes : [ rel . params [ 1 ] . implicitTypes [ 0 ] ] } ] , willBeOptimized : true , uid : uid } m . schemaType = { type : 'map' , key : m . params [ 1 ] . schemaType , value : m . params [ 2 ] . schemaType } maps . push ( applyEachOptimizationToView ( m ) ) newImplicits . push ( uid ) bindingsUsed [ uid ] = true _ . assertDefined ( macroPropertyExpr . schemaType ) return { type : 'param' , name : uid , schemaType : macroPropertyExpr . schemaType } } ) if ( failed ) return originalRel var newMacro = { type : 'macro' , expr : newMacroExpr , manyImplicits : newImplicits . length , implicits : newImplicits , implicitTypes : [ rel . params [ 0 ] . schemaType . members ] , bindingsUsed : bindingsUsed , //newImplicits schemaType : newMacroExpr . schemaType } //console.log('created m: ' + JSON.stringify(newMacro, null, 2)) return { type : 'view' , view : 'each-optimization' , params : [ rel . params [ 0 ] , newMacro ] . concat ( maps ) , schemaType : rel . schemaType , code : rel . code } } catch ( e ) { //console.log('could not optimize each + e.stack) return originalRel } }
takes the rel for the each
takes the rel for the each