On Tue, May 3, 2022 at 6:08 PM Will Faught <will.fau...@gmail.com> wrote:
>
> My apologies, it seems that "reply all" in the Google Groups UI doesn't send 
> email to individuals like "reply all" in Gmail does, just the group. Response 
> copied below.
>
>> Yes, it can. That's not the issue. The issue is that whether those
>> pointer values are equal for two func values is not intuitive at the
>> language level. When using shared libraries (-buildmode=shared) you
>> can get two different pointer values for references to the same
>> function. When using method values you can get the same pointer value
>> for references to method values of different expressions of the same
>> type. When using closures you will sometimes get the same value,
>> sometimes different values, depending on the implementation and the
>> escape analysis done by the compiler.
>
>
> Interesting. This certainly differs from how I pictured functions working 
> (more like C function pointers with extra steps). I'd be curious to know more 
> about the details. Do you know if that's documented somewhere?

I'm not aware of any specific documentation on the topic, sorry.

The fact that C function pointers are guaranteed to compare equal can
actually be a performance hit at program startup for dynamically
linked C programs.  I wrote up the details of the worst case several
years ago at https://www.airs.com/blog/archives/307.  There are other
lesser issues.


> Just curious, what would be the cost if things were rejiggered under the hood 
> to make function comparisons work? Would any language features be impossible, 
> or would it be worse compiler/runtime complexity/performance, or both?

Regardless of compiler/runtime issues, this would introduce language
complexity, similar to the issues with slices.  We would have to
precisely specify when two func values are equal and when they are
not.  There is no intuitive answer to that.

Does a program like this print true or false?

func F() func() int { return func() int { return 0 } }
func G() { fmt.Println(F() == F()) }

What about a program like this:

func H(i int) func() *int { return func() *int { return &i } }
func J() { fmt.Println(H(0) == H(1)) }

Whatever we define for cases like this some people will be ready to
argue for a different choice.  The costs of forcing a decision exceed
the benefits.


> Regarding expectations, many new Java programmers came from JavaScript (like 
> myself), so the confusion is understandable, but it's not something that 
> necessarily needs to be considered. Arguably, old Java programmers would find 
> `==` confusing for structs, since it doesn't compare references. Bad 
> assumptions are best prevented by proper education and training, not by 
> omitting language features. Wrong expectations aren't the same as foot-guns.

I don't agree.  Unexpected behavior is a footgun.  Go is intended to
be a simple language.  When special explanation is required, something
has gone wrong.

In saying this I don't at all claim that Go is perfect.  There are
places where we made mistakes.  But I don't think that our decision to
not define == on slices or functions is one of them.


> >Just because there are two ways to do something, and people tend to lean 
> >different ways, doesn't mean we shouldn't pick a default way, and make the 
> >other way still possible. For example, the range operation can produce per 
> >iteration an element index and an element value for slices, but a byte index 
> >and a rune value for strings. Personally, I found the byte index 
> >counterintuitive, as I expected the value to count runes like slice 
> >elements, but upon reflection, it makes sense, because you can easily count 
> >iterations yourself to have both byte indexes and rune counts, but you can't 
> >so trivially do the opposite. Should we omit ranging over strings entirely 
> >just because someone, somewhere, somehow might have a minority intuition, or 
> >if something is generally counterintuitive, but still the best approach?

The fact that range over []byte and string are different may well have
been a mistake.  It can certainly be convenient, but it trips people
up.  (Certainly others may disagree with me on this.)


> >The best path is to pick the best way for the common case, and make the 
> >other way possible

I do not agree.  The best path is to make no choice, and force the
program writer to be explicit about what they want.

Ian

-- 
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/CAOyqgcV3PCVT11Vk0tzgVoRGTv%3DYUqDekHeY4taFyAx5%3DCD1bQ%40mail.gmail.com.

Reply via email to