function IterateArray (scope, initial_intermediate_computable, array_computable, item_virtual_computable, intermediate_virtual_computable, identity_comparison_function, array_map_function, array_map_function_input_computables) {
  this._choice_types = [];
  this._choice_scopes = [];
  this._choice_computable_indexes = [];
  this._unique_scopes = [];
  this._choice_output_paths = [];

  // TODO: It feels really wrong to expose the scope array from this, but my current element as arg plans require that to be the case.
  // TODO: scope array compound makes the assumption that it is only used for elements for now.  By the time that needs to change I'll likely not be exposing it.
  var output_type = new IRCompoundType({ after: initial_intermediate_computable.get_output_type(), scope_array: new IRArrayType(new IRCompoundType({ after: new IRDOMPlacementType() }, false), 0) }, false);

  if (!(item_virtual_computable instanceof VirtualArrayItem)) {
    throw new Error("item_virtual_computable parameter must be a VirtualArrayItem computable, got "+item_virtual_computable.constructor.name);
  }
  if (!(intermediate_virtual_computable instanceof VirtualIntermediate)) {
    throw new Error("intermediate_virtual_computable parameter must be a VirtualIntermediate computable, got "+intermediate_virtual_computable.constructor.name);
  }

  var intermediate_virtual = intermediate_virtual_computable;
  var item_virtual = item_virtual_computable;
  this._intermediate_virtual = intermediate_virtual;
  this._item_virtual = item_virtual;

  this._array_map_function = array_map_function;
  this._array_map_function_input_computables = array_map_function_input_computables;

  if (this._array_map_function && !this._array_map_function_input_computables) {
    throw new Error("Must provide array map function computables if providing array map function");
  }

  if (!array_map_function && this._choice_types.length > 1) {
    throw new Error("Must provide map function if using more than one option");
  }

  var input_computables = [
    initial_intermediate_computable,
    array_computable,
    intermediate_virtual_computable,
    item_virtual_computable
  ];

  if (array_map_function_input_computables) {
    input_computables = input_computables.concat(array_map_function_input_computables);
  }

  this._choice_input_computables_start_index = input_computables.length;
  this._identity_comparison_function = identity_comparison_function;

  ScopeCreator.call(this, scope, input_computables, output_type);

  var _this = this;
  this.on("dependee_added", function (index, computable) {
    if (index === 0) {
      _this.set_output_type(new IRCompoundType({ after: computable.get_output_type(), scope_array: new IRArrayType(new IRCompoundType({ after: new IRDOMPlacementType() }, false), 0) }, false));
    }
  });
}
/**
 * @constructor
 * @emits Scope#instance_added
 * @extends ScopeCreator
 * @param {Scope} scope The Scope this IterateArray will reside in.
 * @param {Computable} initial_intermediate_computable The Computable that will be used as the initial value for the intermediate, after which each created Scope is responsible for creating something of the same type, potentially transforming the initial value.
 *   - The output type of the IterateArray must be identical to the output type for the initial intermediate computable.  The IterateArray's output will be the intermediate output of the last created Scope.
 * @param {computable} array_computable An array of values.
 * @param {VirtualArrayItem} item_virtual_computable
 * @param {VirtualIntermediate} intermediate_virtual_computable
 * @param {function} identity_comparison_function A comparison function for determining if two items should be considered equivalent.
 * - a, b -> boolean
 * @param {function} [array_map_function]
 * @param {Array.<Computable>} [array_map_function_input_computables] The input computables needed to compute the map function.
 */
