doing cartesian product
cartesian product handles empty arrays