1\. This is the result of copying from `arr` to `result`, not the actual return 
(`return x` does an implicit `result = x`). The following code avoids it:
    
    
    proc foo(): seq[int] =
      result = @[1, 2, 3]
      echo cast[int](result[0].addr)
    
    var arr = foo()
    echo cast[int](arr[0].addr)
    

You can also avoid copying by using `let` instead of `var` (the copying is done 
to avoid aliasing). Passing a value to a procedure will also not copy it.

2\. There is a `shallowCopy` that avoids the copying. Note that `shallowCopy` 
is unsafe when the target is a global variable or managed heap location and the 
source is a constant. You can avoid the unsafety via using a version where the 
right-hand side must be mutable, e.g.:
    
    
    proc `<-`[T](lhs: var T, rhs: var T) {.noSideEffect, magic: "ShallowCopy".}
    

3\. If throughput is your concern, then manual memory management won't help you 
much per se. The primary cost of the the GC in Nim is the 
allocation/deallocation overhead (plus the write barrier, but you incur that 
only if you write a reference to a heap location or global variable), and you 
incur that in C/C++ also, unless you use custom allocation schemes. I know that 
Araq is also working on a region-based collector, which might alleviate the 
overhead (enabled via `--gc:stack`, not sure how mature it is). Note that RAII 
in particular may not help you much; reference counting as in `std::shared_ptr` 
has overhead than Nim's GC, and something like `std::unique_ptr` is either not 
memory-safe or incurs significant overhead (C++ chose the memory-unsafe 
option). In order to have memory-safe move semantics without overhead, you need 
linear or affine types, which would be a significant increase in language 
complexity.

Reply via email to