-
-
Notifications
You must be signed in to change notification settings - Fork 2.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Map is empty if modified in arrays.each
#20008
Comments
It's not a bug.The closure parameter is just a copy, and changes to it are only visible inside the anonymous function. If you pass the pointer, you can achieve the effect you want: import arrays
fn main() {
mut buf := 0
mut ptr := &buf
mut some_array := [1, 2, 3]
arrays.each(some_array, fn [ptr] (e int) {
unsafe { *ptr += e }
})
println(buf) // outputs: 6
} |
See the V documentation: |
Thanks
produce warnings |
As a side note, the decision to pass a copy of a variable to the closure is very confusing. Maybe I'm ignorant, but I don't know any language that would do this. |
They are both |
but is it really pointer indexing? |
The wording of the warning is a bit general, you're right |
python, ruby... x = 10
def add_closure(y):
x += y
print(x) // 10 |
for me it is really hard to understand why the lookup of a key in map or index in an array is an unsafe operation, if the structure is a pointer and safe if it is a value. the lookup happens after dereferencing the pointer I assume, so it should be the same process after that in both cases |
Indexing an array is essentially pointer arithmetic, also known as pointer indexing. arr := [1, 2, 3...] ptr := &arr |
This makes sense. From another point of view, maybe the compiler could infer that some operations that are commonly unsafe are indeed safe, for example:
I would argue that the code in my original example is also "safe" in this sense |
Ideally, this is true, but we can have more complex situations, such as: import arrays
fn main() {
mut buf := 0
mut ptr := &buf
mut some_array := [1, 2, 3]
go/spawn arrays.each(some_array, fn [ptr] (e int) {
*ptr += e
})
println(buf)
ptr = unsafe { nil }
} |
perfectly clear. This is exactly why I mentioned "some operations" :D Thanks for the feedback. The discussion goes too far from the original issue. IMO, the confusion here is that in some languages, closures modify the value they close over. In other languages, they don't, so one needs to be very careful about these semantics. |
Describe the bug
if used as a buffer, a map is empty if modified inside an
arrays.each
call but not empty if modified insidefor
Reproduction Steps
following snippet returns empty buf:
Expected Behavior
a non-empty map is printed like it is done if
arrays.each
replaced withfor
isCurrent Behavior
an empty map is printed
Possible Solution
No response
Additional Information/Context
No response
V version
V 0.4.3 44cf145
Environment details (OS name and version, etc.)
Darwin 23.1.0 Darwin Kernel Version 23.1.0: Mon Oct 9 21:28:12 PDT 2023; root:xnu-10002.41.9~6/RELEASE_ARM64_T8103 arm64
Note
You can use the 👍 reaction to increase the issue's priority for developers.
Please note that only the 👍 reaction to the issue itself counts as a vote.
Other reactions and those to comments will not be taken into account.
The text was updated successfully, but these errors were encountered: