I've been trying to dive back into Nim and get used to the differences in the
way it works compared to the way I'm used to working in python. Mostly it's
been fine, but I came across an awkward problem with iterating through the keys
in a table in alphabetical order. A simplified example would be:
import algorithm
import tables
var test = {"b": 3, "a": 5, "d": 6, "c": 42}.toTable
for i in test.keys():
echo i, ": ", test[i]
# This is the pythonic way (ignoring the irritating requirement to always
provide a cmp
# function), but it fails with "attempting to call undeclared routine:
'keys'"
for i in sorted(test.keys(), cmp=system.cmp):
echo i, ": ", test[i]
# This works, but seems a bit "fussy" to import an extra module and call an
extra proc
# just to be able to use an iterator's output as an openArray. It also
took me a **long**
# time to find the function when I was searching the documentation.
import sequtils
for i in sorted(toSeq(test.keys()), cmp=system.cmp):
echo i, ": ", test[i]
Run
Is there a cleaner way of making iterators be usable in places where an
openArray is needed?
* * *
Also as an aside, what's the reason behind the sort functions not assuming
system.cmp if no cmp parameter is specified? This has caught me out countless
times when I do:
import algorithm
var arr = [1, 5, 3, 6, 7]
arr.sort() # should be arr.sort(cmp=system.cmp)
echo arr
Run
and getting
Error: type mismatch: got <array[0..4, int]>
but expected one of:
proc sort[T](a: var openArray[T]; cmp: proc (x, y: T): int; order =
SortOrder.Ascending)
proc sort[A, B](t: OrderedTableRef[A, B]; cmp: proc (x, y: (A, B)): int)
proc sort[A, B](t: var OrderedTable[A, B]; cmp: proc (x, y: (A, B)): int)
proc sort[A](t: CountTableRef[A])
proc sort[A](t: var CountTable[A])
expression: sort(arr)
Run
I like the fact I can specify a cmp algorithm, but it would be nice to have a
sensible default...