> (...) that has the nasty problem that 3 does not have a type (...) How is that possible? At least in Common Lisp, all literal objects have types, and the same is true of C from what I have just checked.
Proposal: expression to create pointer to simple types
61–70 of 110 posts
Re: Proposal: expression to create pointer to simple types
#62Earlier quoted context omitted.
What about `&m[x]` where m is some map? Does that heap allocate and create a copy, or is it a pointer to the actual storage slot? If the former, that's a hidden copy/allocation that didn't exist before, and if it's the latter, resizing the map invalidates the pointer, so it must be updated somehow.
`&` will "move" something to the heap if it isn't already on the heap. The simpler way to think about it is that in Golang everything is on the heap. However the optimizer will move things to the stack if they don't have their address taken. I think the point about explicitness is that if you don't use `&` then it will be able to be put on the stack. So `&` doesn't cause a heap allocation but lack of `&` (or new()) c…
x := make(map[int]int)
x[0] = 5
y := &x[0]
*y = 10
print(x[0]) // 5 or 10?
x[0] = 6
print(*y) // 6 or 10?
// force the map to grow and reallocate the buckets
for j := 1; j
The crux of the problem is answering what y actually points at: the value in the map bucket, or some freshly allocated value? There are problems with whichever one you pick.edit: changed the second print to *y instead of x[0]. thanks masklinn for catching this error.
Re: Proposal: expression to create pointer to simple types
#63Earlier quoted context omitted.
What about `&m[x]` where m is some map? Does that heap allocate and create a copy, or is it a pointer to the actual storage slot? If the former, that's a hidden copy/allocation that didn't exist before, and if it's the latter, resizing the map invalidates the pointer, so it must be updated somehow.
`&` will "move" something to the heap if it isn't already on the heap. The simpler way to think about it is that in Golang everything is on the heap. However the optimizer will move things to the stack if they don't have their address taken. I think the point about explicitness is that if you don't use `&` then it will be able to be put on the stack. So `&` doesn't cause a heap allocation but lack of `&` (or new()) c…
I think assigning to a pointer would cause an escape.
Just taking a reference wouldn't though, the reference still has to escape (of course you'd usually take a reference so that it can escape but that's not always the case, especially with inlining).
Re: Proposal: expression to create pointer to simple types
#64How exemplary that he filled in the full template questionnaire for language changes, including questions such as "Would you consider yourself a novice, intermediate, or experienced Go programmer?" (he replied "I have some experience").
IIRC Tim Berners-Lee also rather amusingly called himself a "Web Developer" at a conference.
Re: Proposal: expression to create pointer to simple types
#65Earlier quoted context omitted.
`&` will "move" something to the heap if it isn't already on the heap. The simpler way to think about it is that in Golang everything is on the heap. However the optimizer will move things to the stack if they don't have their address taken. I think the point about explicitness is that if you don't use `&` then it will be able to be put on the stack. So `&` doesn't cause a heap allocation but lack of `&` (or new()) c…
I think I didn't communicate my point clearly. Consider this hypothetical program: x := make(map[int]int) x[0] = 5 y := &x[0] *y = 10 print(x[0]) // 5 or 10? x[0] = 6 print(*y) // 6 or 10? // force the map to grow and reallocate the buckets for j := 1; j The crux of the problem is answering what y actually points at: the value in the map bucket, or some freshly allocated value? There are problems with whichever one y…
Do you mean `print(*y)`? You just assigned to `x[0]` so its value should not be in question.
Also
> if it's the latter, resizing the map invalidates the pointer, so it must be updated somehow.
It doesn't (have to) invalidate the pointer though. When resized the map's content get copied to a new backing buffer, the pointer can keep pointing to the old buffer. That's basically the same behaviour as slices: when a slice resizes, a new backing array is allocated, the contents get copied to the new array, and the slice is retargeted to the new array. There can be other slices pointing to the old array (it's of course a very bad idea to update slices to shared arrays, but Go will let you do it).
Re: Proposal: expression to create pointer to simple types
#66Earlier quoted context omitted.
One of the things I think the Go tutorials don't make a big enough deal of is that Go is relatively explicit about allocations. := isn't just a shortcut for declaring variables, it's an allocation, and an error to use it when it doesn't allocate. var X Sometype isn't just a declaration, it's an allocation. := kinda smears the clarity by not allocating if you have a variable on the left that is already allocated, and…
I’m not sure I understood this correctly. Does the following allocate (on the heap)? foo := MyStruct{}
I believe the person you are replying to was making a confusing point about some hand wavy notion of "any kind of allocation", which includes stack allocations... which are determined at compile time, not with "alloca".
Re: Proposal: expression to create pointer to simple types
#67How exemplary that he filled in the full template questionnaire for language changes, including questions such as "Would you consider yourself a novice, intermediate, or experienced Go programmer?" (he replied "I have some experience").
Re: Proposal: expression to create pointer to simple types
#68Earlier quoted context omitted.
I think I didn't communicate my point clearly. Consider this hypothetical program: x := make(map[int]int) x[0] = 5 y := &x[0] *y = 10 print(x[0]) // 5 or 10? x[0] = 6 print(*y) // 6 or 10? // force the map to grow and reallocate the buckets for j := 1; j The crux of the problem is answering what y actually points at: the value in the map bucket, or some freshly allocated value? There are problems with whichever one y…
> print(x[0]) // 5, 6 or 10? Do you mean `print(*y)`? You just assigned to `x[0]` so its value should not be in question. Also > if it's the latter, resizing the map invalidates the pointer, so it must be updated somehow. It doesn't (have to) invalidate the pointer though. When resized the map's content get copied to a new backing buffer, the pointer can keep pointing to the old buffer. That's basically the same beha…
That's true, but I don't think it's very comparable to slices. With slices, you have to explicitly reallocate either by creating a whole new slice or using append. Reslicing, indexing, or other operations do not reallocate. On the other hand, maps may end up resizing on any operation that involves them, or even theoretically in the background without any operations (during GC, for example). It would be unfortunate to lose that implementation flexibility, and keeping it means that you're essentially picking the "make a copy" option.
Re: Proposal: expression to create pointer to simple types
#69Re: Proposal: expression to create pointer to simple types
#70Earlier quoted context omitted.
> print(x[0]) // 5, 6 or 10? Do you mean `print(*y)`? You just assigned to `x[0]` so its value should not be in question. Also > if it's the latter, resizing the map invalidates the pointer, so it must be updated somehow. It doesn't (have to) invalidate the pointer though. When resized the map's content get copied to a new backing buffer, the pointer can keep pointing to the old buffer. That's basically the same beha…
> It doesn't (have to) invalidate the pointer though. When resized the map's content get copied to a new backing buffer, the pointer can keep pointing to the old buffer. That's true, but I don't think it's very comparable to slices. With slices, you have to explicitly reallocate either by creating a whole new slice or using append. Reslicing, indexing, or other operations do not reallocate. On the other hand, maps ma…
It's exactly the same.
> With slices, you have to explicitly reallocate either by creating a whole new slice or using append.
That's a distinction without a difference. `append` does not "explicitly reallocate", it may or may not reallocate, you've no idea. Even if the backing array is full, it might be realloc'd in-place.
> On the other hand, maps may end up resizing on any operation that involves them, or even theoretically in the background without any operations (during GC, for example).
So?
Also technically nothing prevents a GC from reallocating the slice.
> It would be unfortunate to lose that implementation flexibility, and keeping it means that you're essentially picking the "make a copy" option.
I've never heard of a hashmap implementation which would do otherwise.
Trying to extend in-place and attempting to properly redistribute if that works sounds like absolute hell. Likewise trying to shrink in-place, though at least you've got some scratch space which you don't have in the other case: you'd have to segregate everything into one half of the map then insert them in the other half, before shrinking your allocation, which might give you a new allocation anyway, at which point you've moved all your values thrice whereas just creating a new allocation and reinserting your stuff there is a single move.