What do you make of this?
https://go2goplay.golang.org/p/gN-FK2kbYK5

Using interface values, it seems possible to bypass a declared constraint 
that two arguments have the same type.

I am wondering the following.

1. If the function signature says two types should be the same (via type 
parameters), but this can't be determined at compile time, then a runtime 
check should be inserted at the call point - and panic if fail.

2. Since a nil interface value has "no type", then nil interface values 
should be disallowed for arguments defined with type parameters. Again, if 
this can't be determined statically, then add a runtime check and panic.

Incidentally, point (2) also sidesteps the OP's original problem, since it 
guarantees the value can never be nil.

On Wednesday, 20 January 2021 at 10:43:42 UTC axel.wa...@googlemail.com 
wrote:

> On Wed, Jan 20, 2021 at 11:08 AM Brian Candler <b.ca...@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...@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/e4e446de-9be4-4e31-8df7-ed48998022een%40googlegroups.com.

Reply via email to