Re: [go-nuts] Re: How to know if interface{} data is nil w/o reflecting?

2020-09-02 Thread Ian Lance Taylor
On Wed, Sep 2, 2020 at 3:45 AM targe...@gmail.com  wrote:
>
> > Other people have said this too, but I want to emphasize that there
> are not 4 potential states of an interface value. There are 2
> potential states: 1) interface does not hold any value, and is == nil;
> 2) interface holds a value, and is != nil.
>
> Indeed, there are 2 states of interface observable from outside. Although one 
> of these observable states gets expressed through 2 states invisible to outer 
> world. Which isn't a problem on its own.
>
> > When you start talking about an interface as a fat pointer you are
> talking about how those 2 states are implemented. There are other
> possible implementations
>
> Yes. And that's not an issue on its own. The issue is, such implementation 
> detail kind of "leaks" sometimes and bites you when you don't expect. And it 
> does so because the way it gets constructed omits one specific detail of 
> conversion from pointer to interface.

I don't think that is correct.  The implementation detail never leaks.
An interface always either holds a valid value (is != nil) or does not
hold a valid value (is == nil).

I believe the confusion is due to the overloading of "nil".  It means
both an invalid interface and an invalid pointer, but you are
permitted to store an invalid pointer in a valid interface.

Ian

-- 
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/CAOyqgcVG%2BY8d9gtnR7%3DGmdN5eiPQ1ZGP3XoWYCjW2b%3Dbkj1z6w%40mail.gmail.com.


Re: [go-nuts] Re: How to know if interface{} data is nil w/o reflecting?

2020-09-02 Thread 'Axel Wagner' via golang-nuts
The clarifying question first:

What would be the meaning of "none" interface?
>

A `none` interface would be the zero value of an interface - an interface
value with no dynamic type/value.

It doesn't solve issue at hand. The issue is, conversion from typed nil
> pointer to interface results in non-nil interface with valid vtable pointer
> and nil receiver.
>

I don't think this is the core of the problem.

Above, one case mentioned where this happens was refactoring a return type
(or really any variable) from a pointer to an interface. This changes the
semantic of `v == nil` from "is the value of v a nil-pointer" to "does v
have a dynamic value (even a nil-pointer)", leading to silent bugs. That
problem would be solved, because the compiler would now complain about `v
== nil` if v is an interface, prompting you to change it to `v == none` -
i.e. the bug would no longer be silent.

Another frequent occurrence is people *intending* to check if an interface
contains a nil-pointer and then getting confused because they instead check
if the interface has a dynamic value. Again, this confusion would be solved
- it is now clear that you can't compare an interface to nil, so you have
to use reflection to make that determination.

And only limited set of specifically crafted implementations supports nil
> receiver.
>

I would argue (without any data) that it is roughly as common for a method
to not dereference a pointer-receiver, as it is sensible to check if the
dynamic value of an interface is a nil-pointer. Generally, either

1. You know nothing about an interface-value whatsoever. You accept any
e.g. io.Reader. In that case, introspecting the dynamic value of the
interfaces makes no sense - it might not even *be* a pointer and even if it
is, you have no idea whether the implementation is fine with a nil-pointer
or not.
2. You know nothing about an interface-value, but need to know its shape
and kind and maybe have to store something in there (so need a non-nil
pointer). The `json` and `fmt` package are common examples. In this case,
you need to use reflect anyway.
3. You know something about an interface-value. There's some set of
supported dynamic types (e.g. ast.Node) which you know. In that case, you
can add an (unexported) method to the interface to check for validity
(which is even better, as it also works with non-pointers that need
initialization) or use `reflect`.

I just can't think of many places where "checking if the dynamic value of
an interface is a nil-pointer" is necessary or even useful, that don't need
to use reflect anyway.

If you can't accidentally do it and if you can't get confused as to why "my
non-nil interface contains nil", then at least it becomes obvious that you
are using the wrong approach.


> If it's nil data pointer, it would result in false-negatives for
> implementations which support nil receiver.
>
> On Thursday, August 27, 2020 at 3:13:14 PM UTC+3 axel.wa...@googlemail.com
> wrote:
>
>> On Thu, Aug 27, 2020 at 12:53 PM targe...@gmail.com 
>> wrote:
>>
>>> Because you then must remember about this specific case *every time *you
>>> cast potentially nil pointer variable to interface. Every time you must
>>> write `if x != nil { return x; } else { return nil; }` instead of just
>>> `return x;`
>>>
>>
>> This is true, but that alone is not indicative of a problem. You have to
>> remember that `select` does a pseudo-random selection of cases everytime
>> you use it, that you can't write to nil-maps, that dereferencing a
>> nil-pointer might panic, that an index-expression might panic, that
>> integer-addition might overflow, that floating-point math has
>> counter-intuitive edge-cases, that init-functions run before main… you have
>> to remember a *lot* of things every time you need them.
>>
>> I don't want to sound dismissive (as I said, I do think there is
>> obviously *some* problem) but I don't run into cases where I would even be
>> *tempted* to do this. Like, in your example, you'd need to a) have a
>> declared pointer, b) would need to be oblivious to the fact on whether or
>> not it's nil and c) it would have to be an invalid value if so and d) it
>> would have to be a problem not caught by other means (e.g. returning a
>> non-nil error alongside it). And when I am tempted to do this, I just know
>> that the interface value will still be non-nil. And even when I don't, the
>> most trivial of testing catches the problem.
>>
>> Like, I'm not saying it *never* happens or even that it never happens *to
>> me*. But it seems very rarely cause significant problems and I don't
>> understand why people put it so high up their list of being confusing or
>> hard to remember.
>>
>>
>>
>>> > But solutions that try to give special treatment to nil-values when
>>> they are put into interfaces just seem wrong to me.
>>>
>>> Because nils or null pointers are indeed special. They mean "Points to
>>> no data". So dereference operation on such pointer leads to exceptional
>>> state. In 

Re: [go-nuts] Re: How to know if interface{} data is nil w/o reflecting?

2020-09-02 Thread targe...@gmail.com
> I gave you a third solution: Having a separate identifier for the zero 
value of interfaces. 

It doesn't solve issue at hand. The issue is, conversion from typed nil 
pointer to interface results in non-nil interface with valid vtable pointer 
and nil receiver. And only limited set of specifically crafted 
implementations supports nil receiver. What would be the meaning of "none" 
interface? If it's nil data pointer, it would result in false-negatives for 
implementations which support nil receiver.

On Thursday, August 27, 2020 at 3:13:14 PM UTC+3 axel.wa...@googlemail.com 
wrote:

> On Thu, Aug 27, 2020 at 12:53 PM targe...@gmail.com  
> wrote:
>
>> Because you then must remember about this specific case *every time *you 
>> cast potentially nil pointer variable to interface. Every time you must 
>> write `if x != nil { return x; } else { return nil; }` instead of just 
>> `return x;`
>>
>
> This is true, but that alone is not indicative of a problem. You have to 
> remember that `select` does a pseudo-random selection of cases everytime 
> you use it, that you can't write to nil-maps, that dereferencing a 
> nil-pointer might panic, that an index-expression might panic, that 
> integer-addition might overflow, that floating-point math has 
> counter-intuitive edge-cases, that init-functions run before main… you have 
> to remember a *lot* of things every time you need them.
>
> I don't want to sound dismissive (as I said, I do think there is obviously 
> *some* problem) but I don't run into cases where I would even be *tempted* 
> to do this. Like, in your example, you'd need to a) have a declared 
> pointer, b) would need to be oblivious to the fact on whether or not it's 
> nil and c) it would have to be an invalid value if so and d) it would have 
> to be a problem not caught by other means (e.g. returning a non-nil error 
> alongside it). And when I am tempted to do this, I just know that the 
> interface value will still be non-nil. And even when I don't, the most 
> trivial of testing catches the problem.
>
> Like, I'm not saying it *never* happens or even that it never happens *to 
> me*. But it seems very rarely cause significant problems and I don't 
> understand why people put it so high up their list of being confusing or 
> hard to remember.
>
>  
>
>> > But solutions that try to give special treatment to nil-values when 
>> they are put into interfaces just seem wrong to me. 
>>
>> Because nils or null pointers are indeed special. They mean "Points to no 
>> data". So dereference operation on such pointer leads to exceptional state. 
>> In fact, nullable pointer in terms of richer type systems is a sum-type 
>> `nil|*T` where `*T` always points to some valid object
>>
>
> Okay. But even in those languages, `nil` (or `None` or `Nothing` or 
> whatever you call it is still a perfectly acceptable value, with 
> significant semantic meaning. Yes, in those languages the compiler is able 
> to prevent you from dereferencing it, but the value is still just a value 
> like any other. If anything, the fact that even languages with very rich 
> type-systems include types like `Maybe` shows how important `nil` as a 
> possible value is. Otherwise you wouldn't have to put it in artificially.
>
> > 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.
>>
>> Please don't forget that interface pointer isn't simple. It's a so-called 
>> "fat pointer" which consists of pointer to data and pointer to methods 
>> table. Thus, we have 4 potential states
>>
>
> That's one way to look at it. And you are trying to make that way look 
> pretty complicated. But you are talking about implementation details. It's 
> like arguing strings are very complicated, because they can a) be 
> string-constants held in read-only memory, b) be heap-allocated or c) be 
> stack-allocated.
>
> Another way to look at it is that an interface is a type, that may or may 
> not contain a dynamic value of some other type and allows calling methods 
> on it. If it doesn't, the interface-value is nil. If it does, it isn't. 
> That's the way interfaces are defined in the spec.
>
> I am still against teaching interfaces to newcomers as "two pointers, one 
> to a type and one to a value". It leads to exactly the kinds of 
> confusion you are expressing here, because people think about the 
> representation and want to operate on that, instead of thinking about the 
> semantics. It is completely unnecessary and often counterproductive to 
> think of interfaces that way.
>  
>
>> Why is this an issue? Because most interface implementations require 
>> valid data pointer. "Static" (i.e. not needing data) implementations can be 
>> considered corner case.
>

Re: [go-nuts] Re: How to know if interface{} data is nil w/o reflecting?

2020-09-02 Thread targe...@gmail.com
> Other people have said this too, but I want to emphasize that there 
are not 4 potential states of an interface value. There are 2 
potential states: 1) interface does not hold any value, and is == nil; 
2) interface holds a value, and is != nil. 

Indeed, there are 2 states of interface observable from outside. Although 
one of these observable states gets expressed through 2 states invisible to 
outer world. Which isn't a problem on its own.

> When you start talking about an interface as a fat pointer you are 
talking about how those 2 states are implemented. There are other 
possible implementations 

