User-specified input buffers could be added in order to reduce the amount of allocations that are performed:
proc slice(s: string; first, last: int; ret: var string) =
for i in first .. last:
ret.add s[i]
How could the same be done for iterators? It might be trivial with userland iterators, but they are difficult to implement without concepts.
Then there's the issue of not being able to choose which type of allocations to use for large parts of the standard library, and some people seem to be convinced that this will remain the case for some reason, but hopefully we can prove these people wrong. Things that make it difficult to adapt the modules in this regard include things such as broken concepts and possibly the absence of other language features that might make it more convenient to develop and use such interfaces.
It might be trivial with userland iterators, but they are difficult to implement without concepts.
Maybe, I dunno. The real problem seems to be that functional programming simply doesn't work for performance. You always end up transforming the return type T to a var T parameter and lose composability along the way (f(g(x)) is not possible anymore). I envisioned an asFunc macro that transforms a proc foo(x: var string) into a proc foo(): string so that at least not 2 versions of these procs have to be maintained, but this still means that you need to call the var version of foo for performance... The only real solution seems to be a general complex term rewriting macro that eliminates and aggressively reuses temporary strings.