differentiate() can now handle arbitrary length products