One example of prior art: Maxima, which I use in its wxMaxima incarnation. """ Function: permutations(a) Returns a set of all distinct permutations of the members of the list or set a. Each permutation is a list, not a set. When a is a list, duplicate members of a are included in the permutations """ Examples from a Maxima shell:
permutations([1, 2. 3]); {[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]}
permutations([[1, 2], [1, 2], [2, 3]]) {[[1,2],[1,2],[2,3]], [[1,2],[2,3],[1,2]], [[2,3],[1,2],[1,2]]}
permutations({1, 1.0, 1, 1.0}) {[1,1.0],[1.0,1]}
That last one may be surprising at first, but note that it's the first example where I passed a _set_ (instead of a list). And:
{1, 1.0, 1, 1.0} {1,1.0}
Best I can tell, Maxima has no builtin function akin to our permutations(it, r) when r < len(it). But Maxima has a huge number of builtin functions, and I often struggle to find ones I _want_ in its docs ;-)