This will be a Go wart that will never go away. All languages have warts. This 
one just happens to be on the top of the index finger  There is so little 
utility in a nil interface but it’s there. 

> On Aug 27, 2020, at 5:14 AM, 'Axel Wagner' via golang-nuts 
> <golang-nuts@googlegroups.com> wrote:
> 
> 
> 
>> On Thu, Aug 27, 2020 at 11:39 AM targe...@gmail.com <target....@gmail.com> 
>> wrote:
>> > I'm saying the current situation is less confusing than what you describe, 
>> > yes.
>> > AIUI, with what you describe, if I have a variable `x` of type `*T` and an 
>> > interface variable `y`, then `y = x` and `y = (*T)(x)` have different 
>> > semantics. I think it is strange to have a conversion of `x` *to its own 
>> > type* have any sort of semantic implication. It should be a no-op.
>> 
>> It may be expressed in some different way. To me, if `x == nil` and then `y 
>> != nil` after `y = x` is much more confusing.
> 
> And obviously you are not alone. Even though I really don't understand why 
> this isn't just one of those "you learn about it, you know about it, you 
> never run into any problems again" type of things. It does seem to come up 
> sufficiently often to be a problem. And there are solutions that I think are 
> fine. For example, using a different identifier (say `none`) to denote the 
> zero-value of interfaces would be fine by me.
> 
> But solutions that try to give special treatment to nil-values when they are 
> put into interfaces just seem wrong to me. They single out nil-values as 
> somehow special or less valid than other values. They single out 
> pointer/slice/map/chan types as somehow special over int/bool/string/… types. 
> It just seems undeniable to me, that they make the language *less* consistent.
> 
>> If you ask my opinion, I would make interfaces compare to nil on just data 
>> pointer. If one wanted interface which doesn't require data, he could've 
>> easily created one with static stub variable. No additional checks, no 
>> "semi-nil" fat pointers, everything simple and consistent.
> 
> The rule is very simple: A nil-interface is one that has no dynamic value. 
> All values are treated the same for this purpose. All types are treated the 
> same. I don't understand how that is anything but simple and consistent. It 
> might be less understandable for some other reason, but I don't think it's 
> simplicity or consistency.
> 
>> 
>>> On Thursday, August 27, 2020 at 12:20:59 PM UTC+3 axel.wa...@googlemail.com 
>>> wrote:
>>>> On Thu, Aug 27, 2020 at 11:10 AM targe...@gmail.com <targe...@gmail.com> 
>>>> wrote:
>>>> it would definitely. Though price for consistency looks very much 
>>>> acceptable.
>>> 
>>> 
>>> I don't think "consistency" is at all the right word here. If anything, 
>>> things would get *less* consistent, not more.
>>> 
>>>> > Personally, I would also find it very confusing, if converting a T to a 
>>>> > T changed program behavior
>>>> Sorry, didn't get it. Are you saying that nil pointer -> nil interface is 
>>>> more confusing?
>>> 
>>> I'm saying the current situation is less confusing than what you describe, 
>>> yes.
>>> 
>>> AIUI, with what you describe, if I have a variable `x` of type `*T` and an 
>>> interface variable `y`, then `y = x` and `y = (*T)(x)` have different 
>>> semantics. I think it is strange to have a conversion of `x` *to its own 
>>> type* have any sort of semantic implication. It should be a no-op.
>>> 
>>> 
>>>> 
>>>>> On Thursday, August 27, 2020 at 11:49:16 AM UTC+3 
>>>>> axel.wa...@googlemail.com wrote:
>>>>>>> On Thu, Aug 27, 2020 at 10:06 AM targe...@gmail.com 
>>>>>>> <targe...@gmail.com> wrote:
>>>>>>> Not sure if it was mentioned here, but IMO the main issues isn't nil 
>>>>>>> data itself, but how easy it's created. It'd be much less of a surprise 
>>>>>>> if creating nil-data required explicit cast from nil struct pointer to 
>>>>>>> interface pointer and resulted in just nil interface pointer in case of 
>>>>>>> implicit cast. Though such change is almost certainly breaking one.
>>>>>> 
>>>>>> This would require to insert extra nil-checks when assigning a 
>>>>>> pointer-value to an interface, as the compiler can't know if a pointer 
>>>>>> is nil or not. Personally, I would also find it very confusing, if 
>>>>>> converting a T to a T changed program behavior (though arguably, there 
>>>>>> is one such case currently with `uintptr(uintptr(unsafe.Pointer))`. But 
>>>>>> usage of `unsafe` seems sufficiently advanced).
>>>>>>  
>>>>> 
>>>>>> 
>>>>>>> On Monday, August 24, 2020 at 7:08:17 AM UTC+3 alex.be...@gmail.com 
>>>>>>> wrote:
>>>>>>> Can we at least move with the https://github.com/golang/go/issues/22729 
>>>>>>> , please? Anything will help with the current mess.
>>>>>>> 
>>>>>>> 
>>>>>>>> On Sunday, August 23, 2020 at 8:52:30 PM UTC-7, Ian Lance Taylor wrote:
>>>>>>> 
>>>>>>>> On Sun, Aug 23, 2020 at 1:16 PM Denis Cheremisov 
>>>>>>>> <denis.c...@gmail.com> wrote: 
>>>>>>>> > 
>>>>>>>> > You may use something like this 
>>>>>>>> > 
>>>>>>>> >         value2 := 
>>>>>>>> > *(*uint64)(unsafe.Pointer(uintptr(unsafe.Pointer(&value)) + 8)) 
>>>>>>>> >         if value2 == 0 { 
>>>>>>>> >                 return true 
>>>>>>>> >         } 
>>>>>>>> > 
>>>>>>>> > on AMD64, should work also for any 64 bit architecture (at least I 
>>>>>>>> > believe so). Remember though this is hacky and may stop working 
>>>>>>>> > once. 
>>>>>>>> 
>>>>>>>> You could do that, but please don't. 
>>>>>>>> 
>>>>>>>> Ian 
>>>>>>>> 
>>>>>>>> 
>>>>>>>> > воскресенье, 23 августа 2020 г. в 22:58:51 UTC+3, Aviv Eyal: 
>>>>>>>> >> 
>>>>>>>> >> I was trying to show that the current behavior is confusing and 
>>>>>>>> >> that fmt.Print() needing to resort to panic-and-recover is kinda 
>>>>>>>> >> code smell, but I sorts-of convinced myself that the current 
>>>>>>>> >> behavior is right, or at least consistent. 
>>>>>>>> >> 
>>>>>>>> >> In my code, I got bit because I sometimes use v *Type to denote "I 
>>>>>>>> >> may or may not have a value here" (where Type is a value-type). 
>>>>>>>> >> This is probably a bad practice on my behalf, because I break the 
>>>>>>>> >> Liskov substitution principle: there is a value of `*Type` that is 
>>>>>>>> >> not a valid value of `Type`, and I let this value slip by. 
>>>>>>>> >> 
>>>>>>>> >> In this case, `v Type` implements Stringer (i.e. valid callee for 
>>>>>>>> >> `v.String()`, but `v *Type`, in the strictest sense, does not. 
>>>>>>>> >> The only reason we can write: 
>>>>>>>> >> 
>>>>>>>> >>     func (Type) String() string {...} 
>>>>>>>> >>     v *Type = &Type{...} 
>>>>>>>> >>     _ = v.String() 
>>>>>>>> >> 
>>>>>>>> >> and have it compile, is syntactic sugar: `v` gets implicitly 
>>>>>>>> >> de-referenced, and there's an implicit assumption that it's not 
>>>>>>>> >> nil. 
>>>>>>>> >> And there's a matching syntactic sugar for converting `Type` to a 
>>>>>>>> >> `*Type`. 
>>>>>>>> >> 
>>>>>>>> >> So, In the code: 
>>>>>>>> >> 
>>>>>>>> >>     func (Type) String() string {...} 
>>>>>>>> >> 
>>>>>>>> >>     v *Type = nil 
>>>>>>>> >>     r interface{} = v 
>>>>>>>> >>     _, ok = r.(Stringer) 
>>>>>>>> >> 
>>>>>>>> >> What I really want to ask is "Can I, at runtime, call r.String()?", 
>>>>>>>> >> whereas the question Go answers is "Is any of `r`, `*r`, or `&r` 
>>>>>>>> >> defines .String()?" - which matches the static semantics of 
>>>>>>>> >> `r.String()`. 
>>>>>>>> >> 
>>>>>>>> >> So, while I should probably not use *Type as a replacement for 
>>>>>>>> >> Optional<Type>, I think it might make sense to have some operator 
>>>>>>>> >> that can determine, at run-time, if a call `r.String()` is valid 
>>>>>>>> >> (including a nil-check). 
>>>>>>>> >> 
>>>>>>>> >> 
>>>>>>>> >> -- Aviv 
>>>>>>>> >> 
>>>>>>>> >> On Saturday, April 11, 2020 at 4:48:28 PM UTC+3 
>>>>>>>> >> ren...@ix.netcom.com wrote: 
>>>>>>>> >>> 
>>>>>>>> >>> I agree with the OP. The usefulness of nil interfaces is pretty 
>>>>>>>> >>> limited. Show me a useful case that cant easily be implemented 
>>>>>>>> >>> with non-nil interfaces. 
>>>>>>>> >>> 
>>>>>>>> >>> I would argue that allowing nil interfaces causes more subtle 
>>>>>>>> >>> latent bugs and makes it harder to reason about the correctness of 
>>>>>>>> >>> code when reviewing it. 
>>>>>>>> >>> 
>>>>>>>> >>> It just feels wrong. I realize I’m probably in the minority here 
>>>>>>>> >>> but the OP is not alone. 
>>>>>>>> >>> 
>>>>>>>> >>> On Apr 11, 2020, at 8:20 AM, 'Axel Wagner' via golang-nuts 
>>>>>>>> >>> <golan...@googlegroups.com> wrote: 
>>>>>>>> >>> 
>>>>>>>> >>> On Fri, Apr 10, 2020 at 7:17 PM <cpu...@gmail.com> wrote: 
>>>>>>>> >>>> 
>>>>>>>> >>>> I realize I'm reviving an age-old discussion here and apologize 
>>>>>>>> >>>> for bringing up the undead. I happend to run into this when my 
>>>>>>>> >>>> application panicked when some interfaces where initialized with 
>>>>>>>> >>>> nil mock objects instead of being left uninitialized as in 
>>>>>>>> >>>> production mode. 
>>>>>>>> >>> 
>>>>>>>> >>> 
>>>>>>>> >>> Let's imagine a world in which `foo == nil` also is true if `foo` 
>>>>>>>> >>> is an interface-value containing a nil-pointer. Let's say in this 
>>>>>>>> >>> world, someone sends a message to golang-nuts. They wrote a mock 
>>>>>>>> >>> for the same code. And since it's just a mock, they just returned 
>>>>>>>> >>> static value from its methods and didn't need to care if the 
>>>>>>>> >>> pointer was nil or not. They are confused, because the passed in 
>>>>>>>> >>> this mock, but the code just assumed the field was uninitialized 
>>>>>>>> >>> and never called into their mock. What would you tell them? Why is 
>>>>>>>> >>> their confusion less valid? 
>>>>>>>> >>> 
>>>>>>>> >>>> This would be an example where a nil implementing fooer is never 
>>>>>>>> >>>> caught: 
>>>>>>>> >>>> 
>>>>>>>> >>>> type fooer interface { 
>>>>>>>> >>>>  foo() 
>>>>>>>> >>>> } 
>>>>>>>> >>>> 
>>>>>>>> >>>> type other struct{} 
>>>>>>>> >>>> 
>>>>>>>> >>>> func (o *other) foo() {} // implement fooer 
>>>>>>>> >>>> 
>>>>>>>> >>>> func main() { 
>>>>>>>> >>>>  var f fooer 
>>>>>>>> >>>> 
>>>>>>>> >>>>  var p *other // nil 
>>>>>>>> >>>>  f = p // it is a fooer so I can assign it 
>>>>>>>> >>>> 
>>>>>>>> >>>>  if f == nil { 
>>>>>>>> >>>>     // will not get here 
>>>>>>>> >>>>  } 
>>>>>>>> >>>> } 
>>>>>>>> >>>> 
>>>>>>>> >>>> 
>>>>>>>> >>>> My confusion comes from the point that the nil interface is 
>>>>>>>> >>>> apparently not "a nil-pointer with the correct method set" while 
>>>>>>>> >>>> *other is even if nil. 
>>>>>>>> >>> 
>>>>>>>> >>> 
>>>>>>>> >>> In the code you posted, even a nil *other is a perfectly fine 
>>>>>>>> >>> implementation of fooer. You can call `(*other)(nil).foo()` 
>>>>>>>> >>> without any problems. 
>>>>>>>> >>> So, as you illustrated, calling methods on a nil-pointer can be 
>>>>>>>> >>> totally fine. A nil-interface, OTOH, doesn't have any methods to 
>>>>>>>> >>> call, as it doesn't contain a dynamic value. If you write 
>>>>>>>> >>> `(*other)(nil).foo()`, it is completely clear what code gets 
>>>>>>>> >>> called - even if that code *might* panic. If you write 
>>>>>>>> >>> `fooer(nil).foo()`, what code should be called in your opinion? 
>>>>>>>> >>> 
>>>>>>>> >>> I think it's easy to see that a nil-interface and a nil-pointer 
>>>>>>>> >>> stored in an interface are very different things. Even from first 
>>>>>>>> >>> principles, without deep knowledge of the language. And if they 
>>>>>>>> >>> are obviously different, I don't understand why you'd find it 
>>>>>>>> >>> confusing that they are not the same in this particular manner. 
>>>>>>>> >>> 
>>>>>>>> >>>> The above is a case where that might happen. In can be worked 
>>>>>>>> >>>> around but it is unexpected unless the programmer is deeply 
>>>>>>>> >>>> rooted in the language definition.
>>>>>>>> >>> 
>>>>>>>> >>> 
>>>>>>>> >>> I fully agree with that. What I *don't* agree with, is where you 
>>>>>>>> >>> attribute the problem here. You say, the problem is that the 
>>>>>>>> >>> nil-check is ill-behaved. I say that - if anything - the original 
>>>>>>>> >>> nil-assignment is ill-behaved. Having `(fooer)((*other)(nil)) == 
>>>>>>>> >>> nil` be true is semantically wrong, because by checking against 
>>>>>>>> >>> `nil`, you are checking if you have a correct implementation - and 
>>>>>>>> >>> you might well have a correct implementation, even if it's using a 
>>>>>>>> >>> nil-pointer. 
>>>>>>>> >>> 
>>>>>>>> >>> Note, that the contained pointer being nil isn't the *only* case 
>>>>>>>> >>> in which calling the method might panic. For example, what about 
>>>>>>>> >>> this code? 
>>>>>>>> >>> https://play.golang.org/p/lNq0qphez7v
>>>>>>>> >>> Shouldn't the `nil`-check also catch that? After all, calling the 
>>>>>>>> >>> method panics, so it's clearly not a valid implementation - even 
>>>>>>>> >>> if x itself is not nil. Why is a nil-pointer more special than any 
>>>>>>>> >>> other value that causes a method to panic? 
>>>>>>>> >>> 
>>>>>>>> >>>> Seems as of today that there is no tooling to support that check. 
>>>>>>>> >>>> Maybe it's not a widespread issue. 
>>>>>>>> >>> 
>>>>>>>> >>> 
>>>>>>>> >>> As of today, the language also isn't changed :) Maybe someone who 
>>>>>>>> >>> think this is important enough to change the language, could also 
>>>>>>>> >>> feel it's important enough to write this tooling. 
>>>>>>>> >>> 
>>>>>>>> >>>> 
>>>>>>>> >>>> -- 
>>>>>>>> >>>> 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/e0dbcd38-510e-43b9-b363-2af1c636250b%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/CAEkBMfEPjcsZ3enqXyt%2BUphFJ1cNQ81cFCcjfwwkQZKHMrjSzA%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 golan...@googlegroups.com. 
>>>>>>> 
>>>>>>>> > To view this discussion on the web visit 
>>>>>>>> > https://groups.google.com/d/msgid/golang-nuts/c1ed2e38-6215-4ed2-8357-f8b5d83bf1a7n%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/84244528-84e6-4c2e-89bf-7fbf0590e132n%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/46d92421-a3a8-4b8a-b557-aa14d79e55b6n%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+unsubscr...@googlegroups.com.
>> To view this discussion on the web visit 
>> https://groups.google.com/d/msgid/golang-nuts/31df134b-7e55-4f32-9e1f-6d974817891en%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+unsubscr...@googlegroups.com.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/golang-nuts/CAEkBMfGhDrbJRMr%3DtxPu_XNDTzyT7PV61Oo7kOLP5QBqg-Zaiw%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/4D84B334-7AF7-4733-BE31-9EEBC40BBBD1%40ix.netcom.com.

Reply via email to