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
proclen*[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:
[]= 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.
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).
The text was updated successfully, but these errors were encountered:
arnetheduck
changed the title
Slice operations inconsistent between types, operations, bounds checks and compile time.
Slice operations inconsistent between types, operations, bounds checks
Dec 28, 2020
len
for a slice is saturated to 0:Nim/lib/system.nim
Line 1548 in fbc8a40
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
raisesRangeDefect
because it doesn't use the same slice length calculation and ends up violating theNatural
range - it doesn't look deliberate:Nim/lib/system.nim
Line 2493 in fbc8a40
[]=
doesn't raise however and is consistent withlen
(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
andopenArray
, 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.Nim/compiler/ccgexprs.nim
Line 948 in fbc8a40
array
bounds checks however have their own interpretation of a slice length and bounds checks and disallow negative slices slices explicitly:Nim/compiler/ccgexprs.nim
Line 960 in fbc8a40
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 (usingstart, len
,start
must be in range).rust
is strict and implementsstart <= end
andend <= len
(using half-open range semantics).The text was updated successfully, but these errors were encountered: