Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit f6aa74f

Browse files
committed
zip
1 parent c82a54a commit f6aa74f

2 files changed

Lines changed: 140 additions & 0 deletions

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@
44
- [`common_reference_t` of `reference_wrapper` should be a reference type](https://huixie90.github.io/cpp_papers/generated/ref_wrapper_common_ref)
55
- [`any_view`](https://huixie90.github.io/cpp_papers/generated/any_view)
66
- [`flat_meow` Fixes](https://huixie90.github.io/cpp_papers/generated/flat_map)
7+
- [`zip()` Should be an Infinite Range](https://huixie90.github.io/cpp_papers/generated/zip)

zip.md

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
---
2+
title: "`zip()` Should Be an Infinite Range"
3+
document: DXXXXR0
4+
date: 2025-05-31
5+
audience: SG9, LEWG
6+
author:
7+
- name: Hui Xie
8+
9+
- name: Tristan Melen
10+
email: <>
11+
toc: true
12+
---
13+
14+
# Revision History
15+
16+
## R0
17+
18+
- Initial revision.
19+
20+
# Abstract
21+
22+
This paper proposes a fix that makes the `views::zip()` an infinite range `views::repeat(tuple())` instead of the current `views::empty<tuple<>>`
23+
24+
25+
# Design Considerations
26+
27+
## Rationale for the Current `zip()` Design
28+
29+
### P2321R2
30+
31+
According to [@P2321R2], the reason for the current behaviour of `zip()` was:
32+
33+
> As in range-v3, zipping nothing produces an `empty_view` of the appropriate type.
34+
35+
Searching through the historical commits in range-v3, the behaviour of `zip()` was added in this commit [@range-v3].
36+
37+
In this commit, both nullary `cartesian_product()` and `zip()` were added, both yield an empty range, and both are incorrect. And the rationale for this commit was
38+
39+
> This allows us to remove the nasty MSVC special case for empty `cartesian_products`.
40+
41+
In conclusion, this behaviour did not seem to be a result of careful design, but just chosen to work around a "nasty MSVC special case".
42+
43+
### P2540R1
44+
45+
The discussion on the [@reflector] indicated that `cartesian_product()` should be `single(tuple())` and `zip()` should be `repeat(tuple())`.
46+
47+
Luckily, [@P2540R1] fixed `cartesian_product`. So it no longer follows the "range-v3" behaviour but the correct one `views::single(tuple())`.
48+
49+
However, the paper intentionally left `zip`'s behaviour unchanged, after .
50+
51+
The main reason behind this decision was
52+
53+
> In particular, `zip` has the property that it is the inner join of the indexed sets, and is the main diagonal of the Cartesian product. However, the identity element for `zip` is `repeat(tuple<>)`, the infinite range of repeated empty tuples.
54+
> If we allowed zip of an empty range of ranges to be its identity element, we would be introducing an inconsistency into the system, where two different formulations of notionally the same thing produces different answers.
55+
56+
However, the authors believe that the above conclusion is flawed.
57+
58+
TODO: explain the main diagonal and identity yield same results
59+
60+
## TODO
61+
- explain any_of/all_of's identity
62+
- explain cartesian_product
63+
- explain the identify component of "minimum" operation should be infinity
64+
- we prefer the result to be infinite range. if this cannot be agreed on, at the minimum, zip() should be ill-formed
65+
66+
## Other Languages
67+
68+
### Julia
69+
70+
Julia's `zip()` produces an infinite range of empty tuples, which is in line with the authors' view.
71+
72+
### Rust
73+
74+
Rust's compiler actively rejects `multizip` or `izip!` calls with no argument. This is much better than giving the wrong results.
75+
76+
### Java, C#, Haskell
77+
78+
These languages either only supports a zip with two ranges, or provide zip3, zip4, ... functions for more ranges, possibly due to
79+
lack of support for variadic arguments. However, they don't provide a zip0, for a good reason.
80+
81+
### Python
82+
83+
Python got it wrong too. `zip()` is an empty iterable. It is unclear what drives the design decision on this. The author has asked this question
84+
on StackOverflow's Python community long time ago [@stackoverflow], but there is no satisfying answer.
85+
86+
## An Infinite Range is not a `ranges::range`
87+
88+
Whether an infinite range is a `ranges::range` is out of the scope of this paper. After all, this paper only delegates this special case of `views::zip` to `views::repeat` without inventing anything new. Whatever fix that is needed to fix `ranges::range` concept to work nicely with infinite ranges will fix all the existing views, i.e. `views::iota(0)`, `views::repeat(x)` and so on in one go.
89+
90+
91+
# Implementation Experience
92+
93+
94+
# Wording
95+
96+
Modify [range.zip.overview]{.sref} section (2.1) as
97+
98+
- (2.1) [`auto(views​::​empty<tuple<>>)`]{.rm} [`views::repeat(tuple())`]{.add} if `Es` is an empty pack,
99+
100+
101+
## Feature Test Macro
102+
103+
Bump the FTM `__cpp_lib_ranges_zip`
104+
105+
---
106+
references:
107+
- id: stackoverflow
108+
citation-label: stackoverflow
109+
title: "Why does Python `zip()` yield nothing when given no iterables?"
110+
URL: https://stackoverflow.com/questions/71561715/why-does-python-zip-yield-nothing-when-given-no-iterables
111+
112+
- id: range-v3
113+
citation-label: range-v3
114+
title: "[zip] Correctly zip no ranges"
115+
URL: https://github.com/ericniebler/range-v3/commit/ef9a650d4da87f02c5c079055e09017825c92fb3
116+
117+
- id: reflector
118+
citation-label: reflector
119+
title: "[isocpp-lib-ext] zip and cartesian_product base case"
120+
URL: https://lists.isocpp.org/lib-ext/2022/01/22023.php
121+
122+
- id: libcxx
123+
citation-label: libcxx
124+
title: "Implementation of zip() in libc++"
125+
author:
126+
- family: Xie
127+
given: Hui
128+
URL: todo
129+
---
130+
131+
<style>
132+
.bq{
133+
display: block;
134+
margin-block-start: 1em;
135+
margin-block-end: 1em;
136+
margin-inline-start: 40px;
137+
margin-inline-end: 40px;
138+
}
139+
</style>

0 commit comments

Comments
 (0)