My argument had nothing to do with synchronization.

FTR I find the synchronization argument also extremely dubious. By that
argument, you also can't pass the address to a local variable to another
function, when using it as a value elsewhere. It's a weird argument to
make. time.Time uses a mix of pointer- and value receivers and IMO no one
can make a serious argument that this would expose programs to risks of
data races.

But to repeat my actual argument in favour of (sometimes) mixing receiver
kinds:
1. It is totally reasonable to use some types as values.
2. Such types, intended to be used as values, will need to use
value-receivers for some methods, as otherwise their value-version does not
implement certain interfaces (methods are not promoted from pointer to
value types). Like fmt.Stringer, for example. And
3. such types still need to sometimes use pointer-receivers, to implement
functionalities like unmarshalling.

time.Time is a standard library example of such a type. I also provided an
example for an "enum-like" type implementing flag.Value.

On Mon, 7 Oct 2024 at 23:57, Robert Engels <reng...@ix.netcom.com> wrote:

> I am pretty sure it is immaterial. If the object isn’t immutable any copy
> or mutation operation needs to be synchronized.
>
> But the problem afaik is that you can’t control synchronization when the
> object is copied for a value receiver - which means you cant properly
> synchronize when you have pointer and value receivers unless you do it
> externally (which is a huge pain to do everywhere).
>
> On Oct 7, 2024, at 4:43 PM, 'Axel Wagner' via golang-nuts <
> golang-nuts@googlegroups.com> wrote:
>
> 
> No offence, but I made an argument. You don't have to agree with the
> argument and it might be wrong. But to convince me, at least, that argument
> would need to actually be referenced.
>
> I gave reasons why, in my opinion, *not* mixing value and pointer
> receivers sometimes leads to incorrect code. So as far as I'm concerned
> (until someone tells me my reasons are wrong) Goland's linter simply
> encourages you to write bad code. It would not be the first time that I
> strongly disagree with the recommendations of an IDE. Goland in particular
> has a history of making, in my opinion, pretty questionable decisions.
>
> On Mon, 7 Oct 2024 at 22:39, Cleberson Pedreira Pauluci <
> pauluci.cleber...@gmail.com> wrote:
>
>> Many places and books I've read generally say: If a function needs to
>> update a variable, or if an argument is so large that we want to avoid
>> copying it, we should pass the pointer. Same for methods (pointer
>> receiver). (The Go programming language book).
>>
>> About mixing "value receiver" and "pointer receiver". Even the IDE
>> complains about this and recommends following the Go documentation. (Goland)
>>
>>
>> Em segunda-feira, 7 de outubro de 2024 às 15:15:25 UTC-3, burak serdar
>> escreveu:
>>
>>> Mixing pointer and value receivers can be race-prone, because of the
>>> copying involved in passing value receivers.
>>>
>>> On Mon, Oct 7, 2024 at 12:03 PM 'Axel Wagner' via golang-nuts
>>> <golan...@googlegroups.com> wrote:
>>> >
>>> > To be honest, I always found this recommendation a little bit strange,
>>> personally.
>>> >
>>> > I'll note that the standard library does not really keep to this
>>> either. For example, time.Time.UnmarshalText (obviously) has a
>>> pointer-receiver, while almost all other methods on time.Time have a value
>>> receiver.
>>> > And if you implement flag.Value, the Set method obviously needs a
>>> pointer receiver, but if the String method has one as well, it won't print
>>> properly when used as a value. In basically every implementation of
>>> flag.Value I've ever written, String needed a value receiver, while Set
>>> needed a pointer receiver.
>>> >
>>> > I understand the basic idea of the advice, that if a type keeps state
>>> that is manipulated via methods, then it should generally be passed around
>>> as a pointer, so giving all the methods a pointer-receiver works well. But
>>> if a type *is* intended to be used as a value (like time.Time or Enum in my
>>> example) then you will almost certainly end up with a mix of receiver kinds
>>> - as soon as you want to add any form of de-serialization to it. So "don't
>>> mix receiver kinds" seems like misleading advice to me.
>>> >
>>> > On Mon, 7 Oct 2024 at 19:44, Ian Lance Taylor <ia...@golang.org>
>>> wrote:
>>> >>
>>> >> On Mon, Oct 7, 2024 at 10:29 AM Ken Lee <ken.lee....@gmail.com>
>>> wrote:
>>> >> >
>>> >> > ---
>>> >> > There is a consideration to make, though: historically it has been
>>> considered bad form in Go to give a type a mix of value and pointer
>>> receivers in methods without a very specific reason for doing so.
>>> >> > ---
>>> >> >
>>> >> > Is this still the case now? As in 2024.
>>> >>
>>> >> As a general guideline, yes.
>>> >>
>>> >> https://go.dev/wiki/CodeReviewComments#receiver-type
>>> >>
>>> >> Ian
>>> >>
>>> >>
>>> >>
>>> >> > On Sunday 13 January 2013 at 7:03:29 am UTC+8 Kevin Gillette wrote:
>>> >> >>
>>> >> >> Indeed. In addition to implicit dereferencing for value receivers,
>>> the reverse also works as well: anything that is addressable (including
>>> 'value' variables on the stack, or a field of element of anything that's
>>> addressable) will implicitly be addressed when a pointer-receiver method is
>>> called on them (though you must explicitly use the address operator when
>>> you need to pass value variables as pointers).
>>> >> >>
>>> >> >> There is a consideration to make, though: historically it has been
>>> considered bad form in Go to give a type a mix of value and pointer
>>> receivers in methods without a very specific reason for doing so. The
>>> typical justification is that a small struct in a getter method might as
>>> well have a value receiver even though the corresponding setter method uses
>>> a pointer receiver; this, however, can lead to confusion on the part of the
>>> app programmer if they start out using only the read-only methods upon what
>>> turns out to be a value-copy of the original (but hey, it compiled and
>>> seems to work, so it must be correct) -- when use of pointer-receiver
>>> methods don't seem to produce the documented changes in the original, it
>>> can be difficult to debug.
>>> >> >>
>>> >> >>
>>> >> >> On Saturday, January 12, 2013 3:17:16 PM UTC-7, Dave Collins
>>> wrote:
>>> >> >>>
>>> >> >>> On Saturday, January 12, 2013 3:52:35 PM UTC-6, Taric Mirza
>>> wrote:
>>> >> >>>>
>>> >> >>>> Thanks! Works like a charm and is helping cleaning up my code a
>>> ton.
>>> >> >>>>
>>> >> >>>> One other question, this is really more about coding style:
>>> >> >>>>
>>> >> >>>> In the case where you manipulate members of the struct, then
>>> using
>>> >> >>>> pointers as in your example is the way to go.
>>> >> >>>>
>>> >> >>>> But, you have a choice for functions that just read values from
>>> the
>>> >> >>>> struct instead of manipulating it. Is there a best practice
>>> coding
>>> >> >>>> style here, between dereferencing the struct and then using
>>> that, or
>>> >> >>>> dereferencing each member of the struct as you go? eg:
>>> >> >>>>
>>> >> >>>> // A:
>>> >> >>>>
>>> >> >>>> laser := worldobj.(*Laser)
>>> >> >>>> fmt.Printf("%0.4f,%0.4f", (*laser).x, (*laser).y)
>>> >> >>>>
>>> >> >>>> versus
>>> >> >>>>
>>> >> >>>> // B:
>>> >> >>>>
>>> >> >>>> laser := *(worldobj.(*Laser))
>>> >> >>>> fmt.Printf("%0.4f,%0.4f", laser.x, laser.y)
>>> >> >>>>
>>> >> >>>>
>>> >> >>>> I'm kind of torn. I would imagine A) has slightly better
>>> >> >>>> performance, and doesn't require any code-rework if you later on
>>> need
>>> >> >>>> to manipulate the struct.
>>> >> >>>>
>>> >> >>>> On the other hand, B) is more readable since you don't have to
>>> look at
>>> >> >>>> pointers all over the place, just on one line.
>>> >> >>>
>>> >> >>>
>>> >> >>> Actually, you don't need to dereference at all. Go automatically
>>> handles this for you.
>>> >> >>>
>>> >> >>> See this example: http://play.golang.org/p/ANaKaFSQLn
>>> >> >>>
>>> >> > --
>>> >> > You received this message because you are subscribed to the Google
>>> Groups "golang-nuts" group.
>>> >> > To unsubscribe from this group and stop receiving emails from it,
>>> send an email to golang-nuts...@googlegroups.com.
>>> >> > To view this discussion on the web visit
>>> https://groups.google.com/d/msgid/golang-nuts/03df7dce-5c48-44a3-bc3c-851ded2a1f08n%40googlegroups.com.
>>>
>>> >>
>>> >> --
>>> >> You received this message because you are subscribed to the Google
>>> Groups "golang-nuts" group.
>>> >> To unsubscribe from this group and stop receiving emails from it,
>>> send an email to golang-nuts...@googlegroups.com.
>>> >> To view this discussion on the web visit
>>> https://groups.google.com/d/msgid/golang-nuts/CAOyqgcX7v9Edk5beRH38tfJO18ZUXv-nOHsEPPCfMQy0hz%3DFdw%40mail.gmail.com.
>>>
>>> >
>>> > --
>>> > You received this message because you are subscribed to the Google
>>> Groups "golang-nuts" group.
>>> > To unsubscribe from this group and stop receiving emails from it, send
>>> an email to golang-nuts...@googlegroups.com.
>>> > To view this discussion on the web visit
>>> https://groups.google.com/d/msgid/golang-nuts/CAEkBMfGcq2nxaik_qAWoX81W-tTKRRYBDM5_6%3DefSv4tr8b03g%40mail.gmail.com.
>>>
>>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "golang-nuts" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to golang-nuts+unsubscr...@googlegroups.com.
>> To view this discussion on the web visit
>> https://groups.google.com/d/msgid/golang-nuts/9b28006b-c310-417e-9afc-e7f5c470641cn%40googlegroups.com
>> <https://groups.google.com/d/msgid/golang-nuts/9b28006b-c310-417e-9afc-e7f5c470641cn%40googlegroups.com?utm_medium=email&utm_source=footer>
>> .
>>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/CAEkBMfEj%3DQACB31VMc7ami7xt9tMF00kYxFUfZpWfZ0j65GWsw%40mail.gmail.com
> <https://groups.google.com/d/msgid/golang-nuts/CAEkBMfEj%3DQACB31VMc7ami7xt9tMF00kYxFUfZpWfZ0j65GWsw%40mail.gmail.com?utm_medium=email&utm_source=footer>
> .
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAEkBMfFYZ1DTD9fTVzNHtOp7Ed7w3_x8QbxsB2x_%2BTs%3DtxY0BA%40mail.gmail.com.

Reply via email to