Today I discovered that to make an arbitrary arity version of SRFI-1’s unzip1, unzip2 etc, this works:
(define (unzip lis) (apply values (apply map list lis)))
And, since zip
is just:
(define (zip . args) (apply map list args))
This means that this works:
(define (unzip lis) (apply values (apply zip lis)))
unzip
is applied zip
.
Apparently.
dpercy points out that it works because it’s a matrix transpose.
Basically it flips a matrix like this
1 2 3
a b c
along the NW-SE diagonal, into
1 a
2 b
3 c
That should make it clear that this is self-reversible.
The apply is because zip takes vals and returns a list, unzip takes a list and returns vals. But that’s just a grotesque artifact of history. If zip took a list and returned a list, or if it took vals and returned vals, unzip would be zip.
If this was zip, without the vararg dot:
(define (zip* lis) (apply map list lis))
It would just be self-reversing. (compose zip* zip*)
is an expensive
shallow copy.