Live data from Hacker News

Proposal: expression to create pointer to simple types

github.com

81–90 of 110 posts

Re: Proposal: expression to create pointer to simple types

#81

Earlier quoted context omitted.

"implicitly allocate" is slightly misleading, imho. It's promoted to a static. There's no malloc involved.

> "implicitly allocate" is slightly misleading Maybe. I just meant that storage is created implicitly (static or stackframe depending on the case), then a reference is created to that .,

Totally, I don't think you're wrong, just like, people read "allocate" in different ways. I wish words were clearer, heh.

Re: Proposal: expression to create pointer to simple types

#82
post #76

Earlier quoted context omitted.

> That's true, but I don't think it's very comparable to slices 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 e…

> 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. Maybe to you, but to me, a pointer going from modifying the value inside of the map to no longer modifying the value inside of the map during any operation is quite a bit different than requiring a reassignment of the s…

> Maybe to you

Yes, I avoid making assumptions about invariants across mutation calls, that's just a bad idea.

> For slices, we know that x[0] will always print 5 until the value of x is reassigned in some way.

Unless an other goroutine is stomping on your backing array anyway.

> It would have the same problem the map does: you'd have to update any pointers into the slice to point to the new slice, otherwise the semantics of the program changes. That is not something the GC currently does, and would require an awful lot of metadata and scanning.

Yes. So maybe we could ignore that useless strawman?

> I'm not sure what this is referring to.

To what I'm quoting.

> I was trying to say that keeping the flexibility to reallocate the backing store of the map during GC

That sounds less like flexibility and more like "let's make the GC slower and more complex for no reason".

Re: Proposal: expression to create pointer to simple types

#83

I was surprised that you can't apply & to any value. I thought it was gut an ordinary operator and it would ensure that the value it was applied to would be put onto the heap. s := S{} sp := &s // Works _ = sp _ = &S{} // Works i := int32(1) ip := &i // Works! _ = ip _ = &int32(1) // Doesn't work! https://play.golang.org/p/fdgvbEwJWgh It seems odd that you can't apply & to a function's return value. I think the best…

& doesn't always imply a value is on the heap. Escape analysis will ensure that pointers to the stack are safe.

Here's an example with a bit of explanation: if you pass a value to fmt.Println it will escape. The raw println builtin does not cause values to escape. So calling the first function twice and seeing the same address for the value strongly implies stack allocation while calling the 2nd function twice and getting different addresses implies heap allocation.

https://play.golang.org/p/PSb1wj1-x1c

Re: Proposal: expression to create pointer to simple types

#84
post #78

Earlier quoted context omitted.

It doesn't have a type in Haskell, from a certain point of view. `3` is polymorphic. Prelude> :t 3 3 :: Num p => p

It does have a type. You just wrote it down!

Hence "from a certain point of view" - I would argue, in fact, that it's extremely similar to the sense in which 3 doesn't have a type in Go. Haskell's type system can express that sense, whereas Go's can't; but it's the same sense.

> It is an error if the constant value cannot be represented as a value of the respective type. An untyped constant has a default type which is the type to which the constant is implicitly converted in contexts where a typed value is required, for instance, in a short variable declaration such as i := 0 where there is no explicit type. The default type of an untyped constant is bool, rune, int, float64, complex128 or string respectively, depending on whether it is a boolean, rune, integer, floating-point, complex, or string constant.

Re: Proposal: expression to create pointer to simple types

#85
post #51

Earlier quoted context omitted.

I don't see how: temp := someFunc() p := &temp is any less explicit than p := &someFunc() It seems that the `&` is still required to put something onto the heap.

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.

Since it doesn't seem like this was answered in the other discussion, the answer is that Go does not allow taking the address of a map value. You get a compile-time error: "cannot take the address of m[x]".

https://play.golang.org/p/rX8A6ez9fVx

Re: Proposal: expression to create pointer to simple types

#86
post #30
post #22

Why can't &3 work? Rob says 3 does not have a type and that's a problem. Would it be possible to change the Go compiler such that 3 has a type? (I'm guessing no, at least not easily, otherwise he'd be suggesting it, but I'm curious about the reason)

From the language specification: > Numeric constants represent exact values of arbitrary precision and do not overflow.

Ok I think I'm not understanding this correctly then. Why does this return an error?

    package main

    import (
        "fmt"
    )
    
    const tst = 1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
    
    func main() {
        fmt.Println("%v", tst)
    }
Error: ./prog.go:16:17: constant 1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 overflows int

See: https://play.golang.org/p/47l5qAsXD5r

Re: Proposal: expression to create pointer to simple types

#87

Earlier quoted context omitted.

What do you mean by assigning to a pointer? You can only assign a pointer value to a pointer variable and you need to get that pointer from & IIUC.

> What do you mean by assigning to a pointer? *x = y

I don't think that does because IIUC you are copying the bits of y to x. So I guess semantically y has escaped but you aren't doing a new heap allocation, you are reusing the memory of x.

Re: Proposal: expression to create pointer to simple types

#88

Earlier quoted context omitted.

No. In this case foo will live on the stack (unless you take its address later). foo := MyStruct{} // Could live on the stack _ := &foo // Oh, now foo must live on the heap.

This isn't even true. No matter what syntax you write inside a function, the Go compiler always has the final say on what is stack allocated and what is heap allocated. Taking the address of foo will not cause foo to be heap allocated unless Go is unable to prove that the pointer will live for less time than the current stack frame. Look up "escape analysis". Basically the only way to guarantee that something will al…

Good point. It isn't "must", I should have said "may".

Re: Proposal: expression to create pointer to simple types

#89
post #76

Earlier quoted context omitted.

> 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. Maybe to you, but to me, a pointer going from modifying the value inside of the map to no longer modifying the value inside of the map during any operation is quite a bit different than requiring a reassignment of the s…

> Maybe to you Yes, I avoid making assumptions about invariants across mutation calls, that's just a bad idea. > For slices, we know that x[0] will always print 5 until the value of x is reassigned in some way. Unless an other goroutine is stomping on your backing array anyway. > It would have the same problem the map does: you'd have to update any pointers into the slice to point to the new slice, otherwise the sema…

I apologize if the tone of my previous comment sounded harsh to you or if some of my arguments sounded like strawmen. I am in good faith trying to interpret your comments as best as I am able. I don't feel like you're giving me the same courtesy, so I'll exit the discussion now. Thanks.

Re: Proposal: expression to create pointer to simple types

#90
post #85
post #51

Earlier 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.

Since it doesn't seem like this was answered in the other discussion, the answer is that Go does not allow taking the address of a map value. You get a compile-time error: "cannot take the address of m[x]". https://play.golang.org/p/rX8A6ez9fVx

Indeed. This is in a thread where the original comment was "I think the best approach would be making & work in basically any scenario." I'm trying to demonstrate the complications of making it work on map accesses.
Post reply on HN