As I get more fluent in Nim, the main tool I find myself missing is a lightweight reference to a range of bytes in memory β something that points to a portion of a seq without copying it. The closest equivalent I know of is Go's slice[T], which is pretty ubiquitous β it's actually rare in Go to pass or return an array itself.
I'm assuming this doesn't exist in Nim itself; I've spent some time scanning through the standard library docs, esp. the system and sequtils modules, and I think I'd have found it if it were there. But there might be a Nimble package.
This could be implemented pretty simply, if non-optimally; something like
type subseq*[T] = object
parent: ref seq[T]
range: Slice[Natural]
The "non-optimal" part is the double-indirection getting to the bytes; it needs a ref seq to establish ownership so the GC will keep the heap block alive. One could add a direct pointer to the start of the range, in which case range.a isn't needed, so we get
type subseq*[T] = object
parent: ref seq[T]
base: UncheckedArray[T]
len: uint
Both of these become unsafe if the seq is mutated; obviously if it's shortened enough to invalidate the end of the range, and more subtly the second design's base is invalidated if the seq has to grow its buffer. Not sure how to deal with that βΒ it seems to require a Rust-like restriction that a sequence can't be mutated while any slices on it are extant, but I don't think Nim-as-we-know-it has ways to enforce that.
I'm writing code that manipulates portions of seq``s, and I keep creating proc parameter lists that include ``input: openarray[byte]; inRange: var Slice[int], and then inside the proc I keep writing stuff like input[inRange.a + i] π
I have a large C++ codebase that uses a custom slice type that simply contains a pointer and a length, and I've found it extremely useful over the years; it really cleans up code that deals with byte ranges. (C++17's string_view is pretty much the same thing.) Of course it's very unsafe, but I'm used to that in C++. I'd like a safer version of it (more like Go's) in Nim. So I'm implementing one now; your toy sequence class from your ARC/ORC talk is proving very useful!
There is also openArray. It's currently restricted to parameters due to memory safety reasons, there is an RFC to extend it.
I assume you mean this? What's the status of that and the other Nim2020 RFCs? It has always said 0% complete on that page, and 2020 is about half over. I don't believe any of it is 0% complete ;-)
I'm writing code that manipulates portions of seq s, and I keep creating proc parameter lists that include input: openarray[byte]; inRange: var Slice[int], and then inside the proc I keep writing stuff like input[inRange.a + i]
Er, you can slice with toOpenArray, no need for the inRange: var stuff. In an ideal world we would have made a[x..y] an alias for toOpenArray.
I don't believe any of it is 0% complete ;-)
We're fixing the "last" bugs for ARC/ORC (ha ha...), work on IC was done by an external developer but it's far from finished. There has been no work done on https://github.com/nim-lang/RFCs/issues/178
Sad but true.
Er, you can slice with toOpenArray, no need for the inRange: var stuff.
That isn't enough, because the proc alters the range (that's why inRange is a var.) It's basically consuming part of the input array, and updates the start of the range so that on return it points to only the unconsumed bytes.
I could have made the API so it returns the number of bytes consumed, but that makes the caller do more bookkeeping. I suppose to some extent this is just me going against the grain of Nim's idioms...)