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