Quote from the book:
"The code employs a number of optimisations. In general the biggest slowdowns in Nim applications are a result of too many variables being allocated and deallocated. The parse procedure could return the parsed tokens but that would result in a new string being allocated each iteration. Instead the parse procedure accepts a mutable reference to 2 strings and 2 ints, which it then fills with the parsed tokens."
Of course that makes much sense. But as I already mentioned in IRC, when looking at the Nim code it is not easy to proof that parseUtils.parseUntil() will not allocate new strings. It uses token = substr(s, start, i-1)" which looks for me as token is new allocated.
proc substr*(s: string, first, last: int): string {.magic: "CopyStrLast", importc: "copyStrLast", noSideEffect.}
OK, it is magic.
So lets test it.
import parseutils
var a = "abc.def"
var b: string = newStringOfCap(1024)
echo cast[int](addr(b[0]))
discard parseUntil(a, b, '.')
echo cast[int](addr(b[0]))
For me result is
140517950218336 140517950214280
For me that looks not really like reusing the same string. And it works fine with plain "var b: string" -- which was not really obvious from the book. :-(