On Tue, May 3, 2022 at 11:01 PM Will Faught <will.fau...@gmail.com> wrote:
>
> On Tue, May 3, 2022 at 7:27 PM Ian Lance Taylor <i...@golang.org> wrote:
>>
>> Does a program like this print true or false?
>>
>> func F() func() int { return func() int { return 0 } }
>> func G() { fmt.Println(F() == F()) }
>>
>
> It would print false, because the function literal creates a new allocation 
> (according to the rule I sketched out). I can see the desire to optimize 
> that, but personally when I write code like that, I'm thinking, "and then 
> return a new function." Causing an allocation isn't surprising behavior here, 
> and so neither is uniqueness in terms of comparisons.
>
>>
>> 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)) }
>>
>
> It would print false for the same reason.
>
>>
>> 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.
>
>
> So on the balance, the cost of making a decision is worth it for something 
> big like dependencies or generics, but not function equality. Well, I guess 
> that's fair enough, but it seems like one could use that kind of argument to 
> undermine any language change, though, including dependencies and generics. 
> It doesn't seem like the function equality rule I sketched out would add 
> much, if any, language complexity. It's only one sentence: "Function values 
> are equal if they were created by the same function literal or declaration."

I don't think that is clear, because it seems to me that each call to
F(), above, returns the same function literal, yet you said that F()
== F() is false.

As an implementation note, currently F() does not allocate.  If we
require that F() != F(), then calling F() must allocate.  Adding an
allocation there is straightforward, but even if we permitted function
comparisons I think that function literals will be used far more than
they are compared, so adding an allocation seems like a poor use of
resources.



>> > 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.
>
>
> I wrote that wrong expectations aren't foot-guns, not that unexpected 
> behaviors aren't foot-guns. Wrong expectations, as in "I can call this 
> pointer-receiver method on this unaddressable value," or "since zero values 
> are useful, I can set keys and values in this zero-value map." Downloading a 
> compiler for some new language I haven't bothered to learn, typing in 
> Java-like stuff, and then being upset when it doesn't work isn't a problem of 
> unexpected behavior, it's a problem of wrong expectations (usually 
> misunderstandings or ignorance).

I don't want to get into a terminology war, but I don't understand the
distinction that you are drawing.  If I have "wrong expectations,"
then what actually happens when I try something is "unexpected
behavior."  It's literally not what I expected.

It's reasonable to say that if you are using a new language you should
read the friendly manual.  But it's also reasonable to say that as
much as possible languages should be unsurprising.  Computer languages
build on each other.  Go has obvious debts to languages like C and
Oberon, and it would be confusing if constructs in Go acted
differently than the identical constructs in those languages.


>> Go is intended to
>> be a simple language.  When special explanation is required, something
>> has gone wrong.
>>
>
> The Go language spec is full of special explanations. The section on 
> comparisons is quite detailed and complicated. I recently had to ask here why 
> the range operation doesn't work for type set unions of slices and maps, 
> which you very kindly answered, if I remember correctly. How is slice 
> equality different in terms of special explanation?

The fact that Go is imperfect, which it is, is not an argument for
adding further imperfections.

> I've argued that slice comparisons make Go even simpler and more consistent 
> with various examples, analogies, and so on. Please see my response to Axel, 
> if you haven't already. Do you have a specific counter argument to any 
> specific argument that I've made regarding simplicity or consistency?

All changes to languages have costs and benefits.  Your arguments
about simplicity and consistency are benefits.  The counter-arguments
that I and several others have been making are costs.  In deciding
whether to change the language we must weigh those costs and benefits
and decide which are more important.

To put it another way, I don't have specific counter arguments to your
specific arguments about simplicity and consistency.  But that doesn't
mean that I agree, it just means that I think that other consequences
are more important.

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/CAOyqgcW4qFK42B7kr3hsmZOi03o4K1e2Xssq%2BGjjMPSsoTvv-Q%40mail.gmail.com.

Reply via email to