> 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.
it would definitely. Though price for consistency looks very much 
acceptable.

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

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+unsubscr...@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.

Reply via email to