> I'm mostly form C++ land 
from of course :)

On Thursday, August 27, 2020 at 2:01:33 PM UTC+3 targe...@gmail.com wrote:

> I know this. I'm mostly form C++ land, so you may imagine how many warts 
> are there "on the top of the index finger" :)
> I'm merely speaking against opinion that Shroedingerface is not a problem 
> at all.
> On Thursday, August 27, 2020 at 1:55:54 PM UTC+3 ren...@ix.netcom.com 
> wrote:
>
>> 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 <
>> golan...@googlegroups.com> wrote:
>>
>> 
>>
>>
>> On Thu, Aug 27, 2020 at 11:39 AM targe...@gmail.com <targe...@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
>>>>>>>  
>>>>>>> <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...@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
>>>  
>>> <https://groups.google.com/d/msgid/golang-nuts/31df134b-7e55-4f32-9e1f-6d974817891en%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/CAEkBMfGhDrbJRMr%3DtxPu_XNDTzyT7PV61Oo7kOLP5QBqg-Zaiw%40mail.gmail.com
>>  
>> <https://groups.google.com/d/msgid/golang-nuts/CAEkBMfGhDrbJRMr%3DtxPu_XNDTzyT7PV61Oo7kOLP5QBqg-Zaiw%40mail.gmail.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/f3081a9b-bf99-41f9-81e6-62147cbb6a12n%40googlegroups.com.

Reply via email to