It would be nice if pairs could be used with iterators. Here's an example with the lines iterator for files. This won't work, but it would be nice to achieve this behavior.
var f: File
if open(f, "/some/path/to/my/file.txt"):
for i, line in pairs(f.lines):
echo i
echo line
It fails with
Error: undeclared identifier: 'lines'
Looking at the system module, I didn't see any pair procs that take an iterator, so I'm not surprised this fails. Though this error seems to be about something else (I think).
Looks pretty simple to implement, maybe it would be a good idea for the stdlib:
iterator pairs(it: iterator): auto =
var i = 0
for x in it:
yield (i, x)
inc i
var f: File
if open(f, "fo"):
for i, line in f.lines.pairs:
echo i, " ", line
But I'm not sure how to write the signature of pairs explicitly.
pairs() and mpairs() is already there.
you want import strutils, and something like the following:
import strutils var f: File proc main() = if open(f, "/some/path/to/my/file.txt"): var s = readAll(f) for i, line in readAll(f).splitLines().pairs(): echo i, ": ", line main()
The implicit call of pairs also worries me a bit, because it is so easy to hide bugs like this:
let persons = [
("bob", 20),
("alice", 19)
]
for name, age in persons:
echo name, age
A safer solution would be to simply allow tuple unpacking only if the underlying type is tuple-like (HashMaps and actual tuples). In order to unpack (index, element) call an explicit iterator (I was suggesting the pythonic enumerate before). However, this would break many for i,x in something loops.
Jehan: I'm not sure overloading pairs for iterators to always mean "with an index as the other component" is a good idea. You probably want a more specific name for this functionality, e.g. "withIndex".
The API naming guideline says "pairs - iterator over (key, value) pairs", the key for a value in a sequence is its index, and the docs for system.pairs say "Yields (index, a[index]) pairs", so it seems to be the right name here. If you want to argue that pairs should produce pairs of elements from the iterator, the exact same argument could be made for the existing pairs methods on sequences. I don't think pairs is a particularly good name for its functionality, precisely because of this ambiguity (keyAndValue might be better), but pairs is the name currently in use. Arrays and iterators should be interchangeable ... important for consistency and templates. (In many other systems, traversing an array or other sequence actually processes an iterator derived from the sequence.)
"something else?"
Yes, it should return the index and the value (the triple), like I already said ... that's the semantics of pairs (unobvious from the name).
Ah, I see jlp765 said the same thing. And it's true. Again, it should yield exactly what you would get with a sequence ... the index and the value. This is how it works with other iterator-based collection systems, like STL, LINQ, and Scala ... there's no difference (other than unoptimized performance) between iterating through a sequence and iterating over an iterator ... in fact they're the same, because the sequence provides an iterator to fetch its values.
resurrecting this old thread, not sure if anything has changed since then:
import os
# works:
for k in walkFiles("."):
echo(k)
# fails: Error: attempting to call undeclared routine: 'walkFiles'
for i,k in pairs(walkFiles(".")):
echo(i,k)
Unfortunately not, this is an inline iterator chaining issue.
You can refer to Github issue #4516. There is a workaround macro in this thread as well.
@mratsim and @timothee, if you just want pairs, you can do something almost equivalent with macros. I whipped up an example in my nim-extensions nimble module that you can look at. I need to update it with more comments, but it works like so:
import os
import extensions/enumerate
for i, line in enumerate(lines, "file.txt"):
echo i, " ", line
for i, tup in enumerate(walkDir, "."):
echo i, " ", tup
Not sure though.
Shouldn't modules and indentifiers be in different namespaces from the point of view of the compiler? I don't see why this is ever an issue.