On Wed, Jan 20, 2021 at 11:08 AM Brian Candler <b.cand...@pobox.com> wrote:

> The end result is there's a crucial but subtle difference between:
>
> type Foo interface { ... }
> func f(v Foo) ...
>
> and
>
> type Foo interface { ... }
> func f[T Foo](v T) ...
>
> Given that the second case supports both concrete types *and* interface
> types, then it seems to me that comparing a value with nil is a
> semantically valid thing to do.
>

FWIW, it's also possible to write a constraint that can *only* be satisfied
by concrete types - namely one containing a type-list.

IMO it is confusing to allow comparing generic values to nil, in general.
If we could, I would either assume I can compare any *non*-generic value to
nil. I would assume we can always go from a generic function to an
instantiated one by substituting all occurrences of the type-parameters.
But IMO, nil is already confusing enough as it is.

I think the solutions Patrick and Ian provided for checking if an interface
is nil, or a value is zero, are enough. Because, to be clear: Calling a
method on an interface can panic *whether or not that interface is nil*.
Fundamentally, the case where a caller passes you a nil-interface is not
different from the case where a caller passes you an interface with a
method that dereferences a nil-pointer or accesses a slice out of bounds -
or an interface that just calls panic("foo") in one of its methods. It's a
bug in the caller and panicing in such a case is the correct thing to do.
You will never be able to statically catch all bugs or statically prevent
all panics. I don't think this particular panic is special enough to give
it extra attention - because, again, you *can* do the check, if you want
to, it's just not super convenient.


If the function specialisation is a concrete type, then that comparison
> would always be false and the code path optimised out.
>
> Alternatively, generics could exclude interface values.  But then you get
> the weird situation that a generic function declaration that *looks* like
> an interface type, explicitly disallows interface type values!
>
> ---- 8< ----
>
> With my wild hat on: it makes me wonder what would happen if the generics
> proposal became nothing more than interfaces with linked constraints - so
> that you could say "this function takes a function of type T (interface C)
> and returns *the same type* T", or "this function takes a []T and returns a
> value of *the same type* T".
>
> What I mean is, the difference between
> func f(a, b fmt.Stringer) c fmt.Stringer { ... }
> and
> func f[T fmt.Stringer](a, b T) c T { ... }
> would simply be that a, b and c had to be of the *same* concrete type -
> but were otherwise still interface values (and specialisation, if
> implemented, would just be a hidden optimisation).
>
> The obvious problem is that if you actually pass interface values around,
> then many type-mismatch violations couldn't be detected until runtime.
>
> However: I find the same problem occurs with the current generics
> implementation, *if* you pass interface variables.  Check this out:
> https://go2goplay.golang.org/p/F08gh5gotsO
> Print2() expects that both arguments are of the same type - but in the
> final call, they are not!  There is neither compile-time nor run-time error.
>
> ISTM that constrained interface types *could* also be checked at compile
> time, in the common case where the caller passes concrete types. Rewriting
> to use plain interfaces instead of generics:
> https://go2goplay.golang.org/p/CfkvAcgr8mC
> I think that an interface type constraint system *could* statically check
> that both args of the first Print2() call were (or were not) the same type.
>
> What you might end up with is linked type constraints being a natural
> extension of interfaces.  Generic specialisation would just be an
> optimisation on top of that (if the call site knows that a particular set
> of concrete types is being used).  Type lists could also become an
> extension of interfaces.
>
> However, that's just off the top of my head.  Whilst I've been following
> generics intermittently, no doubt this has been considered (and discarded)
> before.
>
> Regards, Brian.
>
> --
> 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/34bdb40e-ad0b-47ce-8588-d014d0886470n%40googlegroups.com
> <https://groups.google.com/d/msgid/golang-nuts/34bdb40e-ad0b-47ce-8588-d014d0886470n%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/CAEkBMfGv4iTzqNYnG%2BeQafi5ShgrOEpCtSToR_LTneuAHhMagQ%40mail.gmail.com.

Reply via email to