Yes. And that's not an issue on its own. The issue is, such implementation 
detail kind of "leaks" sometimes and bites you when you don't expect. And 
it does so because the way it gets constructed omits one specific detail of 
conversion from pointer to interface.

On Thursday, August 27, 2020 at 9:58:21 PM UTC+3 Ian Lance Taylor wrote:

> On Thu, Aug 27, 2020 at 3:53 AM targe...@gmail.com  
> wrote:
> >
> > Please don't forget that interface pointer isn't simple. It's a 
> so-called "fat pointer" which consists of pointer to data and pointer to 
> methods table. Thus, we have 4 potential states - (nil, nil), (nil, 
> pointer), (pointer, nil) and (pointer,pointer). First one is just ordinary 
> nil interface. Last one is just ordinary interface pointer with all 
> operations callable without issue (as long as they're properly implemented, 
> of course). Third one with valid data pointer and nil table pointer can be 
> AFAIK created only through reflection and is safely considered "invalid 
> state". We're left with second state with nil data pointer and valid table 
> pointer, making interface methods callable on it. It wouldn't be a problem 
> - if such state couldn't be created by merely casting typed nil pointer 
> (typed pointer variable with nil value) to interface. Why is this an issue? 
> Because most interface implementations require valid data pointer. "Static" 
> (i.e. not needing data) implementations can be considered corner case.
>
> Other people have said this too, but I want to emphasize that there
> are not 4 potential states of an interface value. There are 2
> potential states: 1) interface does not hold any value, and is == nil;
> 2) interface holds a value, and is != nil.
>
> When you start talking about an interface as a fat pointer you are
> talking about how those 2 states are implemented. There are other
> possible implementations, and in fact the implementation in gccgo used
> to be different. And even the implementation in the gc compiler has
> changed; at one time ints and other small values were stored directly
> in the interface value, but now we instead store a pointer to the
> data.
>
> Ian
>

-- 
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/5de71d2c-958b-47e5-8bd2-4e54b3d14150n%40googlegroups.com.


Re: [go-nuts] Re: How to know if interface{} data is nil w/o reflecting?

2020-08-27 Thread Robert Engels
Maybe I misunderstood this 
> 
> The first is the old adage: "Accept interfaces return concrete types." 

No interface based design would have you declare a concrete type as the return 
value - so it must be declaring a interface return and returning a concrete. 

Which is what was being argued against. 


> On Aug 27, 2020, at 1:36 PM, burak serdar  wrote:
> 
> On Thu, Aug 27, 2020 at 12:27 PM Robert Engels  wrote:
>> 
>> I think you just made the case... if you have existing code that declares a 
>> concrete return type and you change that to an interface and nothing else 
>> you are going to have problems.
> 
> I don't think anybody said "..change it to interface and nothing
> else". The problem is, even if you change it to include a nil-check it
> is still wrong. I agree that you should not do that. There is the
> "vet" tool that tells you about things you shouldn't do, and I think
> it would be useful if it warned against that.
> 
> 
>> 
>> On Aug 27, 2020, at 12:11 PM, Jake Montgomery  wrote:
>> 
>> 
>> 
>> 
>>> On Thursday, August 27, 2020 at 10:45:52 AM UTC-4, burak serdar wrote:
>>> 
>>> On Thu, Aug 27, 2020 at 6:12 AM 'Axel Wagner' via golang-nuts
>>>  wrote:
 
 On Thu, Aug 27, 2020 at 12:53 PM targe...@gmail.com  
 wrote:
> 
> Because you then must remember about this specific case every time you 
> cast potentially nil pointer variable to interface. Every time you must 
> write `if x != nil { return x; } else { return nil; }` instead of just 
> `return x;`
 
 
 This is true, but that alone is not indicative of a problem. You have to 
 remember that `select` does a pseudo-random selection of cases everytime 
 you use it, that you can't write to nil-maps, that dereferencing a 
 nil-pointer might panic, that an index-expression might panic, that 
 integer-addition might overflow, that floating-point math has 
 counter-intuitive edge-cases, that init-functions run before main… you 
 have to remember a *lot* of things every time you need them.
 
 I don't want to sound dismissive (as I said, I do think there is obviously 
 *some* problem) but I don't run into cases where I would even be *tempted* 
 to do this. Like, in your example, you'd need to a) have a declared 
 pointer, b) would need to be oblivious to the fact on whether or not it's 
 nil and c) it would have to be an invalid value if so and d) it would have 
 to be a problem not caught by other means (e.g. returning a non-nil error 
 alongside it). And when I am tempted to do this, I just know that the 
 interface value will still be non-nil. And even when I don't, the most 
 trivial of testing catches the problem.
 
 Like, I'm not saying it *never* happens or even that it never happens *to 
 me*. But it seems very rarely cause significant problems and I don't 
 understand why people put it so high up their list of being confusing or 
 hard to remember.
>>> 
>>> I saw this happen mostly after refactoring code to replace structs
>>> with interfaces. Functions start returning interfaces instead of
>>> concrete types, and there is no obvious indication in the code that
>>> might alert the potential problem.
>> 
>> 
>> Like Burak, once I was no longer a noob, this has rarely bitten me. In fact, 
>> I literally can't remember it being a problem since I became proficient in 
>> Go. It probably has, but not enough to stick with me. I also almost never 
>> find myself using the `if x != nil { return x; } else { return nil; }` 
>> pattern, so it is not a burden for me.
>> 
>> I'm not going to argue whether Go got it right, or not, since a change at 
>> this point is exceedingly unlikely. But, on a pragmatic level, two thing 
>> struck me about your response.
>> 
>> The first is the old adage: "Accept interfaces return concrete types." There 
>> are many good reasons for violating this rule, but I hope all this 
>> refactoring that involved changing functions that had concrete types, but 
>> choose to return them as interfaces really thought about the justification 
>> for breaking the advice.
>> 
>> The second is that refactoring is always tricky and requires attention to 
>> detail. A struct and interface are not the same thing, so this is not 
>> zero-change transformation by definition. It seems like you should be very 
>> aware that you are changing a function from returning a struct to returning 
>> an interface, at the time. Maybe the first time this would bite you, but 
>> after that it seems like it would become wrote to know that such a change 
>> requires a tiny bit of extra thought.
>> 
>> Admittedly these are not firm technical arguments ... just my experience and 
>> opinion.
>> 
>> 
>> 
>> --
>> 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 

Re: [go-nuts] Re: How to know if interface{} data is nil w/o reflecting?

2020-08-27 Thread Ian Lance Taylor
On Thu, Aug 27, 2020 at 3:53 AM targe...@gmail.com  wrote:
>
> Please don't forget that interface pointer isn't simple. It's a so-called 
> "fat pointer" which consists of pointer to data and pointer to methods table. 
> Thus, we have 4 potential states - (nil, nil), (nil, pointer), (pointer, nil) 
> and (pointer,pointer). First one is just ordinary nil interface. Last one is 
> just ordinary interface pointer with all operations callable without issue 
> (as long as they're properly implemented, of course). Third one with valid 
> data pointer and nil table pointer can be AFAIK created only through 
> reflection and is safely considered "invalid state". We're left with second 
> state with nil data pointer and valid table pointer, making interface methods 
> callable on it. It wouldn't be a problem - if such state couldn't be created 
> by merely casting typed nil pointer (typed pointer variable with nil value) 
> to interface. Why is this an issue? Because most interface implementations 
> require valid data pointer. "Static" (i.e. not needing data) implementations 
> can be considered corner case.

Other people have said this too, but I want to emphasize that there
are not 4 potential states of an interface value.  There are 2
potential states: 1) interface does not hold any value, and is == nil;
2) interface holds a value, and is != nil.

When you start talking about an interface as a fat pointer you are
talking about how those 2 states are implemented.  There are other
possible implementations, and in fact the implementation in gccgo used
to be different.  And even the implementation in the gc compiler has
changed; at one time ints and other small values were stored directly
in the interface value, but now we instead store a pointer to the
data.

Ian

-- 
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/CAOyqgcWGy7nGqxbR9Gicf0owUB_eJWre0fTDzuUcX1yFNOO69A%40mail.gmail.com.


Re: [go-nuts] Re: How to know if interface{} data is nil w/o reflecting?

2020-08-27 Thread burak serdar
On Thu, Aug 27, 2020 at 12:27 PM Robert Engels  wrote:
>
> I think you just made the case... if you have existing code that declares a 
> concrete return type and you change that to an interface and nothing else you 
> are going to have problems.

I don't think anybody said "..change it to interface and nothing
else". The problem is, even if you change it to include a nil-check it
is still wrong. I agree that you should not do that. There is the
"vet" tool that tells you about things you shouldn't do, and I think
it would be useful if it warned against that.


>
> On Aug 27, 2020, at 12:11 PM, Jake Montgomery  wrote:
>
> 
>
>
> On Thursday, August 27, 2020 at 10:45:52 AM UTC-4, burak serdar wrote:
>>
>> On Thu, Aug 27, 2020 at 6:12 AM 'Axel Wagner' via golang-nuts
>>  wrote:
>> >
>> > On Thu, Aug 27, 2020 at 12:53 PM targe...@gmail.com  
>> > wrote:
>> >>
>> >> Because you then must remember about this specific case every time you 
>> >> cast potentially nil pointer variable to interface. Every time you must 
>> >> write `if x != nil { return x; } else { return nil; }` instead of just 
>> >> `return x;`
>> >
>> >
>> > This is true, but that alone is not indicative of a problem. You have to 
>> > remember that `select` does a pseudo-random selection of cases everytime 
>> > you use it, that you can't write to nil-maps, that dereferencing a 
>> > nil-pointer might panic, that an index-expression might panic, that 
>> > integer-addition might overflow, that floating-point math has 
>> > counter-intuitive edge-cases, that init-functions run before main… you 
>> > have to remember a *lot* of things every time you need them.
>> >
>> > I don't want to sound dismissive (as I said, I do think there is obviously 
>> > *some* problem) but I don't run into cases where I would even be *tempted* 
>> > to do this. Like, in your example, you'd need to a) have a declared 
>> > pointer, b) would need to be oblivious to the fact on whether or not it's 
>> > nil and c) it would have to be an invalid value if so and d) it would have 
>> > to be a problem not caught by other means (e.g. returning a non-nil error 
>> > alongside it). And when I am tempted to do this, I just know that the 
>> > interface value will still be non-nil. And even when I don't, the most 
>> > trivial of testing catches the problem.
>> >
>> > Like, I'm not saying it *never* happens or even that it never happens *to 
>> > me*. But it seems very rarely cause significant problems and I don't 
>> > understand why people put it so high up their list of being confusing or 
>> > hard to remember.
>>
>> I saw this happen mostly after refactoring code to replace structs
>> with interfaces. Functions start returning interfaces instead of
>> concrete types, and there is no obvious indication in the code that
>> might alert the potential problem.
>
>
> Like Burak, once I was no longer a noob, this has rarely bitten me. In fact, 
> I literally can't remember it being a problem since I became proficient in 
> Go. It probably has, but not enough to stick with me. I also almost never 
> find myself using the `if x != nil { return x; } else { return nil; }` 
> pattern, so it is not a burden for me.
>
> I'm not going to argue whether Go got it right, or not, since a change at 
> this point is exceedingly unlikely. But, on a pragmatic level, two thing 
> struck me about your response.
>
> The first is the old adage: "Accept interfaces return concrete types." There 
> are many good reasons for violating this rule, but I hope all this 
> refactoring that involved changing functions that had concrete types, but 
> choose to return them as interfaces really thought about the justification 
> for breaking the advice.
>
> The second is that refactoring is always tricky and requires attention to 
> detail. A struct and interface are not the same thing, so this is not 
> zero-change transformation by definition. It seems like you should be very 
> aware that you are changing a function from returning a struct to returning 
> an interface, at the time. Maybe the first time this would bite you, but 
> after that it seems like it would become wrote to know that such a change 
> requires a tiny bit of extra thought.
>
> Admittedly these are not firm technical arguments ... just my experience and 
> opinion.
>
>
>
> --
> 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/99a93de9-5dbc-474a-b0c9-906a8ae2cbaeo%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 
> 

