Multiple aggregations, optimized.

    Parameters
    ----------
    array : numpy.ndarray or WeldObject
        Input array.
    weld_type : WeldType
        Type of each element in the input array.
    aggregations : list of str
        Which aggregations to compute.

    Returns
    -------
    WeldObject
        Representation of this computation.

def weld_agg(array, weld_type, aggregations):
    """Multiple aggregations, optimized.

    Parameters
    ----------
    array : numpy.ndarray or WeldObject
        Input array.
    weld_type : WeldType
        Type of each element in the input array.
    aggregations : list of str
        Which aggregations to compute.

    Returns
    -------
    WeldObject
        Representation of this computation.

    """
    from functools import reduce

    obj_id, weld_obj = create_weld_object(array)

    # find which aggregation computations are actually needed
    to_compute = reduce(lambda x, y: x | y, ({agg} | _agg_dependencies[agg] for agg in aggregations))
    # get priorities and sort in the proper order of computation
    to_compute = sorted(((agg, _agg_priorities[agg]) for agg in to_compute), key=lambda x: x[1])
    # remove the priorities
    to_compute = (agg_pair[0] for agg_pair in to_compute)
    aggs = '\n'.join(('let agg_{} = {};'.format(agg, _agg_code[agg]) for agg in to_compute))

    # these are the aggregations requested
    merges = '\n'.join(('let res = merge(res, {});'.format('agg_{}'.format(agg)) for agg in aggregations))
    mergers = """let res = appender[f64];
{merges}
result(res)
"""
    mergers = mergers.format(merges=merges)

    weld_template = '{}\n{}'.format(aggs, mergers)

    weld_obj.weld_code = weld_template.format(array=obj_id,
                                              type=weld_type)

    return weld_obj