*
in a function definition doesn't mean optional; it means "pack any additional (non-keyword) arguments the caller supplied into a tuple and put the tuple here". Similarly, *
on a function call means "unpack this sequence of things and supply all the elements as arguments to the function individually."
unpack(*(1,2,3))
unpacks (1,2,3)
and calls
unpack(1,2,3)
1
is assigned to first
, and the remaining arguments 2
and 3
are packed into a tuple and assigned to rest
.