Re: [go-nuts] Re: How to know if interface{} data is nil w/o reflecting?

2020-08-27 Thread Robert Engels
I think you just made the case... if you have existing code that declares a 
concrete return type and you change that to an interface and nothing else you 
are going to have problems. 

> On Aug 27, 2020, at 12:11 PM, Jake Montgomery  wrote:
> 
> 
> 
> 
>> On Thursday, August 27, 2020 at 10:45:52 AM UTC-4, burak serdar wrote:
>> On Thu, Aug 27, 2020 at 6:12 AM 'Axel Wagner' via golang-nuts 
>>  wrote: 
>> > 
>> > On Thu, Aug 27, 2020 at 12:53 PM targe...@gmail.com  
>> > wrote: 
>> >> 
>> >> Because you then must remember about this specific case every time you 
>> >> cast potentially nil pointer variable to interface. Every time you must 
>> >> write `if x != nil { return x; } else { return nil; }` instead of just 
>> >> `return x;` 
>> > 
>> > 
>> > This is true, but that alone is not indicative of a problem. You have to 
>> > remember that `select` does a pseudo-random selection of cases everytime 
>> > you use it, that you can't write to nil-maps, that dereferencing a 
>> > nil-pointer might panic, that an index-expression might panic, that 
>> > integer-addition might overflow, that floating-point math has 
>> > counter-intuitive edge-cases, that init-functions run before main… you 
>> > have to remember a *lot* of things every time you need them. 
>> > 
>> > I don't want to sound dismissive (as I said, I do think there is obviously 
>> > *some* problem) but I don't run into cases where I would even be *tempted* 
>> > to do this. Like, in your example, you'd need to a) have a declared 
>> > pointer, b) would need to be oblivious to the fact on whether or not it's 
>> > nil and c) it would have to be an invalid value if so and d) it would have 
>> > to be a problem not caught by other means (e.g. returning a non-nil error 
>> > alongside it). And when I am tempted to do this, I just know that the 
>> > interface value will still be non-nil. And even when I don't, the most 
>> > trivial of testing catches the problem. 
>> > 
>> > Like, I'm not saying it *never* happens or even that it never happens *to 
>> > me*. But it seems very rarely cause significant problems and I don't 
>> > understand why people put it so high up their list of being confusing or 
>> > hard to remember. 
>> 
>> I saw this happen mostly after refactoring code to replace structs 
>> with interfaces. Functions start returning interfaces instead of 
>> concrete types, and there is no obvious indication in the code that 
>> might alert the potential problem.
> 
> Like Burak, once I was no longer a noob, this has rarely bitten me. In fact, 
> I literally can't remember it being a problem since I became proficient in 
> Go. It probably has, but not enough to stick with me. I also almost never 
> find myself using the `if x != nil { return x; } else { return nil; }` 
> pattern, so it is not a burden for me.
> 
> I'm not going to argue whether Go got it right, or not, since a change at 
> this point is exceedingly unlikely. But, on a pragmatic level, two thing 
> struck me about your response. 
> 
> The first is the old adage: "Accept interfaces return concrete types." There 
> are many good reasons for violating this rule, but I hope all this 
> refactoring that involved changing functions that had concrete types, but 
> choose to return them as interfaces really thought about the justification 
> for breaking the advice. 
> 
> The second is that refactoring is always tricky and requires attention to 
> detail. A struct and interface are not the same thing, so this is not 
> zero-change transformation by definition. It seems like you should be very 
> aware that you are changing a function from returning a struct to returning 
> an interface, at the time. Maybe the first time this would bite you, but 
> after that it seems like it would become wrote to know that such a change 
> requires a tiny bit of extra thought. 
> 
> Admittedly these are not firm technical arguments ... just my experience and 
> opinion. 
> 
>  
> 
> -- 
> 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/99a93de9-5dbc-474a-b0c9-906a8ae2cbaeo%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/EEC803AB-E5A9-4274-9CE6-6DB2A340F29B%40ix.netcom.com.


Re: [go-nuts] Re: How to know if interface{} data is nil w/o reflecting?

2020-08-27 Thread Jake Montgomery


On Thursday, August 27, 2020 at 10:45:52 AM UTC-4, burak serdar wrote:
>
> On Thu, Aug 27, 2020 at 6:12 AM 'Axel Wagner' via golang-nuts 
> > wrote: 
> > 
> > On Thu, Aug 27, 2020 at 12:53 PM targe...@gmail.com  > wrote: 
> >> 
> >> Because you then must remember about this specific case every time you 
> cast potentially nil pointer variable to interface. Every time you must 
> write `if x != nil { return x; } else { return nil; }` instead of just 
> `return x;` 
> > 
> > 
> > This is true, but that alone is not indicative of a problem. You have to 
> remember that `select` does a pseudo-random selection of cases everytime 
> you use it, that you can't write to nil-maps, that dereferencing a 
> nil-pointer might panic, that an index-expression might panic, that 
> integer-addition might overflow, that floating-point math has 
> counter-intuitive edge-cases, that init-functions run before main… you have 
> to remember a *lot* of things every time you need them. 
> > 
> > I don't want to sound dismissive (as I said, I do think there is 
> obviously *some* problem) but I don't run into cases where I would even be 
> *tempted* to do this. Like, in your example, you'd need to a) have a 
> declared pointer, b) would need to be oblivious to the fact on whether or 
> not it's nil and c) it would have to be an invalid value if so and d) it 
> would have to be a problem not caught by other means (e.g. returning a 
> non-nil error alongside it). And when I am tempted to do this, I just know 
> that the interface value will still be non-nil. And even when I don't, the 
> most trivial of testing catches the problem. 
> > 
> > Like, I'm not saying it *never* happens or even that it never happens 
> *to me*. But it seems very rarely cause significant problems and I don't 
> understand why people put it so high up their list of being confusing or 
> hard to remember. 
>
> I saw this happen mostly after refactoring code to replace structs 
> with interfaces. Functions start returning interfaces instead of 
> concrete types, and there is no obvious indication in the code that 
> might alert the potential problem.


Like Burak, once I was no longer a noob, this has rarely bitten me. In 
fact, I literally can't remember it being a problem since I became 
proficient in Go. It probably has, but not enough to stick with me. I also 
almost never find myself using the `if x != nil { return x; } else { return 
nil; }` pattern, so it is not a burden for me.

I'm not going to argue whether Go got it right, or not, since a change at 
this point is exceedingly unlikely. But, on a pragmatic level, two thing 
struck me about your response. 

The first is the old adage: "Accept interfaces return concrete types." 
There are many good reasons for violating this rule, but I hope all this 
refactoring that involved changing functions that had concrete types, but 
choose to return them as interfaces really thought about the justification 
for breaking the advice. 

The second is that refactoring is always tricky and requires attention to 
detail. A struct and interface are not the same thing, so this is not 
zero-change transformation by definition. It seems like you should be very 
aware that you are changing a function from returning a struct to returning 
an interface, at the time. Maybe the first time this would bite you, but 
after that it seems like it would become wrote to know that such a change 
requires a tiny bit of extra thought. 

Admittedly these are not firm technical arguments ... just my experience 
and opinion. 

 

-- 
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/99a93de9-5dbc-474a-b0c9-906a8ae2cbaeo%40googlegroups.com.


Re: [go-nuts] Re: How to know if interface{} data is nil w/o reflecting?

2020-08-27 Thread Marvin Renich
* targe...@gmail.com  [200827 05:40]:
> On Thursday, August 27, 2020 at 12:20:59 PM UTC+3 axel.wa...@googlemail.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. 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.

I agree with Axel.  The `y = x` operation is a conversion, not just an
assignment.  You cannot assume that the transitive property of equality
holds where conversions are used.  Note also that both y == nil and x ==
nil involve implicit conversion, because nil is the _untyped_ zero
value, so the value being compared to y is nil converted to the
interface type, and the value being compared to x is nil converted to
the concrete type; these are _different_ zero values.

I think there are two incorrect generalizations that lead to Go
programmers having the confusion being discussed.  The first is that nil
is the "universal" zero value, which leads to the false idea that nil
of one type is the same as nil of another type.  I think when a
programmer stops to think about this, they will get the correct answer,
but often this level of detail is not brought to a high enough level of
conciousness when actually writing code.  The correct thinking is that
nil is the _untyped_ (rather than universal) zero value.  Note that you
cannot even evaluate nil == nil!

The second is thinking of an interface value containing a concrete value
as being the same thing as the concrete value.  I'm not sure why this is
such a sticking point for some, but it clearly is.  It may be for some
that they think of interfaces as a "partial generic" language feature,
such that declaring a variable of an interface type is a way to directly
use any of the types that implement that interface.  This is the wrong
way to think of it, as the interface value cannot be used in Go code in
the same was as the concrete value, except in the very specific case
where you are invoking a method on the interface value that is defined
_by the interface_.  In particular, the interface value has its own,
distinct, zero value from the zero value of the contained concrete type.

Consider the code:

type Fooer interface {
Foo()
}

type X int

func (i X) Foo() {
}

func main() {
var i X
var f Fooer = i
fmt.Println(f == 0)
}

