Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Slice operations inconsistent between types, operations, bounds checks #16492

Open
arnetheduck opened this issue Dec 28, 2020 · 0 comments
Open

Comments

@arnetheduck
Copy link
Contributor

len for a slice is saturated to 0:

proc len*[U: Ordinal; V: Ordinal](x: HSlice[U, V]): int {.noSideEffect, inline.} =

It follows that any operations on sequences, arrays etc should allow slices that are of "negative" length, and yet the standard library and compiler each have their own ideas:

using a slice [2..0], string raises RangeDefect because it doesn't use the same slice length calculation and ends up violating the Natural range - it doesn't look deliberate:

result = newString(L)

[]= doesn't raise however and is consistent with len (a lucky coincidence since it doesn't allocate).

The range checks in the compiler are a bit of a mystery, they're quite random:

for seq and openArray, any slice indices are fine - including out-of-bounds - as long as the difference is -1 (again using its own idea of length) - if the difference is not -1, each index separately must be in range - thus for a seq of length 3, [42,41] is allowed but [43, 41] is not.

"if ($2-$1 != -1 && " &

array bounds checks however have their own interpretation of a slice length and bounds checks and disallow negative slices slices explicitly:

"($2-$1 < -1 || $1 < $3 || $1 > $4 || $2 < $3 || $2 > $4)){ #raiseIndexError(); $5}$n",

Even if the bounds checks were consistent with the standard library, they are of questionable utility - out-of-bounds range operations could simply return an empty list (as well as allowing partial overlaps) - an alternative way to solve the bounds checks at least would be to remove them. Python for example implements slicing this way (though porting code from there of course is made difficult by the unfortunate choice that closed ranges are used in nim) - C++ allows the length of substr to go out-of-bounds, returning as many characters as possible (using start, len, start must be in range). rust is strict and implements start <= end and end <= len (using half-open range semantics).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant