Task

Show one or more idiomatic ways of generating the Cartesian product of two arbitrary lists in your language.

Demonstrate that your function/method correctly returns:

{1, 2} × {3, 4} = {(1, 3), (1, 4), (2, 3), (2, 4)}
and, in contrast:

{3, 4} × {1, 2} = {(3, 1), (3, 2), (4, 1), (4, 2)}
Also demonstrate, using your function/method, that the product of an empty list with any other list is empty.

 {1, 2} × {} = {}
 {} × {1, 2} = {}
For extra credit, show or write a function returning the n-ary product of an arbitrary number of lists, each of arbitrary length. Your function might, for example, accept a single argument which is itself a list of lists, and return the n-ary product of those lists.

Use your n-ary Cartesian product function to show the following products:

 {1776, 1789} × {7, 12} × {4, 14, 23} × {0, 1}
 {1, 2, 3} × {30} × {500, 100}
 {1, 2, 3} × {} × {500, 100}


 
proc cartesianProduct {l1 l2} {
  set result {}
  foreach el1 $l1 {
    foreach el2 $l2 {
      lappend result [list $el1 $el2]
    }
  }
  return $result
}
 
puts "simple"
puts "result: [cartesianProduct {1 2} {3 4}]"
puts "result: [cartesianProduct {3 4} {1 2}]"
puts "result: [cartesianProduct {1 2} {}]"
puts "result: [cartesianProduct {} {3 4}]"
 
proc cartesianNaryProduct {lists} {
  set result {{}}
  foreach l $lists {
    set res {}
    foreach comb $result {
      foreach el $l {
        lappend res [linsert $comb end $el]
      }
    }
    set result $res
  }
  return $result
}
 
puts "n-ary"
puts "result: [cartesianNaryProduct {{1776 1789} {7 12} {4 14 23} {0 1}}]"
puts "result: [cartesianNaryProduct {{1 2 3} {30} {500 100}}]"
puts "result: [cartesianNaryProduct {{1 2 3} {} {500 100}}]"
 
 