You would not (at least you should not) expect this to compile, much
less give you the "obvious"(?) answer.  Yet, when you change

type X int
func (i X) Foo() {
...
var i X
...
fmt.Println(f == 0)

  to

type X struct{}
func (i *X) Foo() {
...
var i *X
...
fmt.Println(f == nil)

you expect that the nil is being compared to the concrete value
contained by f rather than the value of f.

If you had to explicitly convert nil to the proper type before
comparison, the problem would be much more obvious.

If you think of an interface value as a container for a concrete value,
rather than the concrete value itself, then the interface value might be
empty (nil, no concrete value) or it might contain a concrete value (not
nil, but the concrete value might be its own zero value).

As Axel said, you just have to learn that interface_value == nil
determines whether interface_value has been assigned a concrete value,
not whether the concrete value is its own zero value (which might
coincide with nil converted to the concrete type).

...Marvin

-- 
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/20200827160217.mw7tg6ef224htgxe%40basil.wdw.


Re: [go-nuts] Re: How to know if interface{} data is nil w/o reflecting?

2020-08-27 Thread burak serdar
On Thu, Aug 27, 2020 at 6:12 AM 'Axel Wagner' via golang-nuts
 wrote:
>
> On Thu, Aug 27, 2020 at 12:53 PM targe...@gmail.com  
> wrote:
>>
>> Because you then must remember about this specific case every time you cast 
>> potentially nil pointer variable to interface. Every time you must write `if 
>> x != nil { return x; } else { return nil; }` instead of just `return x;`
>
>
> This is true, but that alone is not indicative of a problem. You have to 
> remember that `select` does a pseudo-random selection of cases everytime you 
> use it, that you can't write to nil-maps, that dereferencing a nil-pointer 
> might panic, that an index-expression might panic, that integer-addition 
> might overflow, that floating-point math has counter-intuitive edge-cases, 
> that init-functions run before main… you have to remember a *lot* of things 
> every time you need them.
>
> I don't want to sound dismissive (as I said, I do think there is obviously 
> *some* problem) but I don't run into cases where I would even be *tempted* to 
> do this. Like, in your example, you'd need to a) have a declared pointer, b) 
> would need to be oblivious to the fact on whether or not it's nil and c) it 
> would have to be an invalid value if so and d) it would have to be a problem 
> not caught by other means (e.g. returning a non-nil error alongside it). And 
> when I am tempted to do this, I just know that the interface value will still 
> be non-nil. And even when I don't, the most trivial of testing catches the 
> problem.
>
> Like, I'm not saying it *never* happens or even that it never happens *to 
> me*. But it seems very rarely cause significant problems and I don't 
> understand why people put it so high up their list of being confusing or hard 
> to remember.

I saw this happen mostly after refactoring code to replace structs
with interfaces. Functions start returning interfaces instead of
concrete types, and there is no obvious indication in the code that
might alert the potential problem. Even though this problem is usually
discussed in the context of returning errors, this happened to me
multiple times with types other than errors, and always after
refactoring. I agree that it rarely causes problems, but when it does,
it is hard to find because there is usually a nil-check and no obvious
reason to doubt that would fail.

A go vet addition that detects and warns against this might be more
useful than a language facility. I remember discussing this before and
the concern was false-positives, so a warning instead of an error
would be useful.

>
>
>>
>> > But solutions that try to give special treatment to nil-values when they 
>> > are put into interfaces just seem wrong to me.
>>
>> Because nils or null pointers are indeed special. They mean "Points to no 
>> data". So dereference operation on such pointer leads to exceptional state. 
>> In fact, nullable pointer in terms of richer type systems is a sum-type 
>> `nil|*T` where `*T` always points to some valid object
>
>
> Okay. But even in those languages, `nil` (or `None` or `Nothing` or whatever 
> you call it is still a perfectly acceptable value, with significant semantic 
> meaning. Yes, in those languages the compiler is able to prevent you from 
> dereferencing it, but the value is still just a value like any other. If 
> anything, the fact that even languages with very rich type-systems include 
> types like `Maybe` shows how important `nil` as a possible value is. 
> Otherwise you wouldn't have to put it in artificially.
>
>> > 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.
>>
>> Please don't forget that interface pointer isn't simple. It's a so-called 
>> "fat pointer" which consists of pointer to data and pointer to methods 
>> table. Thus, we have 4 potential states
>
>
> That's one way to look at it. And you are trying to make that way look pretty 
> complicated. But you are talking about implementation details. It's like 
> arguing strings are very complicated, because they can a) be string-constants 
> held in read-only memory, b) be heap-allocated or c) be stack-allocated.
>
> Another way to look at it is that an interface is a type, that may or may not 
> contain a dynamic value of some other type and allows calling methods on it. 
> If it doesn't, the interface-value is nil. If it does, it isn't. That's the 
> way interfaces are defined in the spec.
>
> I am still against teaching interfaces to newcomers as "two pointers, one to 
> a type and one to a value". It leads to exactly the kinds of confusion you 
> are expressing here, because people think about the representation and want 
> to operate on that, instead of thinking about the semantics. It is 

Re: [go-nuts] Re: How to know if interface{} data is nil w/o reflecting?

2020-08-27 Thread 'Axel Wagner' via golang-nuts
(whoops: "I don't run into cases […] very often")

On Thu, Aug 27, 2020 at 2:12 PM Axel Wagner 
wrote:

> On Thu, Aug 27, 2020 at 12:53 PM targe...@gmail.com 
> wrote:
>
>> Because you then must remember about this specific case *every time *you
>> cast potentially nil pointer variable to interface. Every time you must
>> write `if x != nil { return x; } else { return nil; }` instead of just
>> `return x;`
>>
>
> This is true, but that alone is not indicative of a problem. You have to
> remember that `select` does a pseudo-random selection of cases everytime
> you use it, that you can't write to nil-maps, that dereferencing a
> nil-pointer might panic, that an index-expression might panic, that
> integer-addition might overflow, that floating-point math has
> counter-intuitive edge-cases, that init-functions run before main… you have
> to remember a *lot* of things every time you need them.
>
> I don't want to sound dismissive (as I said, I do think there is obviously
> *some* problem) but I don't run into cases where I would even be *tempted*
> to do this. Like, in your example, you'd need to a) have a declared
> pointer, b) would need to be oblivious to the fact on whether or not it's
> nil and c) it would have to be an invalid value if so and d) it would have
> to be a problem not caught by other means (e.g. returning a non-nil error
> alongside it). And when I am tempted to do this, I just know that the
> interface value will still be non-nil. And even when I don't, the most
> trivial of testing catches the problem.
>
> Like, I'm not saying it *never* happens or even that it never happens *to
> me*. But it seems very rarely cause significant problems and I don't
> understand why people put it so high up their list of being confusing or
> hard to remember.
>
>
>
>> > But solutions that try to give special treatment to nil-values when
>> they are put into interfaces just seem wrong to me.
>>
>> Because nils or null pointers are indeed special. They mean "Points to no
>> data". So dereference operation on such pointer leads to exceptional state.
>> In fact, nullable pointer in terms of richer type systems is a sum-type
>> `nil|*T` where `*T` always points to some valid object
>>
>
> Okay. But even in those languages, `nil` (or `None` or `Nothing` or
> whatever you call it is still a perfectly acceptable value, with
> significant semantic meaning. Yes, in those languages the compiler is able
> to prevent you from dereferencing it, but the value is still just a value
> like any other. If anything, the fact that even languages with very rich
> type-systems include types like `Maybe` shows how important `nil` as a
> possible value is. Otherwise you wouldn't have to put it in artificially.
>
> > 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.
>>
>> Please don't forget that interface pointer isn't simple. It's a so-called
>> "fat pointer" which consists of pointer to data and pointer to methods
>> table. Thus, we have 4 potential states
>>
>
> That's one way to look at it. And you are trying to make that way look
> pretty complicated. But you are talking about implementation details. It's
> like arguing strings are very complicated, because they can a) be
> string-constants held in read-only memory, b) be heap-allocated or c) be
> stack-allocated.
>
> Another way to look at it is that an interface is a type, that may or may
> not contain a dynamic value of some other type and allows calling methods
> on it. If it doesn't, the interface-value is nil. If it does, it isn't.
> That's the way interfaces are defined in the spec.
>
> I am still against teaching interfaces to newcomers as "two pointers, one
> to a type and one to a value". It leads to exactly the kinds of
> confusion you are expressing here, because people think about the
> representation and want to operate on that, instead of thinking about the
> semantics. It is completely unnecessary and often counterproductive to
> think of interfaces that way.
>
>
>> Why is this an issue? Because most interface implementations require
>> valid data pointer. "Static" (i.e. not needing data) implementations can be
>> considered corner case.
>
>
> It's not about needing data or not needing data. It's about deriving
> meaning from the fact that there is none. As I said, this is clearly
> important and used regularly - otherwise languages wouldn't need to add a
> `Maybe` (or whatever) type to do it.
>
> More importantly, if a pointer-type can't act on nil-pointers, that's a
> problem *orthogonal* to whether you put it into an interface or not. If you
> return an invalid value, it doesn't become valid just because you call it a
> `*T` instead of an `io.Reader`. If being able to 

Re: [go-nuts] Re: How to know if interface{} data is nil w/o reflecting?

2020-08-27 Thread 'Axel Wagner' via golang-nuts
On Thu, Aug 27, 2020 at 12:53 PM targe...@gmail.com 
wrote:

> Because you then must remember about this specific case *every time *you
> cast potentially nil pointer variable to interface. Every time you must
> write `if x != nil { return x; } else { return nil; }` instead of just
> `return x;`
>

This is true, but that alone is not indicative of a problem. You have to
remember that `select` does a pseudo-random selection of cases everytime
you use it, that you can't write to nil-maps, that dereferencing a
nil-pointer might panic, that an index-expression might panic, that
integer-addition might overflow, that floating-point math has
counter-intuitive edge-cases, that init-functions run before main… you have
to remember a *lot* of things every time you need them.

I don't want to sound dismissive (as I said, I do think there is obviously
*some* problem) but I don't run into cases where I would even be *tempted*
to do this. Like, in your example, you'd need to a) have a declared
pointer, b) would need to be oblivious to the fact on whether or not it's
nil and c) it would have to be an invalid value if so and d) it would have
to be a problem not caught by other means (e.g. returning a non-nil error
alongside it). And when I am tempted to do this, I just know that the
interface value will still be non-nil. And even when I don't, the most
trivial of testing catches the problem.

Like, I'm not saying it *never* happens or even that it never happens *to
me*. But it seems very rarely cause significant problems and I don't
understand why people put it so high up their list of being confusing or
hard to remember.



