1. pointer in Thing, var param (drawback: you have to make sure that the pointer stays valid):
type Thing = object list: ptr seq[int] proc initThing(list: var seq[int]): Thing = result.list = list.addr Run 2. ref original var original: ref seq[int] new(original) original[] = @[1, 2, 3, 4, 5] type Thing = object list: ref seq[int] proc initThing(list: ref seq[int]): Thing = result.list = list Run 3. cast ptr to ref (drawback: this is a lie, easy to get a reuse after free): var original = @[1, 2, 3, 4, 5] type Thing = object list: ref seq[int] proc initThing(list: var seq[int]): Thing = result.list = cast[ref seq[int]](list.addr) Run 4. forget about preserving original: type Thing = object list: ref seq[int] proc initThing(list: seq[int]): Thing = new(result.list) result.list[] = list var thing = initThing(@[1, 2, 3, 4, 5]) let original = thing.list Run Example problem with #3: type Thing = object list: ref seq[int] proc initThing(list: var seq[int]): Thing = result.list = cast[ref seq[int]](list.addr) var thing: Thing new(thing.list) block: var original = @[1, 2, 3, 4, 5] thing = initThing(original) original[0] = 666 echo thing.list.repr # use after free: ref @[666, 0, 3, 20, 3467820324424670016] Run