digitalmars.D - array slicing currently does not support steps?
- mw (11/13) Aug 03 2020 Hi,
- Paul Backus (3/5) Aug 03 2020 You can use std.range.stride for this:
- mw (5/12) Aug 03 2020 OK, good to know.
- Paul Backus (3/12) Aug 03 2020 In general, D tries to avoid adding special-purpose syntax for
- WebFreak001 (14/28) Aug 04 2020 just act like this is syntax in the language and not a function
- Simen =?UTF-8?B?S2rDpnLDpXM=?= (17/31) Aug 04 2020 Since D slices are just views of memory, this would either change
- jmh530 (16/21) Aug 04 2020 [snip]
- Paul Backus (16/30) Aug 04 2020 Currently, when you do `y = x[0..5]`, both x and y point to the
- jmh530 (2/18) Aug 04 2020 Thanks, that makes sense.
Hi, I just noted that D array slice does not support steps? https://dlang.org/articles/d-array-article.html Ever since Python 1.4, the slicing syntax has supported an optional third ``step'' or ``stride'' argument. For example, these are all legal Python syntax: L[1:10:2], L[:-1:1], L[::-1]. This was added to Python at the request of the developers of Numerical Python, which uses the third argument extensively. https://docs.python.org/2.3/whatsnew/section-slices.html[0, 2, 4, 6, 8] Shall we add a DIP for this?L = range(10) L[::2]
Aug 03 2020
On Monday, 3 August 2020 at 23:32:29 UTC, mw wrote:Hi, I just noted that D array slice does not support steps?You can use std.range.stride for this: http://dpldocs.info/experimental-docs/std.range.stride.html
Aug 03 2020
On Monday, 3 August 2020 at 23:50:45 UTC, Paul Backus wrote:On Monday, 3 August 2020 at 23:32:29 UTC, mw wrote:OK, good to know. But if it's built into the language syntax (as extended array slicing), it will be better: more succinct, and much easier for Python programmers to adopt D.Hi, I just noted that D array slice does not support steps?You can use std.range.stride for this: http://dpldocs.info/experimental-docs/std.range.stride.html
Aug 03 2020
On Tuesday, 4 August 2020 at 00:03:16 UTC, mw wrote:On Monday, 3 August 2020 at 23:50:45 UTC, Paul Backus wrote:In general, D tries to avoid adding special-purpose syntax for things that can be easily solved with library code.You can use std.range.stride for this: http://dpldocs.info/experimental-docs/std.range.stride.htmlOK, good to know. But if it's built into the language syntax (as extended array slicing), it will be better: more succinct, and much easier for Python programmers to adopt D.
Aug 03 2020
On Tuesday, 4 August 2020 at 00:03:16 UTC, mw wrote:On Monday, 3 August 2020 at 23:50:45 UTC, Paul Backus wrote:just act like this is syntax in the language and not a function call: auto x = array[0 .. 10].stride(2); I think readability-wise this beats other syntax you can come up with and it's just a library solution :) If you then want to copy it into an actual array you can pass as slice use auto x = array[0 .. 10].stride(2).array; or adjust your functions to handle ranges properly :p On the function implementation side I can definitely see room for improvement though, like the signatures DIP rikkimax had once made which would make templates not needed for supporting passing and storing ranges.On Monday, 3 August 2020 at 23:32:29 UTC, mw wrote:OK, good to know. But if it's built into the language syntax (as extended array slicing), it will be better: more succinct, and much easier for Python programmers to adopt D.Hi, I just noted that D array slice does not support steps?You can use std.range.stride for this: http://dpldocs.info/experimental-docs/std.range.stride.html
Aug 04 2020
On Monday, 3 August 2020 at 23:32:29 UTC, mw wrote:Hi, I just noted that D array slice does not support steps? https://dlang.org/articles/d-array-article.html Ever since Python 1.4, the slicing syntax has supported an optional third ``step'' or ``stride'' argument. For example, these are all legal Python syntax: L[1:10:2], L[:-1:1], L[::-1]. This was added to Python at the request of the developers of Numerical Python, which uses the third argument extensively. https://docs.python.org/2.3/whatsnew/section-slices.htmlSince D slices are just views of memory, this would either change how slicing works (copy the data when using stride), or change the memory layout of slices. Currently, a slice is essentially a (ptr, length) struct, and adding stride to the mix would require adding another field to every slice. This would break all D code ever, so we can disregard that solution. Copying the data doesn't actually break any code, since the no-stride case would be unaffected, and is the only case currently in use. However, having a different behavior here would break the principle of least astonishment. Lastly, there's std.range.stride, which is an excellent workaround with none of these drawbacks. All in all, a DIP is very unlikely to be accepted given the above. -- Simen[0, 2, 4, 6, 8] Shall we add a DIP for this?L = range(10) L[::2]
Aug 04 2020
On Tuesday, 4 August 2020 at 07:39:04 UTC, Simen Kjærås wrote:[snip] Currently, a slice is essentially a (ptr, length) struct, and adding stride to the mix would require adding another field to every slice. This would break all D code ever, so we can disregard that solution.[snip] I think I've suggested something similar in the past. I don't understand why another field is required as it would just be some special syntax over indexing. For instance, I would imagine it used like auto x = [1, 2, 3, 4, 5, 6, 7]; auto y = x[0..2..5]; assert(y == [1, 3, 5]); This would be marginally different from python, which puts the strides last and uses colons (which I prefer), but its the same general idea (other languages have similar behavior). A language like Chapel optionally allows for strides (which do take up space). A user-defined type in D could do the same thing. If the stride is a compile-time type, then you could have a specialization where the stride is 1 and does not take up space.
Aug 04 2020
On Tuesday, 4 August 2020 at 13:15:39 UTC, jmh530 wrote:On Tuesday, 4 August 2020 at 07:39:04 UTC, Simen Kjærås wrote:Currently, when you do `y = x[0..5]`, both x and y point to the same memory. In order for `y == [1, 3, 5]` to be true, one of the following must hold: 1) y points to memory which contains 1, 3, and 5 in contiguous locations. 2) y has an overloaded == operator which takes the stride into account. simple int[], but must instead be a custom type that stores the stride in addition to a pointer and a length. As WebFreak001 pointed out, you can get the "custom type" version with `x[0..5].stride(2)`, and the the "array with copied elements" version with `x[0..5].stride(2).array`.[snip] Currently, a slice is essentially a (ptr, length) struct, and adding stride to the mix would require adding another field to every slice. This would break all D code ever, so we can disregard that solution.[snip] I think I've suggested something similar in the past. I don't understand why another field is required as it would just be some special syntax over indexing. For instance, I would imagine it used like auto x = [1, 2, 3, 4, 5, 6, 7]; auto y = x[0..2..5]; assert(y == [1, 3, 5]);
Aug 04 2020
On Tuesday, 4 August 2020 at 14:52:49 UTC, Paul Backus wrote:[snip] Currently, when you do `y = x[0..5]`, both x and y point to the same memory. In order for `y == [1, 3, 5]` to be true, one of the following must hold: 1) y points to memory which contains 1, 3, and 5 in contiguous locations. 2) y has an overloaded == operator which takes the stride into account. be a simple int[], but must instead be a custom type that stores the stride in addition to a pointer and a length. As WebFreak001 pointed out, you can get the "custom type" version with `x[0..5].stride(2)`, and the the "array with copied elements" version with `x[0..5].stride(2).array`.Thanks, that makes sense.
Aug 04 2020