> 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. 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.

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
>>>>  
>>>> <https://groups.google.com/d/msgid/golang-nuts/84244528-84e6-4c2e-89bf-7fbf0590e132n%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...@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
>>  
>> <https://groups.google.com/d/msgid/golang-nuts/46d92421-a3a8-4b8a-b557-aa14d79e55b6n%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/31df134b-7e55-4f32-9e1f-6d974817891en%40googlegroups.com.

Reply via email to