> > But solutions that try to give special treatment to nil-values when they
> are put into interfaces just seem wrong to me.
>
> Because nils or null pointers are indeed special. They mean "Points to no
> data". So dereference operation on such pointer leads to exceptional state.
> In fact, nullable pointer in terms of richer type systems is a sum-type
> `nil|*T` where `*T` always points to some valid object
>

Okay. But even in those languages, `nil` (or `None` or `Nothing` or
whatever you call it is still a perfectly acceptable value, with
significant semantic meaning. Yes, in those languages the compiler is able
to prevent you from dereferencing it, but the value is still just a value
like any other. If anything, the fact that even languages with very rich
type-systems include types like `Maybe` shows how important `nil` as a
possible value is. Otherwise you wouldn't have to put it in artificially.

> 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.
>
> Please don't forget that interface pointer isn't simple. It's a so-called
> "fat pointer" which consists of pointer to data and pointer to methods
> table. Thus, we have 4 potential states
>

That's one way to look at it. And you are trying to make that way look
pretty complicated. But you are talking about implementation details. It's
like arguing strings are very complicated, because they can a) be
string-constants held in read-only memory, b) be heap-allocated or c) be
stack-allocated.

Another way to look at it is that an interface is a type, that may or may
not contain a dynamic value of some other type and allows calling methods
on it. If it doesn't, the interface-value is nil. If it does, it isn't.
That's the way interfaces are defined in the spec.

I am still against teaching interfaces to newcomers as "two pointers, one
to a type and one to a value". It leads to exactly the kinds of
confusion you are expressing here, because people think about the
representation and want to operate on that, instead of thinking about the
semantics. It is completely unnecessary and often counterproductive to
think of interfaces that way.


> Why is this an issue? Because most interface implementations require valid
> data pointer. "Static" (i.e. not needing data) implementations can be
> considered corner case.


It's not about needing data or not needing data. It's about deriving
meaning from the fact that there is none. As I said, this is clearly
important and used regularly - otherwise languages wouldn't need to add a
`Maybe` (or whatever) type to do it.

More importantly, if a pointer-type can't act on nil-pointers, that's a
problem *orthogonal* to whether you put it into an interface or not. If you
return an invalid value, it doesn't become valid just because you call it a
`*T` instead of an `io.Reader`. If being able to return a `nil`-pointer as
a type for which that isn't a valid value is a problem, then that should be
impossible - not wrapping that value in an interface.

So if we're hypothetically designing language with such fat pointers
>

You are reversing the 

Re: [go-nuts] Re: How to know if interface{} data is nil w/o reflecting?

2020-08-27 Thread targe...@gmail.com
> And for different types this is pretty normal as you can have
>x == 0.2   //  true
>y = int(x)
>float64(y) != 0.2  // true too

A more correct analogy would've been:
var x := 0.2
var y := float32(x)
math.IsNaN(float64(y)) // true in this analogy

> It is a property of all float types
I used floats as an example of type with such "kaboom" value.

> For the rest of the argument: It _really_ isn't  an actual problem. In 10 
years of Go this happened maybe three time to me and was dead simple to 
identify.

I faced this issue twice. Once caused by my code and the other by not mine. 
Second time it wasn't that simple to identify because Schroedingerface 
travelled quite a long distance from its birthplace. Anyway, this issue 
seems to get raised repeatedly. 

On Thursday, August 27, 2020 at 2:16:34 PM UTC+3 Volker Dobler wrote:

> On Thursday, 27 August 2020 11:39:11 UTC+2, targe...@gmail.com wrote:
>>
>> To me, if `x == nil` and then `y != nil` after `y = x` is much more 
>> confusing.
>>
>
> This can happen only if x and y have different  types.
> And for different types this is pretty normal as you can have
> x == 0.2   //  true
> y = int(x)
> float64(y) != 0.2  // true too
> With the only difference that you have explicit type conversions
> where interface assignment is implicit.
>
> And this is not even the strangest thing that can happen:
> NaN floats are especially peculiar. You can have
>x := y
>x != y  // true
>x != x  // also true
>  
> That is something everybody has to learn once. It is a
> property of all float types. Different types behave differently.
> And this is true not only for operators like +, - or / but also
> for operators like =, == and !=.
>
> For the rest of the argument: It _really_ isn't  an actual
> problem. In 10 years of Go this happened maybe three
> time to me and was dead simple to identify.
>
> V.
>
>

-- 
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/3efd9d39-0360-4efc-b47e-54482cd7dd35n%40googlegroups.com.


Re: [go-nuts] Re: How to know if interface{} data is nil w/o reflecting?

2020-08-27 Thread Volker Dobler
On Thursday, 27 August 2020 11:39:11 UTC+2, targe...@gmail.com wrote:
>
> To me, if `x == nil` and then `y != nil` after `y = x` is much more 
> confusing.
>

This can happen only if x and y have different  types.
And for different types this is pretty normal as you can have
x == 0.2   //  true
y = int(x)
float64(y) != 0.2  // true too
With the only difference that you have explicit type conversions
where interface assignment is implicit.

And this is not even the strangest thing that can happen:
NaN floats are especially peculiar. You can have
   x := y
   x != y  // true
   x != x  // also true
 
That is something everybody has to learn once. It is a
property of all float types. Different types behave differently.
And this is true not only for operators like +, - or / but also
for operators like =, == and !=.

For the rest of the argument: It _really_ isn't  an actual
problem. In 10 years of Go this happened maybe three
time to me and was dead simple to identify.

V.

-- 
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/1ad000eb-05ef-473b-b8f2-379df14ca155o%40googlegroups.com.


Re: [go-nuts] Re: How to know if interface{} data is nil w/o reflecting?

2020-08-27 Thread Robert Engels
“Tip” of course :)

> On Aug 27, 2020, at 6:03 AM, targe...@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 
>  wrote:
> 
 
>>> 
 
> On Thu, Aug 27, 2020 at 11:39 AM 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 
>>>  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 
>>  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 
> 

Re: [go-nuts] Re: How to know if interface{} data is nil w/o reflecting?

2020-08-27 Thread targe...@gmail.com
> 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  
>> 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  
 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).
>>  
>>

Re: [go-nuts] Re: How to know if interface{} data is nil w/o reflecting?

2020-08-27 Thread targe...@gmail.com
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  
> 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  
>>> 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 

Re: [go-nuts] Re: How to know if interface{} data is nil w/o reflecting?

2020-08-27 Thread Robert Engels
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 
>  wrote:
> 
> 
> 
>> On Thu, Aug 27, 2020 at 11:39 AM 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  
 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 
>>>  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 
  wrote: 
 > 
 > You may use something like this 
 > 
 > value2 := 
 > 

Re: [go-nuts] Re: How to know if interface{} data is nil w/o reflecting?

2020-08-27 Thread targe...@gmail.com
> 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.

Because you then must remember about this specific case *every time *you 
cast potentially nil pointer variable to interface. Every time you must 
write `if x != nil { return x; } else { return nil; }` instead of just 
`return x;` Does this make language simpler?

> But solutions that try to give special treatment to nil-values when they 
are put into interfaces just seem wrong to me. 

Because nils or null pointers are indeed special. They mean "Points to no 
data". So dereference operation on such pointer leads to exceptional state. 
In fact, nullable pointer in terms of richer type systems is a sum-type 
`nil|*T` where `*T` always points to some valid object, and thus 
dereferencing it is valid. map/slice/chan types are pointers in disguise. 
By the way, AFAIK string isn't "special" here because "" and nil are 
treated equally. As for comparison to int/bool, you can safely perform all 
the operations on 0 the same way as on non-zero integers, except dividing 
by it. Same for `false`. nil can be vaguely compared to floats' NaN - 
except NaN is a potential (albeit rare) result of any operation on floats, 
while pointer cannot become invalid through dereference.

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

Please don't forget that interface pointer isn't simple. It's a so-called 
"fat pointer" which consists of pointer to data and pointer to methods 
table. Thus, we have 4 potential states - (nil, nil), (nil, pointer), 
(pointer, nil) and (pointer,pointer). First one is just ordinary nil 
interface. Last one is just ordinary interface pointer with all operations 
callable without issue (as long as they're properly implemented, of 
course). Third one with valid data pointer and nil table pointer can be 
AFAIK created only through reflection and is safely considered "invalid 
state". We're left with second state with nil data pointer and valid table 
pointer, making interface methods callable on it. It wouldn't be a problem 
- if such state couldn't be created by merely casting typed nil pointer 
(typed pointer variable with nil value) to interface. Why is this an issue? 
Because most interface implementations require valid data pointer. "Static" 
(i.e. not needing data) implementations can be considered corner case.

So if we're hypothetically designing language with such fat pointers, how 
can we solve this issue?

One way is golang's way, where interface is nil when both components are 
nil. In such case, implicit casts mentioned above can easily lead to 
invalid state. To circumvent this, such state (nil, pointer) is better 
created only explicitly, "I know what I'm doing".

The other way is to check interface against nil only by its data pointer. 
When it's created from typed pointer, it always gets valid table pointer 
and data pointer from original typed one. When it's compared to nil, it's 
compared only with its data pointer. Thus, nil translates to nil, and we 
avoid second Shroedinger's state. If we wanna static implementation, we 
just create static variable which is `struct{}` and return pointer to it. 
Alas, this approach is no-go because it involves breakage too deep.
On Thursday, August 27, 2020 at 1:14:17 PM UTC+3 axel.wa...@googlemail.com 
wrote:

> On Thu, Aug 27, 2020 at 11:39 AM 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 

Re: [go-nuts] Re: How to know if interface{} data is nil w/o reflecting?

2020-08-27 Thread 'Axel Wagner' via golang-nuts
On Thu, Aug 27, 2020 at 11:39 AM 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 
>> 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 
 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
