Skip to content

Commit c60b477

Browse files
committed
Bring old implementation of List.zip back
The previous implementation supported lists of tuples. Although its @SPEC only accepted lists of lists, we bring it back to avoid unnecessary breaking changes, especially since the function has been deprecated.
1 parent 49979d2 commit c60b477

File tree

1 file changed

+30
-2
lines changed

1 file changed

+30
-2
lines changed

lib/elixir/lib/list.ex

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -634,10 +634,38 @@ defmodule List do
634634
end
635635

636636
@deprecated "Use Enum.zip/1 instead"
637-
def zip(list_of_lists) when is_list(list_of_lists) do
638-
Enum.zip(list_of_lists)
637+
# We keep the old implementation because it also supported lists
638+
# of tuples, even though this was not included in its @spec.
639+
def zip([]), do: []
640+
def zip(list_of_lists) when is_list(list_of_lists), do: do_zip(list_of_lists, [])
641+
642+
defp do_zip(list, acc) do
643+
converter = fn x, acc -> do_zip_each(to_list(x), acc) end
644+
645+
case :lists.mapfoldl(converter, [], list) do
646+
{_, nil} ->
647+
:lists.reverse(acc)
648+
649+
{mlist, heads} ->
650+
do_zip(mlist, [to_tuple(:lists.reverse(heads)) | acc])
651+
end
652+
end
653+
654+
defp do_zip_each(_, nil) do
655+
{nil, nil}
639656
end
640657

658+
defp do_zip_each([head | tail], acc) do
659+
{tail, [head | acc]}
660+
end
661+
662+
defp do_zip_each([], _) do
663+
{nil, nil}
664+
end
665+
666+
defp to_list(tuple) when is_tuple(tuple), do: Tuple.to_list(tuple)
667+
defp to_list(list) when is_list(list), do: list
668+
641669
@doc ~S"""
642670
Checks if `list` is a charlist made only of printable ASCII characters.
643671

0 commit comments

Comments
 (0)