def reduce_loom(op, operands):
  """Apply a binary LoomOp on `operands` to obtain one result."""
  if not operands:
    raise ValueError('operands is empty')

  # Binary tree reduction.
  while len(operands) > 1:
    evens = operands[::2]
    odds = operands[1::2]
    new_operands = [op(*pair) for pair in zip(evens, odds)]
    if len(evens) != len(odds):
      new_operands.append(operands[-1])
    operands = new_operands
  return operands[0]