>>>  wrote:
>>> >
>>> > You may use something like this
>>> >
>>> > value2 :=
>>> *(*uint64)(unsafe.Pointer(uintptr(unsafe.Pointer()) + 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 

Re: [go-nuts] Re: How to know if interface{} data is nil w/o reflecting?

2020-08-27 Thread targe...@gmail.com
 > 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  
> 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  
>>> 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 
>>  wrote: 
>> > 
>> > You may use something like this 
>> > 
>> > value2 := 
>> *(*uint64)(unsafe.Pointer(uintptr(unsafe.Pointer()) + 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 = {...} 
>> >> _ = 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: 
>> 

Re: [go-nuts] Re: How to know if interface{} data is nil w/o reflecting?

2020-08-27 Thread 'Axel Wagner' via golang-nuts
On Thu, Aug 27, 2020 at 11:10 AM 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 
>> 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
>  wrote:
> >
> > You may use something like this
> >
> > value2 :=
> *(*uint64)(unsafe.Pointer(uintptr(unsafe.Pointer()) + 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 = {...}
> >> _ = 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 `` defines
> .String()?" - which matches the static semantics of `r.String()`.
> >>
> >> So, while I should probably not use *Type as a replacement for
> Optional, 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 

Re: [go-nuts] Re: How to know if interface{} data is nil w/o reflecting?

2020-08-27 Thread targe...@gmail.com
 > 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  
> 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 
  wrote: 
 > 
 > You may use something like this 
 > 
 > value2 := 
 *(*uint64)(unsafe.Pointer(uintptr(unsafe.Pointer()) + 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 = {...} 
 >> _ = 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 `` defines 
 .String()?" - which matches the static semantics of `r.String()`. 
 >> 
 >> So, while I should probably not use *Type as a replacement for 
 Optional, 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  wrote: 
  
  I realize I'm 

Re: [go-nuts] Re: How to know if interface{} data is nil w/o reflecting?

2020-08-27 Thread 'Axel Wagner' via golang-nuts
On Thu, Aug 27, 2020 at 10:06 AM 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
>>>  wrote:
>>> >
>>> > You may use something like this
>>> >
>>> > value2 :=
>>> *(*uint64)(unsafe.Pointer(uintptr(unsafe.Pointer()) + 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 = {...}
>>> >> _ = 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 `` defines
>>> .String()?" - which matches the static semantics of `r.String()`.
>>> >>
>>> >> So, while I should probably not use *Type as a replacement for
>>> Optional, 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  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
>>> 

Re: [go-nuts] Re: How to know if interface{} data is nil w/o reflecting?

2020-08-27 Thread targe...@gmail.com
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.

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 
>>  wrote: 
>> > 
>> > You may use something like this 
>> > 
>> > value2 := 
>> *(*uint64)(unsafe.Pointer(uintptr(unsafe.Pointer()) + 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 = {...} 
>> >> _ = 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 `` defines 
>> .String()?" - which matches the static semantics of `r.String()`. 
>> >> 
>> >> So, while I should probably not use *Type as a replacement for 
>> Optional, 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  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 
>> 

Re: [go-nuts] Re: How to know if interface{} data is nil w/o reflecting?

2020-08-23 Thread alex . besogonov
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 
> > wrote: 
> > 
> > You may use something like this 
> > 
> > value2 := 
> *(*uint64)(unsafe.Pointer(uintptr(unsafe.Pointer()) + 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 = {...} 
> >> _ = 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 `` defines 
> .String()?" - which matches the static semantics of `r.String()`. 
> >> 
> >> So, while I should probably not use *Type as a replacement for 
> Optional, 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  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 
> 

Re: [go-nuts] Re: How to know if interface{} data is nil w/o reflecting?

2020-08-23 Thread Ian Lance Taylor
On Sun, Aug 23, 2020 at 1:16 PM Denis Cheremisov
 wrote:
>
> You may use something like this
>
> value2 := *(*uint64)(unsafe.Pointer(uintptr(unsafe.Pointer()) + 
> 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 = {...}
>> _ = 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 `` defines .String()?" 
>> - which matches the static semantics of `r.String()`.
>>
>> So, while I should probably not use *Type as a replacement for 
>> Optional, 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 
>>>  wrote:
>>>
>>> On Fri, Apr 10, 2020 at 7:17 PM  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 

Re: [go-nuts] Re: How to know if interface{} data is nil w/o reflecting?

2020-08-23 Thread Denis Cheremisov
You may use something like this

*value2 := 
*(*uint64)(unsafe.Pointer(uintptr(unsafe.Pointer()) + 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.


воскресенье, 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 = {...}
> _ = 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 `` defines 
> .String()?" - which matches the static semantics of `r.String()`.
>
> So, while I should probably not use *Type as a replacement for 
> Optional, 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  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 

Re: [go-nuts] Re: How to know if interface{} data is nil w/o reflecting?

2020-08-23 Thread 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 = {...}
_ = 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 `` defines 
.String()?" - which matches the static semantics of `r.String()`.

So, while I should probably not use *Type as a replacement for 
Optional, 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  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 

Re: [go-nuts] Re: How to know if interface{} data is nil w/o reflecting?

2020-04-11 Thread Robert Engels
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 
>  wrote:
> 
>> On Fri, Apr 10, 2020 at 7:17 PM  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+unsubscr...@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+unsubscr...@googlegroups.com.
> To view this discussion on the web visit 
> 

Re: [go-nuts] Re: How to know if interface{} data is nil w/o reflecting?

2020-04-11 Thread 'Axel Wagner' via golang-nuts
On Fri, Apr 10, 2020 at 7:17 PM  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+unsubscr...@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+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAEkBMfEPjcsZ3enqXyt%2BUphFJ1cNQ81cFCcjfwwkQZKHMrjSzA%40mail.gmail.com.


Re: [go-nuts] Re: How to know if interface{} data is nil w/o reflecting?

2017-11-03 Thread ojucie
Yes, Ayan, you are quite correct. There are a lot of comparisons to check 
if an error is nil. It has it's own FAQ entry: 
https://golang.org/doc/faq#nil_error

Sincerely, what I am after is an example of a situation where the solution 
proposed by Dave Cheney would create a problem, like "See here. In this 
situation the proposed change would break my code."

When comparing error to nil, Dave's change would work just fine. That FAQ 
entry would not be needed anymore.

On Friday, November 3, 2017 at 7:31:47 AM UTC-2, Ayan George wrote:
>
>
>
> On 11/03/2017 05:23 AM, oju...@gmail.com  wrote: 
> > Could somebody please point me to any example of comparing an 
> > interface to nil, in production code? Thanks. 
> > 
>
> Does checking if a variable of type error is nil count? 
>
> -ayan 
>

-- 
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.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] Re: How to know if interface{} data is nil w/o reflecting?

2017-11-03 Thread Ayan George


On 11/03/2017 05:23 AM, oju...@gmail.com wrote:
> Could somebody please point me to any example of comparing an
> interface to nil, in production code? Thanks.
> 

Does checking if a variable of type error is nil count?

-ayan

-- 
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.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] Re: How to know if interface{} data is nil w/o reflecting?

2017-11-02 Thread Volker Dobler
On Wednesday, 1 November 2017 12:19:19 UTC+1, JuciÊ Andrade wrote:
>
> Ayan, imagine I am part of a development team. In our program I have a 
> pointer r:
>
> r *myType
>
> My variable r can be nil, because that is a valid situation. It is used in 
> dozens of places, like this:
>
> if r != nil {
> r.doSomething()
> }
>
> That is a very usual idiom, no only in Go, but in many languages. Every 
> programmer is acquainted to that.
>
> Then, years later, other programmer in my team decides to create an 
> interface to better capture a new understanding of the problem at hand, 
> changing the type of r to:
>
> r myInterface
>
> Subtly, the meaning of 
>
> if r != nil {
> r.doSomething()
> }
>
> changes. Under the right circumstances our software starts to behave 
> strangely. What?
>
> This problem is dangerous because it is so subtle. We will read our old 
> code time and again to no avail, because everything seems fine and no one 
> has changed that "if r != nil r.doSomething" in ages.
>

This is a nice argument. But please consider a small variation on it:
Let's start of with as you did: r is a pointer and you check its nilness:

r *myType
if r != nil {
r.doSomething()
}
"Then, years later, other programmer in my team decides to [...]
[add one more level of indirection] to better capture a new
understanding of the problem at hand, changing the type of r to:"

r **myType

"Subtly, the meaning of" 

if r != nil {
r.doSomething()
}

"changes. Under the right circumstances our software starts to
behave strangely. What?"

Of course it will! And this is (I hope undoubtedly) not a language
design error. Of course it would sometimes be handy to be able
to write
var a ***int
if a _!=_ nil { ... }
with an operator _!=_ with semantics like
if a != nil && *a != nil && **a!=nil { ... }
(all the way down).
But there currently is no such deep-down-comparison operator
(and it presumably would be hard to design a consistent one).

What you have been asking for is some magic to unpeel the topmost
interface level. But where to stop? How should
var b *myInterface
if b != nil { ... }
behave? Check if b actually is non-nil, then check if the interface
itself is non-nil and then peek inside the interface and check if there
is a non-nil value?

Just because a single example demonstrates that some behaviour
would be helpful and help mitigate an error does not mean it does
not open a different can of worms.

V.



-- 
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.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] Re: How to know if interface{} data is nil w/o reflecting?

2017-11-01 Thread 'Bryan Mills' via golang-nuts
On Wednesday, November 1, 2017 at 10:32:21 AM UTC-4, Ian Lance Taylor wrote:
>
> On Wed, Nov 1, 2017 at 4:18 AM,   wrote: 
> > 
> > Ayan, imagine I am part of a development team. In our program I have a 
> > pointer r: 
> > 
> > r *myType 
> > 
> > My variable r can be nil, because that is a valid situation. It is used 
> in 
> > dozens of places, like this: 
> > 
> > if r != nil { 
> > r.doSomething() 
> > } 
> > 
> > That is a very usual idiom, no only in Go, but in many languages. Every 
> > programmer is acquainted to that. 
> > 
> > Then, years later, other programmer in my team decides to create an 
> > interface to better capture a new understanding of the problem at hand, 
> > changing the type of r to: 
> > 
> > r myInterface 
> > 
> > Subtly, the meaning of 
> > 
> > if r != nil { 
> > r.doSomething() 
> > } 
> > 
> > changes. Under the right circumstances our software starts to behave 
> > strangely. What? 
> > 
> > This problem is dangerous because it is so subtle. We will read our old 
> code 
> > time and again to no avail, because everything seems fine and no one has 
> > changed that "if r != nil r.doSomething" in ages. 
> > 
> > As Dave Cheney said in 
> > https://github.com/golang/go/issues/21538#issuecomment-323561094 that 
> could 
> > be solved: 
> > 
> > "by making an nil interface and an interface which contains a type who's 
> > value is nil also equal to nil." 
>
> A different way to state your argument is that nil is overloaded in 
> Go.  Your argument is essentially identical to saying suppose you have 
> an integer r: 
>
> type MyIntegerType int 
> var r MyIntegerType 
>
> and a bunch of code that tests whether r is 0 or not 
>
> if r != 0 { 
> r.doSomething() 
> } 
>
> Then you change r to an interface type, and now the meaning of r != 0 
> has subtly changed.  The code still compiles, but now it means 
> something different.  r != 0 will be true even if the value of r 
> actually is 0, because in `r != 0` the `0` will be given type `int`, 
> but `r` is type `MyIntegerType`, so the values are not equal. 
>
> That is definitely potentially confusing, but I would like to believe 
> that you would not argue that we should treat r != 0 specially for 
> integer types.  Or, at least, we shouldn't treat it any differently 
> than r != 1.  And, obviously, `r == nil` should not be true if r 
> happens to be `0`. 
>
> I think the reason it feels different for pointer types is that we, 
> probably incorrectly, chose to use the same identifier, `nil`, to 
> represent the zero value both for pointers and for interfaces. 
> Suppose we had given the zero value of interface types the name 
> `nilinterface`.  Then the situation for pointers would be the similar 
> to that for integers.  Writing `r != nilinterface` would be equivalent 
> to `r != nil` today: it would test whether the interface itself is 
> nil.  `r != nil` would be a compilation error, because, unlike `0`, 
> there is no default type for `nil`. 
>
> If we do change something in this area for Go 2, which we probably 
> won't, my preference would definitely be to introduce `nilinterface` 
> rather than to further confuse the meaning of `r != nil`. 
>

C++ had a similar change with the `nullptr 
` literal in C++11: 
`NULL` was overloaded between pointers and integers, whereas `nullptr` can 
only be (implicitly converted to) a pointer.

-- 
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.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] Re: How to know if interface{} data is nil w/o reflecting?

2017-11-01 Thread 'Axel Wagner' via golang-nuts
It seems a very bad idea, to require the common case to go through some
package or else get lint-warned.

Checking "x == nil" is the correct way to check whether a value contains a
valid implementation of an interface - and a nil-pointer with the correct
method set is, as far as you should be concerned, such a valid
implementation.
If you indeed want to check whether the contained value is a nil-pointer
(I'm having actual trouble coming up with a scenario where you'd want to do
that - except cases like encoding/json, where you need to use reflection
anyway), you have to check that explicitly, either by converting nil into
the correct type (i.e. "x == (*T)(nil)"), or by type-asserting. That is the
uncommon case, so it's fine having to jump through a couple of hoops for
hat.

What *might* make more sense, is trying to lint whether a nil-pointer is
used for an interface, and the corresponding methods are not nil-safe. I.e.
do the "is a nil-pointer a valid value for this interface" check where it
belongs: At the point where the interface-conversion happens (when
assigning it to an interface-typed variable or passing it as an
interface-typed parameter).

On Wed, Nov 1, 2017 at 6:09 PM, Jack Christensen 
wrote:

>
>
> On 11/01/2017 09:31 AM, Ian Lance Taylor wrote:
>
>> On Wed, Nov 1, 2017 at 4:18 AM,   wrote:
>>
>>> Ayan, imagine I am part of a development team. In our program I have a
>>> pointer r:
>>>
>>> r *myType
>>>
>>> My variable r can be nil, because that is a valid situation. It is used
>>> in
>>> dozens of places, like this:
>>>
>>> if r != nil {
>>>  r.doSomething()
>>> }
>>>
>>> That is a very usual idiom, no only in Go, but in many languages. Every
>>> programmer is acquainted to that.
>>>
>>> Then, years later, other programmer in my team decides to create an
>>> interface to better capture a new understanding of the problem at hand,
>>> changing the type of r to:
>>>
>>> r myInterface
>>>
>>> Subtly, the meaning of
>>>
>>> if r != nil {
>>>  r.doSomething()
>>> }
>>>
>>> changes. Under the right circumstances our software starts to behave
>>> strangely. What?
>>>
>>> This problem is dangerous because it is so subtle. We will read our old
>>> code
>>> time and again to no avail, because everything seems fine and no one has
>>> changed that "if r != nil r.doSomething" in ages.
>>>
>>> As Dave Cheney said in
>>> https://github.com/golang/go/issues/21538#issuecomment-323561094 that
>>> could
>>> be solved:
>>>
>>> "by making an nil interface and an interface which contains a type who's
>>> value is nil also equal to nil."
>>>
>> A different way to state your argument is that nil is overloaded in
>> Go.  Your argument is essentially identical to saying suppose you have
>> an integer r:
>>
>> type MyIntegerType int
>> var r MyIntegerType
>>
>> and a bunch of code that tests whether r is 0 or not
>>
>> if r != 0 {
>>  r.doSomething()
>> }
>>
>> Then you change r to an interface type, and now the meaning of r != 0
>> has subtly changed.  The code still compiles, but now it means
>> something different.  r != 0 will be true even if the value of r
>> actually is 0, because in `r != 0` the `0` will be given type `int`,
>> but `r` is type `MyIntegerType`, so the values are not equal.
>>
>> That is definitely potentially confusing, but I would like to believe
>> that you would not argue that we should treat r != 0 specially for
>> integer types.  Or, at least, we shouldn't treat it any differently
>> than r != 1.  And, obviously, `r == nil` should not be true if r
>> happens to be `0`.
>>
>> I think the reason it feels different for pointer types is that we,
>> probably incorrectly, chose to use the same identifier, `nil`, to
>> represent the zero value both for pointers and for interfaces.
>> Suppose we had given the zero value of interface types the name
>> `nilinterface`.  Then the situation for pointers would be the similar
>> to that for integers.  Writing `r != nilinterface` would be equivalent
>> to `r != nil` today: it would test whether the interface itself is
>> nil.  `r != nil` would be a compilation error, because, unlike `0`,
>> there is no default type for `nil`.
>>
>> If we do change something in this area for Go 2, which we probably
>> won't, my preference would definitely be to introduce `nilinterface`
>> rather than to further confuse the meaning of `r != nil`.
>>
>> Ian
>>
>> Perhaps a small package and linter could solve this without requiring a
> language change. The package would expose either a NilInterface value or a
> IsNilInterface method. Users of the package would either compare to the
> pkg.NilInterface or call the pkg.IsNilInterface method. Then the linter
> could warn on all direct interface comparisons to nil.
>
> Jack
>
>
> --
> 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 

Re: [go-nuts] Re: How to know if interface{} data is nil w/o reflecting?

2017-11-01 Thread Jack Christensen



On 11/01/2017 09:31 AM, Ian Lance Taylor wrote:

On Wed, Nov 1, 2017 at 4:18 AM,   wrote:

Ayan, imagine I am part of a development team. In our program I have a
pointer r:

r *myType

My variable r can be nil, because that is a valid situation. It is used in
dozens of places, like this:

if r != nil {
 r.doSomething()
}

That is a very usual idiom, no only in Go, but in many languages. Every
programmer is acquainted to that.

Then, years later, other programmer in my team decides to create an
interface to better capture a new understanding of the problem at hand,
changing the type of r to:

r myInterface

Subtly, the meaning of

if r != nil {
 r.doSomething()
}

changes. Under the right circumstances our software starts to behave
strangely. What?

This problem is dangerous because it is so subtle. We will read our old code
time and again to no avail, because everything seems fine and no one has
changed that "if r != nil r.doSomething" in ages.

As Dave Cheney said in
https://github.com/golang/go/issues/21538#issuecomment-323561094 that could
be solved:

"by making an nil interface and an interface which contains a type who's
value is nil also equal to nil."

A different way to state your argument is that nil is overloaded in
Go.  Your argument is essentially identical to saying suppose you have
an integer r:

type MyIntegerType int
var r MyIntegerType

and a bunch of code that tests whether r is 0 or not

if r != 0 {
 r.doSomething()
}

Then you change r to an interface type, and now the meaning of r != 0
has subtly changed.  The code still compiles, but now it means
something different.  r != 0 will be true even if the value of r
actually is 0, because in `r != 0` the `0` will be given type `int`,
but `r` is type `MyIntegerType`, so the values are not equal.

That is definitely potentially confusing, but I would like to believe
that you would not argue that we should treat r != 0 specially for
integer types.  Or, at least, we shouldn't treat it any differently
than r != 1.  And, obviously, `r == nil` should not be true if r
happens to be `0`.

I think the reason it feels different for pointer types is that we,
probably incorrectly, chose to use the same identifier, `nil`, to
represent the zero value both for pointers and for interfaces.
Suppose we had given the zero value of interface types the name
`nilinterface`.  Then the situation for pointers would be the similar
to that for integers.  Writing `r != nilinterface` would be equivalent
to `r != nil` today: it would test whether the interface itself is
nil.  `r != nil` would be a compilation error, because, unlike `0`,
there is no default type for `nil`.

If we do change something in this area for Go 2, which we probably
won't, my preference would definitely be to introduce `nilinterface`
rather than to further confuse the meaning of `r != nil`.

Ian

Perhaps a small package and linter could solve this without requiring a 
language change. The package would expose either a NilInterface value or 
a IsNilInterface method. Users of the package would either compare to 
the pkg.NilInterface or call the pkg.IsNilInterface method. Then the 
linter could warn on all direct interface comparisons to nil.


Jack

--
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.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] Re: How to know if interface{} data is nil w/o reflecting?

2017-11-01 Thread Ian Lance Taylor
On Wed, Nov 1, 2017 at 4:18 AM,   wrote:
>
> Ayan, imagine I am part of a development team. In our program I have a
> pointer r:
>
> r *myType
>
> My variable r can be nil, because that is a valid situation. It is used in
> dozens of places, like this:
>
> if r != nil {
> r.doSomething()
> }
>
> That is a very usual idiom, no only in Go, but in many languages. Every
> programmer is acquainted to that.
>
> Then, years later, other programmer in my team decides to create an
> interface to better capture a new understanding of the problem at hand,
> changing the type of r to:
>
> r myInterface
>
> Subtly, the meaning of
>
> if r != nil {
> r.doSomething()
> }
>
> changes. Under the right circumstances our software starts to behave
> strangely. What?
>
> This problem is dangerous because it is so subtle. We will read our old code
> time and again to no avail, because everything seems fine and no one has
> changed that "if r != nil r.doSomething" in ages.
>
> As Dave Cheney said in
> https://github.com/golang/go/issues/21538#issuecomment-323561094 that could
> be solved:
>
> "by making an nil interface and an interface which contains a type who's
> value is nil also equal to nil."

A different way to state your argument is that nil is overloaded in
Go.  Your argument is essentially identical to saying suppose you have
an integer r:

type MyIntegerType int
var r MyIntegerType

and a bunch of code that tests whether r is 0 or not

if r != 0 {
r.doSomething()
}

Then you change r to an interface type, and now the meaning of r != 0
has subtly changed.  The code still compiles, but now it means
something different.  r != 0 will be true even if the value of r
actually is 0, because in `r != 0` the `0` will be given type `int`,
but `r` is type `MyIntegerType`, so the values are not equal.

That is definitely potentially confusing, but I would like to believe
that you would not argue that we should treat r != 0 specially for
integer types.  Or, at least, we shouldn't treat it any differently
than r != 1.  And, obviously, `r == nil` should not be true if r
happens to be `0`.

I think the reason it feels different for pointer types is that we,
probably incorrectly, chose to use the same identifier, `nil`, to
represent the zero value both for pointers and for interfaces.
Suppose we had given the zero value of interface types the name
`nilinterface`.  Then the situation for pointers would be the similar
to that for integers.  Writing `r != nilinterface` would be equivalent
to `r != nil` today: it would test whether the interface itself is
nil.  `r != nil` would be a compilation error, because, unlike `0`,
there is no default type for `nil`.

If we do change something in this area for Go 2, which we probably
won't, my preference would definitely be to introduce `nilinterface`
rather than to further confuse the meaning of `r != nil`.

Ian

-- 
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.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] Re: How to know if interface{} data is nil w/o reflecting?

2017-11-01 Thread Ain

On Wednesday, November 1, 2017 at 3:37:54 PM UTC+2, Ayan George wrote:
>
>
>
> On 11/01/2017 07:18 AM, oju...@gmail.com  wrote: 
> > Ayan, imagine I am part of a development team. In our program I have a 
> > pointer r: 
> > 
> > r *myType 
> > 
> > My variable r can be nil, because that is a valid situation. It is used 
> > in dozens of places, like this: 
> > 
> > if r != nil { 
> > r.doSomething() 
> > } 
> > 
> > That is a very usual idiom, no only in Go, but in many languages. Every 
> > programmer is acquainted to that. 
> > 
> > Then, years later, other programmer in my team decides to create an 
> > interface to better capture a new understanding of the problem at hand, 
> > changing the type of r to: 
> > 
> > r myInterface 
> > 
> > Subtly, the meaning of 
> > 
> > if r != nil { 
> > r.doSomething() 
> > } 
> > 
> > changes. Under the right circumstances our software starts to behave 
> > strangely. What? 
> > 
> > This problem is dangerous because it is so subtle. We will read our old 
> > code time and again to no avail, because everything seems fine and no 
> > one has changed that "if r != nil r.doSomething" in ages. 
> > 
>
> I think I understand what you're saying. The thing is: You changed the 
> type of r and I don't believe anyone ever promised that you can change 
> the type of a variable to an interface AND preserve its behavior. 
>
> Would you expect r to behave the same if you changed it from type string 
> to an int? 
>

Point is, in that case compiler would catch it for you and you wouldn't be 
able to compile until you fix all the parts of the code which now doesn't 
make sense. Not so in the case JuciÊ Andrade pointed out.


ain

-- 
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.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] Re: How to know if interface{} data is nil w/o reflecting?

2017-11-01 Thread Ayan George


On 11/01/2017 07:18 AM, oju...@gmail.com wrote:
> Ayan, imagine I am part of a development team. In our program I have a
> pointer r:
> 
> r *myType
> 
> My variable r can be nil, because that is a valid situation. It is used
> in dozens of places, like this:
> 
> if r != nil {
>     r.doSomething()
> }
> 
> That is a very usual idiom, no only in Go, but in many languages. Every
> programmer is acquainted to that.
> 
> Then, years later, other programmer in my team decides to create an
> interface to better capture a new understanding of the problem at hand,
> changing the type of r to:
> 
> r myInterface
> 
> Subtly, the meaning of
> 
> if r != nil {
>     r.doSomething()
> }
> 
> changes. Under the right circumstances our software starts to behave
> strangely. What?
> 
> This problem is dangerous because it is so subtle. We will read our old
> code time and again to no avail, because everything seems fine and no
> one has changed that "if r != nil r.doSomething" in ages.
> 

I think I understand what you're saying. The thing is: You changed the
type of r and I don't believe anyone ever promised that you can change
the type of a variable to an interface AND preserve its behavior.

Would you expect r to behave the same if you changed it from type string
to an int?

Also, you understand how interfaces work. I think our hypothetical
developer should simply understand how interfaces work as well; it is
reasonable to expect developers to know the language.

I don't think it is reasonable to introduce this kind of ambiguity to
protect developers from actually learning the language. I think
interfaces as they are are clear and consistent and making nil
interfaces suddenly equal to interfacess with nil values is more
'subtle' and harder to understand.

-- 
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.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] Re: How to know if interface{} data is nil w/o reflecting?

2017-11-01 Thread ojucie
Ayan, imagine I am part of a development team. In our program I have a 
pointer r:

r *myType

My variable r can be nil, because that is a valid situation. It is used in 
dozens of places, like this:

if r != nil {
r.doSomething()
}

That is a very usual idiom, no only in Go, but in many languages. Every 
programmer is acquainted to that.

Then, years later, other programmer in my team decides to create an 
interface to better capture a new understanding of the problem at hand, 
changing the type of r to:

r myInterface

Subtly, the meaning of 

if r != nil {
r.doSomething()
}

changes. Under the right circumstances our software starts to behave 
strangely. What?

This problem is dangerous because it is so subtle. We will read our old 
code time and again to no avail, because everything seems fine and no one 
has changed that "if r != nil r.doSomething" in ages.

As Dave Cheney said in 
https://github.com/golang/go/issues/21538#issuecomment-323561094 that could 
be solved:

"by making an nil interface and an interface which contains a type who's 
value is nil also equal to nil."


On Wednesday, November 1, 2017 at 7:06:31 AM UTC-2, Ayan George wrote:
>
> On 10/31/2017 12:42 PM, oju...@gmail.com  wrote: 
> > Today you can't, Ayan. 
> > 
>
> Right -- I understand that.  I'm asking how would you propose Go do 
> that?  What changes would you make to fix this? 
>
> I'm asking: If you claim Go is fundamentally broken in this way, how 
> would you fix it? 
>
> -ayan 
>
>
>

-- 
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.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] Re: How to know if interface{} data is nil w/o reflecting?

2017-11-01 Thread Ayan George


On 10/31/2017 12:42 PM, oju...@gmail.com wrote:
> Today you can't, Ayan.
> 

Right -- I understand that.  I'm asking how would you propose Go do
that?  What changes would you make to fix this?

I'm asking: If you claim Go is fundamentally broken in this way, how
would you fix it?

-ayan


-- 
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.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] Re: How to know if interface{} data is nil w/o reflecting?

2017-10-31 Thread Jesse McNelis
On Wed, Nov 1, 2017 at 3:42 AM,   wrote:
> Today you can't, Ayan.
>

It's very consistent, you can't compare an interface value reliably to
any untyped constant.
Because there is no way for the compiler to figure out what type it should take.

https://play.golang.org/p/4Fn0YNE2md

-- 
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.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] Re: How to know if interface{} data is nil w/o reflecting?

2017-10-31 Thread 'Axel Wagner' via golang-nuts
On Tue, Oct 31, 2017 at 5:33 PM,  wrote:

> The internal layout Go uses to store an interface should not mess with the
> expected behavior.
>
If interface is two separate fields, or just a pointer, or refers to a
> bitmap stored on the Moon, I don't care. I shouldn't care.


And you don't have to care. This is not an implementation detail, it is a
spec-detail. It is a consequence of

a) Methods can be declared on any type, including pointers
b) Methods can be called on any value of that type, including its zero value
c) An interface is a type for "any type with the following sets of methods"

Whether you represent an interface as one word, two words, zero words or
one billion words is irrelevant, as long as you implement Go, you have to
adhere to these rules and they imply the criticized behavior. Personally, I
have a gripe with the fact that the FAQ justifies this behavior with an
implementation detail, when really it's a consequence of the language. The
rules a), b) and c) make individually total sense. It makes sense to be
able to declare methods on pointers, as it is expected that methods can
modify state from other imperative languages. It makes sense that methods
can be called on zero values, because they should be a property of the
type, not the value. It makes sense to have the notion of a method set as
an interface.

I sincerely hope Go 2 will have it fixed.
>

https://github.com/golang/go/issues/21538 has already been filed and there
might be other issues amounting to the same thing. I think it is fair to
say, that a) for Go1, this can't be changed either way and b) for Go2, the
community is aware of the confusion.

