“Tip” of course :)

> On Aug 27, 2020, at 6:03 AM, targe...@gmail.com <target....@gmail.com> wrote:
> 
> 
> > 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.
>>>>>>> 
>>>>>>> -- 
>>>>>>> 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...@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...@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/f3081a9b-bf99-41f9-81e6-62147cbb6a12n%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/5FCBE3B9-A632-419C-8FA2-5EEBE08D06CF%40ix.netcom.com.

Reply via email to