@constructor
@emits Scope#instance_added
@extends ScopeCreator
@param {Scope} scope The Scope this IterateArray will reside in.
@param {Computable} initial_intermediate_computable The Computable that will be used as the initial value for the intermediate, after which each created Scope is responsible for creating something of the same type, potentially transforming the initial value.
- The output type of the IterateArray must be identical to the output type for the initial intermediate computable.  The IterateArray's output will be the intermediate output of the last created Scope.
@param {computable} array_computable An array of values.
@param {VirtualArrayItem} item_virtual_computable
@param {VirtualIntermediate} intermediate_virtual_computable
@param {function} identity_comparison_function A comparison function for determining if two items should be considered equivalent.
- a, b -> boolean
@param {function} [array_map_function]
@param {Array.} [array_map_function_input_computables] The input computables needed to compute the map function.
@constructor @emits Scope#instance_added @extends ScopeCreator @param { Scope } scope The Scope this IterateArray will reside in . @param { Computable } initial_intermediate_computable The Computable that will be used as the initial value for the intermediate after which each created Scope is responsible for creating something of the same type potentially transforming the initial value . - The output type of the IterateArray must be identical to the output type for the initial intermediate computable . The IterateArray ' s output will be the intermediate output of the last created Scope . @param { computable } array_computable An array of values . @param { VirtualArrayItem } item_virtual_computable @param { VirtualIntermediate } intermediate_virtual_computable @param { function } identity_comparison_function A comparison function for determining if two items should be considered equivalent . - a b - > boolean @param { function } [ array_map_function ] @param { Array . } [ array_map_function_input_computables ] The input computables needed to compute the map function .
function IterateArray (scope, initial_intermediate_computable, array_computable, item_virtual_computable, intermediate_virtual_computable, identity_comparison_function, array_map_function, array_map_function_input_computables) {
  this._choice_types = [];
  this._choice_scopes = [];
  this._choice_computable_indexes = [];
  this._unique_scopes = [];
  this._choice_output_paths = [];
  var output_type = new IRCompoundType({ after: initial_intermediate_computable.get_output_type(), scope_array: new IRArrayType(new IRCompoundType({ after: new IRDOMPlacementType() }, false), 0) }, false);
  if (!(item_virtual_computable instanceof VirtualArrayItem)) {
    throw new Error("item_virtual_computable parameter must be a VirtualArrayItem computable, got "+item_virtual_computable.constructor.name);
  }
  if (!(intermediate_virtual_computable instanceof VirtualIntermediate)) {
    throw new Error("intermediate_virtual_computable parameter must be a VirtualIntermediate computable, got "+intermediate_virtual_computable.constructor.name);
  }
  var intermediate_virtual = intermediate_virtual_computable;
  var item_virtual = item_virtual_computable;
  this._intermediate_virtual = intermediate_virtual;
  this._item_virtual = item_virtual;
  this._array_map_function = array_map_function;
  this._array_map_function_input_computables = array_map_function_input_computables;
  if (this._array_map_function && !this._array_map_function_input_computables) {
    throw new Error("Must provide array map function computables if providing array map function");
  }
  if (!array_map_function && this._choice_types.length > 1) {
    throw new Error("Must provide map function if using more than one option");
  }
  var input_computables = [
    initial_intermediate_computable,
    array_computable,
    intermediate_virtual_computable,
    item_virtual_computable
  ];
  if (array_map_function_input_computables) {
    input_computables = input_computables.concat(array_map_function_input_computables);
  }
  this._choice_input_computables_start_index = input_computables.length;
  this._identity_comparison_function = identity_comparison_function;
  ScopeCreator.call(this, scope, input_computables, output_type);
  var _this = this;
  this.on("dependee_added", function (index, computable) {
    if (index === 0) {
      _this.set_output_type(new IRCompoundType({ after: computable.get_output_type(), scope_array: new IRArrayType(new IRCompoundType({ after: new IRDOMPlacementType() }, false), 0) }, false));
    }
  });
}
function IterateArray ( scope , initial_intermediate_computable , array_computable , item_virtual_computable , intermediate_virtual_computable , identity_comparison_function , array_map_function , array_map_function_input_computables ) { this . _choice_types = [ ] ; this . _choice_scopes = [ ] ; this . _choice_computable_indexes = [ ] ; this . _unique_scopes = [ ] ; this . _choice_output_paths = [ ] ; var output_type = new IRCompoundType ( { after : initial_intermediate_computable . get_output_type ( ) , scope_array : new IRArrayType ( new IRCompoundType ( { after : new IRDOMPlacementType ( ) } , false ) , 0 ) } , false ) ; if ( ! ( item_virtual_computable instanceof VirtualArrayItem ) ) { throw new Error ( "item_virtual_computable parameter must be a VirtualArrayItem computable, got " + item_virtual_computable . constructor . name ) ; } if ( ! ( intermediate_virtual_computable instanceof VirtualIntermediate ) ) { throw new Error ( "intermediate_virtual_computable parameter must be a VirtualIntermediate computable, got " + intermediate_virtual_computable . constructor . name ) ; } var intermediate_virtual = intermediate_virtual_computable ; var item_virtual = item_virtual_computable ; this . _intermediate_virtual = intermediate_virtual ; this . _item_virtual = item_virtual ; this . _array_map_function = array_map_function ; this . _array_map_function_input_computables = array_map_function_input_computables ; if ( this . _array_map_function && ! this . _array_map_function_input_computables ) { throw new Error ( "Must provide array map function computables if providing array map function" ) ; } if ( ! array_map_function && this . _choice_types . length > 1 ) { throw new Error ( "Must provide map function if using more than one option" ) ; } var input_computables = [ initial_intermediate_computable , array_computable , intermediate_virtual_computable , item_virtual_computable ] ; if ( array_map_function_input_computables ) { input_computables = input_computables . concat ( array_map_function_input_computables ) ; } this . _choice_input_computables_start_index = input_computables . length ; this . _identity_comparison_function = identity_comparison_function ; ScopeCreator . call ( this , scope , input_computables , output_type ) ; var _this = this ; this . on ( "dependee_added" , function ( index , computable ) { if ( index === 0 ) { _this . set_output_type ( new IRCompoundType ( { after : computable . get_output_type ( ) , scope_array : new IRArrayType ( new IRCompoundType ( { after : new IRDOMPlacementType ( ) } , false ) , 0 ) } , false ) ) ; } } ) ; }
@constructor
 @emits Scope#instance_added
 @extends ScopeCreator
 @param {Scope} scope The Scope this IterateArray will reside in.
@constructor @emits Scope#instance_added @extends ScopeCreator @param { Scope } scope The Scope this IterateArray will reside in .
// TODO: It feels really wrong to expose the scope array from this, but my current element as arg plans require that to be the case. // TODO: scope array compound makes the assumption that it is only used for elements for now.  By the time that needs to change I'll likely not be exposing it.