-- 
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.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] Re: How to know if interface{} data is nil w/o reflecting?

2017-10-31 Thread Marvin Renich
* oju...@gmail.com  [171031 12:34]:
> Ian, with all due respect, I beg to differ.
> 
> Let's look at that example posted 5 years back:
> 
> http://play.golang.org/p/Isoo0CcAvr
> 
> Yes, that is the proper behavior according to the rules, we have a FAQ 
> entry, fine, but ... put simply: that makes no sense. Why? Because we, the 
> users, expect the code to work the other way. That is a big surprise and we 
> don't need the tool creating surprises for us, much to the contrary.

I beg to differ.  I, a user, very much expect the current behavior and
would be very surprised if it worked the way you are suggesting.

Ian's msg gives good reasons why it would be wrong to change the
behavior, even if we could go back in time to before the release of Go
1 and the Compatibility Guarantee.

...Marvin

-- 
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.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] Re: How to know if interface{} data is nil w/o reflecting?

2017-10-31 Thread ojucie
Ian, with all due respect, I beg to differ.

Let's look at that example posted 5 years back:

http://play.golang.org/p/Isoo0CcAvr

Yes, that is the proper behavior according to the rules, we have a FAQ 
entry, fine, but ... put simply: that makes no sense. Why? Because we, the 
users, expect the code to work the other way. That is a big surprise and we 
don't need the tool creating surprises for us, much to the contrary.

The internal layout Go uses to store an interface should not mess with the 
expected behavior. If interface is two separate fields, or just a pointer, 
or refers to a bitmap stored on the Moon, I don't care. I shouldn't care. 
The fact that today we must tell every new Go user this whole story is a 
shame. Go is meant to be easy, after all.

The behavior of a software of mine is not what my user expect? In my book 
that means I have a bug. Even with a very reasonable explanation, that 
remains a bug. I can spend hours explaining a strange behavior to my user. 
He will tell me: "Oh, yes. Now I got it, thanks. Fix that".

That reminds me of an old adage:
“If the map doesn't agree with the ground the map is wrong” 
I sincerely hope Go 2 will have it fixed.

-- 
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.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] Re: How to know if interface{} data is nil w/o reflecting?

2017-10-31 Thread Ayan George


On 10/31/2017 10:25 AM, oju...@gmail.com wrote:
> Not being able to test for a nil interface is a Go language bug.
> 

Just curious:  How would you do this without type assertion or reflection?

-- 
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.
For more options, visit https://groups.google.com/d/optout.