You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Zipped family of functions and Enumerated function create new arrays, which isn't very obvious in a typical usage code and incur performance penalties. If we introduce this pattern, the need for Enumerated and Zipped family will be greatly reduced to the point we might want to remove them.
Here's an example from the old school of writing loops. (Which I belong to :)
for i in 0..Length(xs)-1 {
X(xs[i]);
}
You have access to i and you can index an array any way you want. However it has drawbacks.
You have to know what index range is - i.e. from 0 to |xs|-1. In some languages indexes start with 1.
You need to be careful with index ranges and index expressions every time your write such loop. In practice most loops are over all the elements of the array.
You have to write indexing everywhere the 'current' element is used. If there're many of them it gets annoying. You need to think which element of which array is 'current' in every such place. In practice you often start you loop with a local variable holding the 'current' element: let x = xs[i].
A modern way of writing this is
ApplyToEach(X, xs)
which I don't like much because it's hard to figure out the complexity by looking at the code. Another way is this.
for q in xs {
X(q);
}
It solves the problem of the first approach but hides index from you. You can no longer use index. If you need index, you may write something like this.
for i in IndexRange(xs) {
X(xs[i]);
}
It gives you index and hides array bounds. But it doesn't give you the 'current' element. So to get all the benefits you use 'Enumerated'.
for (i,q) in Enumerated(xs) {
R1Frac(1, i, q);
}
Now, it's not efficient because it creates an array. Maybe we can solve this by allowing the following construction:
for (i,q) in (IndexRange(xs), xs) {
R1Frac(1, i, q);
}
In this case, you have access to the index, 'current' element and index range is hidden.
Complication: What to do if the number of elements in these ranges are different? Use the shortest one? Fail execution?
The text was updated successfully, but these errors were encountered:
Would it also be acceptable to optimize Enumerated so it doesn't perform this allocation? That avoids the case where the two tuple elements are not the same size.
Would it also be acceptable to optimize Enumerated so it doesn't perform this allocation? That avoids the case where the two tuple elements are not the same size.
Unfortunately, no. There is no concept of an iterator in Q#, so there is nothing we could return that would satisfy iteration other than a new array.
Zipped
family of functions andEnumerated
function create new arrays, which isn't very obvious in a typical usage code and incur performance penalties. If we introduce this pattern, the need for Enumerated and Zipped family will be greatly reduced to the point we might want to remove them.Here's an example from the old school of writing loops. (Which I belong to :)
You have access to i and you can index an array any way you want. However it has drawbacks.
A modern way of writing this is
which I don't like much because it's hard to figure out the complexity by looking at the code. Another way is this.
It solves the problem of the first approach but hides index from you. You can no longer use index. If you need index, you may write something like this.
It gives you index and hides array bounds. But it doesn't give you the 'current' element. So to get all the benefits you use 'Enumerated'.
Now, it's not efficient because it creates an array. Maybe we can solve this by allowing the following construction:
In this case, you have access to the index, 'current' element and index range is hidden.
Complication: What to do if the number of elements in these ranges are different? Use the shortest one? Fail execution?
The text was updated successfully, but these errors were encountered: