Last active
February 15, 2025 18:44
-
-
Save ZoomTen/98332bf74cb0082378557cc3bc96482a to your computer and use it in GitHub Desktop.
The thing Nim tries to warn me about when using closures
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
proc b(x: ptr seq[int]): auto = | |
proc a(): seq[int] = | |
x[].add(10) | |
return x[] | |
a | |
proc ax(): auto = | |
# allocate a sequence manually | |
# will be GC'd at the first opportunity | |
var k = @[1, 2, 3] | |
# pass its pointer to the crasherinator | |
let m = b(k.addr) | |
echo m() | |
echo m() | |
echo m() | |
echo m() | |
echo m() | |
echo m() | |
m | |
# k is deleted here, but we return a | |
# closure that still holds its reference | |
proc ll(): auto = | |
let p = ax() | |
# k is deleted, but the closure env still | |
# holds a reference to it | |
echo p() | |
echo p() | |
echo p() | |
echo p() | |
echo p() | |
p | |
let k = ll() | |
# boom | |
echo k() | |
echo k() | |
echo k() | |
echo k() | |
echo k() | |
echo k() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
proc a(x: ref seq[int]): auto = | |
# nim knows this ref is still used | |
# when this is invoked, and so is | |
# still valid (i think) | |
proc b(): seq[int] = | |
x[].add(10) | |
return x[] | |
b | |
proc ax(): auto = | |
# create an intentional reference to a sequence | |
# will be GC'd properly | |
let k = new seq[int] | |
# populate this sequence manually | |
k[].add(1) | |
k[].add(2) | |
k[].add(3) | |
# before passing it to the crasherinator | |
let m = a(k) | |
echo m() | |
echo m() | |
echo m() | |
echo m() | |
echo m() | |
echo m() | |
m | |
# a reference to k still exists in the closure | |
# won't be deleted yet because it's a ref | |
proc ll(): auto = | |
let p = ax() | |
echo p() | |
echo p() | |
echo p() | |
echo p() | |
echo p() | |
p | |
let k = ll() | |
echo k() | |
echo k() | |
echo k() | |
echo k() | |
echo k() | |
echo k() | |
# no crash here! |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment