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

2018-05-08 Thread Ian Lance Taylor
On Tue, May 8, 2018 at 6:17 PM, Michael Cohen  wrote:
>
> It seems to me that the compiler should at least warn when someone is
> comparing an interface to nil (or maybe the linter should warn). It does not
> seem that this could ever be what you actually want and it is always a
> subtle bug just waiting to bite.

It's perfectly reasonable to compare an interface to nil if you want
to see whether it has been set to anything.  In particular it's very
common in Go to write `err != nil`, so clearly warning about every
comparison of an interface value to `nil` is a non-started.  See
https://golang.org/doc/faq#nil_error.  But see also
https://golang.org/issue/22729.

The issue of passing a nil pointer to a value method is a good reason
to write your String methods as pointer methods.

Ian



> On Wednesday, 9 May 2018, Ian Lance Taylor  wrote:
>>
>> On Tue, May 8, 2018 at 7:19 AM, Michael Cohen  wrote:
>> >
>> > Well no - the error I get is that I am attempting to call String()
>> > method on
>> > a null receiver - so the caller just passed me a regular nil object. The
>> > issue is that I am trying to make a generic polymorphic function which
>> > should be able to handle whatever is thrown at it - so I guess reflect
>> > is
>> > necessary.
>> >
>> >  I think I am supposed to detect the null receiver before calling
>> > String()
>> > on it. I ended up using this little utility:
>> >
>> >
>> > https://stackoverflow.com/questions/13476349/check-for-nil-and-nil-interface-in-go
>> >
>> > func isNil(a interface{}) bool {
>> >   defer func() { recover() }()
>> >   return a == nil || reflect.ValueOf(a).IsNil()
>> > }
>> >
>> >
>> > But this feels really hacky when I really just want to say if value !=
>> > nil {
>> > } .
>>
>> I think there may be some confusion here.  Go doesn't have a "regular
>> nil object."  Specific types can be `nil`.  In particular, pointer
>> types can be `nil`.
>>
>> When a type implements a `String` method it is possible to call that
>> method with a `nil` pointer.  In general it is possible to call any
>> method with a `nil` pointer.  That is not an error.
>>
>> Some specific implementations of a `String` method may panic when
>> called with a `nil` pointer.  For better or for worse, the fmt package
>> has special handling for this.
>>
>> What this means is that unless you have some special knowledge of the
>> type you are working with, you should not check for `nil` before
>> calling the `String` method.  For some types the `String` method will
>> correctly handle `nil`.  If you have types with a `String` method that
>> does not correctly handle `nil`, then it's worth pondering why and how
>> you got a `nil` pointer for this type in the first place.  But if you
>> can reasonably have a `nil` pointer, and can reasonably expect that
>> the `String` method will panic in that case, then what you should do
>> is call `fmt.Sprint(v)`.  That will do the right thing whether v's
>> `String` method handles `nil` or not.
>>
>> 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] How to know if interface{} data is nil w/o reflecting?

2018-05-08 Thread Michael Cohen
Thanks Ian for the thorough explanation - again I apologize for asking noob
questions :-).

The issue in this case was this error:

panic: value method github.com/shirou/gopsutil/process.Process.String
called using nil *Process pointer

which seems to be coming from the go runtime itself. Certainly the String
method of Process does not have a pointer receiver:

func (p Process) String() string {
s, _ := json.Marshal(p)
return string(s)
}

So it makes sense for the runtime to panic when we attempt to call it on a
nil pointer. I looked at the code for the fmt.Sprintf method as you
suggested and it seems to be doing the same thing as what my code is doing
- i.e. it catches the panic and then calls reflect to check if it is
because its a nil pointer. So i guess what feels hacky is really the way it
is supposed to be done in golang.

I wrote the following code to try to understand the behavior more
https://play.golang.org/p/kKWGCeacAEM
package main

import (
"fmt"
)

func type_function(a *int) {
fmt.Println("type_function: ", a == nil)
 }

func interface_function(a interface{}) {
fmt.Println("interface_function: ", a == nil)
}

func main() {
type_function(nil)   // true
interface_function(nil)   // true

var foo *int = nil
fmt.Println("is foo nil: ", foo == nil)
interface_function(foo)  // false ... ?
}

It seems to me that if a function accepts a pointer type - it is ok to
compare a pointer type against nil. But if a function accepts an interface
as an arg it is never safe to compare an interface against nil because from
inside the function you have no idea if the caller called with actual nil,
or a variable who's value is nil (this difference is very weird because
this is not how most languages behave - a variable is usually a full
substitute to the literal value it holds).

It seems to me that the compiler should at least warn when someone is
comparing an interface to nil (or maybe the linter should warn). It does
not seem that this could ever be what you actually want and it is always a
subtle bug just waiting to bite.

Thanks
Michael.


On Wednesday, 9 May 2018, Ian Lance Taylor  wrote:

> On Tue, May 8, 2018 at 7:19 AM, Michael Cohen  wrote:
> >
> > Well no - the error I get is that I am attempting to call String()
> method on
> > a null receiver - so the caller just passed me a regular nil object. The
> > issue is that I am trying to make a generic polymorphic function which
> > should be able to handle whatever is thrown at it - so I guess reflect is
> > necessary.
> >
> >  I think I am supposed to detect the null receiver before calling
> String()
> > on it. I ended up using this little utility:
> >
> > https://stackoverflow.com/questions/13476349/check-for-nil-a
> nd-nil-interface-in-go
> >
> > func isNil(a interface{}) bool {
> >   defer func() { recover() }()
> >   return a == nil || reflect.ValueOf(a).IsNil()
> > }
> >
> >
> > But this feels really hacky when I really just want to say if value !=
> nil {
> > } .
>
> I think there may be some confusion here.  Go doesn't have a "regular
> nil object."  Specific types can be `nil`.  In particular, pointer
> types can be `nil`.
>
> When a type implements a `String` method it is possible to call that
> method with a `nil` pointer.  In general it is possible to call any
> method with a `nil` pointer.  That is not an error.
>
> Some specific implementations of a `String` method may panic when
> called with a `nil` pointer.  For better or for worse, the fmt package
> has special handling for this.
>
> What this means is that unless you have some special knowledge of the
> type you are working with, you should not check for `nil` before
> calling the `String` method.  For some types the `String` method will
> correctly handle `nil`.  If you have types with a `String` method that
> does not correctly handle `nil`, then it's worth pondering why and how
> you got a `nil` pointer for this type in the first place.  But if you
> can reasonably have a `nil` pointer, and can reasonably expect that
> the `String` method will panic in that case, then what you should do
> is call `fmt.Sprint(v)`.  That will do the right thing whether v's
> `String` method handles `nil` or not.
>
> 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] How to know if interface{} data is nil w/o reflecting?

2018-05-08 Thread Ian Lance Taylor
On Tue, May 8, 2018 at 7:19 AM, Michael Cohen  wrote:
>
> Well no - the error I get is that I am attempting to call String() method on
> a null receiver - so the caller just passed me a regular nil object. The
> issue is that I am trying to make a generic polymorphic function which
> should be able to handle whatever is thrown at it - so I guess reflect is
> necessary.
>
>  I think I am supposed to detect the null receiver before calling String()
> on it. I ended up using this little utility:
>
> https://stackoverflow.com/questions/13476349/check-for-nil-and-nil-interface-in-go
>
> func isNil(a interface{}) bool {
>   defer func() { recover() }()
>   return a == nil || reflect.ValueOf(a).IsNil()
> }
>
>
> But this feels really hacky when I really just want to say if value != nil {
> } .

I think there may be some confusion here.  Go doesn't have a "regular
nil object."  Specific types can be `nil`.  In particular, pointer
types can be `nil`.

When a type implements a `String` method it is possible to call that
method with a `nil` pointer.  In general it is possible to call any
method with a `nil` pointer.  That is not an error.

Some specific implementations of a `String` method may panic when
called with a `nil` pointer.  For better or for worse, the fmt package
has special handling for this.

What this means is that unless you have some special knowledge of the
type you are working with, you should not check for `nil` before
calling the `String` method.  For some types the `String` method will
correctly handle `nil`.  If you have types with a `String` method that
does not correctly handle `nil`, then it's worth pondering why and how
you got a `nil` pointer for this type in the first place.  But if you
can reasonably have a `nil` pointer, and can reasonably expect that
the `String` method will panic in that case, then what you should do
is call `fmt.Sprint(v)`.  That will do the right thing whether v's
`String` method handles `nil` or not.

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] How to know if interface{} data is nil w/o reflecting?

2018-05-08 Thread Jakob Borg


> On 8 May 2018, at 16:19, Michael Cohen  wrote:
> 
> Well no - the error I get is that I am attempting to call String() method on 
> a null receiver - so the caller just passed me a regular nil object.

They passed you a totally legit fmt.Stringer which then panicked when you 
called String() on it. That’s their fault.

>  I think I am supposed to detect the null receiver before calling String() on 
> it. I ended up using this little utility:

I really don’t think you are. But it’s your code. :)

//jb

-- 
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] How to know if interface{} data is nil w/o reflecting?

2018-05-08 Thread Michael Cohen
Well no - the error I get is that I am attempting to call String() method
on a null receiver - so the caller just passed me a regular nil object. The
issue is that I am trying to make a generic polymorphic function which
should be able to handle whatever is thrown at it - so I guess reflect is
necessary.

 I think I am supposed to detect the null receiver before calling String()
on it. I ended up using this little utility:

https://stackoverflow.com/questions/13476349/check-for-nil-and-nil-interface-in-go

func isNil(a interface{}) bool {
  defer func() { recover() }()
  return a == nil || reflect.ValueOf(a).IsNil()}


But this feels really hacky when I really just want to say if value != nil
{ } .

Thanks
Michael.

On Wednesday, 9 May 2018, Jakob Borg  wrote:

> On 8 May 2018, at 15:26, scude...@gmail.com wrote:
>
> But this crashes when foo is really a nil pointer to a type which does
> support Stringer.
>
>
> The crash isn’t on “your” side though, it’s presumably inside the String()
> method. Hence, the caller passed you something invalid that you can’t
> handle. I’d argue that avoiding this is their responsibility.
>
> My case is made weaker by how fmt.Println and friends handle this though.
> They’ll call the String() method, recover from the panic, use reflect to
> see if the boxed value is nil, and print a “”. I guess this is
> friendly, but not something I think normal code should do.
>
> (In your specific case you seem to be reimplementing fmt.Sprint; you can
> just use that instead. :)
>
> //jb
>

-- 
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] How to know if interface{} data is nil w/o reflecting?

2018-05-08 Thread Jakob Borg
On 8 May 2018, at 15:26, scude...@gmail.com wrote:
But this crashes when foo is really a nil pointer to a type which does support 
Stringer.

The crash isn’t on “your” side though, it’s presumably inside the String() 
method. Hence, the caller passed you something invalid that you can’t handle. 
I’d argue that avoiding this is their responsibility.

My case is made weaker by how fmt.Println and friends handle this though. 
They’ll call the String() method, recover from the panic, use reflect to see if 
the boxed value is nil, and print a “”. I guess this is friendly, but not 
something I think normal code should do.

(In your specific case you seem to be reimplementing fmt.Sprint; you can just 
use that instead. :)

//jb

-- 
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] How to know if interface{} data is nil w/o reflecting?

2018-01-02 Thread David Collier-Brown
I was responding to the case where one is passed an interface, expects 
it to contain a typed value, and

it does not.

--dave

--
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] How to know if interface{} data is nil w/o reflecting?

2018-01-01 Thread 'Axel Wagner' via golang-nuts
I don't understand this comparison. The C idiom you mention is concretely
typed (i.e. C doesn't have interfaces, so it doesn't have dynamic types),
so I fail to see what it has to do with interfaces. And it makes *far* more
sense to check if you got passed a nil-pointer, than to check the concrete
value of an interface -- i.e. something like this makes of course *some*
sense, in Go:

func Foo(p *string) {
if p != nil {
*p = doSomeStuff()
}
}

It makes sense to check p for nil, because you know its type and you know
you can't use it, if its nil. It's thus a very different problem than what
this thread is about.

Moreover, how does, what you say what was said above? i.e. a) As a user of
an interface, its dynamic value shouldn't concern you, in general, b) not
all zero values are nil, so checking for nil to see whether the dynamic
value is the zero value doesn't make sense and c) the zero value -
including nil - is a perfectly valid implementation of an interface?



On Tue, Jan 2, 2018 at 1:40 AM, David Collier-Brown 
wrote:

> Drifting back toward the original subject, I'm reminded of the non-bsd-c
> idiom of
>
> char *foo(char *p) {
> if (p != NULL && *p != NULL) {
> return some string operation...
> }
> ...
>
> It seems logical to check the type of the contents of an interface
> type, and its presence in a function that can take nil types and
> nil contents, much as in the C idiom.
>
> Mind you, I do find type assertions a bit clunky.
>
> --dave
>
> --
> 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.
>

-- 
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] How to know if interface{} data is nil w/o reflecting?

2018-01-01 Thread David Collier-Brown
Drifting back toward the original subject, I'm reminded of the non-bsd-c 
idiom of

char *foo(char *p) {
if (p != NULL && *p != NULL) {
return some string operation...
}
...

It seems logical to check the type of the contents of an interface
type, and its presence in a function that can take nil types and
nil contents, much as in the C idiom. 

Mind you, I do find type assertions a bit clunky. 

--dave

-- 
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] How to know if interface{} data is nil w/o reflecting?

2018-01-01 Thread matthewjuran
Since an interface can be nil I’ve been assuming interface behaves like 
slice with a pointer to the concrete data within a reference struct (that 
also includes the data type) which is passed around as an interface var.

This playground shows that the interface var is a similar reference type to 
slice: https://play.golang.org/p/PIWpyrpwNq5

I didn’t know where to look in the Go source to find the definition of an 
interface (src/runtime/type.go, src/runtime/iface.go, src/go/types/type.go, 
and src/cmd/compile/internal/types/type.go weren't immediately clear to 
me). The specification says an interface stores a value; my 
misunderstanding is that while the interface var may refer to data 
elsewhere, this data is a copy of the original.

So using a pointer assigned to an interface as a way to save stack space is 
absurd, but using a pointer assigned to an interface as a way to modify the 
original data does make sense. Arguing about nil interface vs nil pointer 
in an interface is not absurd, I apologize for my statement.

Matt

On Saturday, December 30, 2017 at 1:22:37 PM UTC-6, Matt Harden wrote:
>
> I don't know what you mean by "reference type" - as I understand it, 
> that's not a meaningful phrase in Go. Did you mean "interface"? If so, we 
> store pointers in interfaces all the time in Go. When we set an interface 
> variable i to x, we are semantically making a copy of x and storing it in 
> i. We won't be able to modify x using i (because it has a copy of x, not a 
> pointer to the original). If x is a pointer to something, then we *will* be 
> able to modify that something using i.
>
> On Sat, Dec 30, 2017 at 8:08 AM  wrote:
>
>> Storing a pointer in a reference type seems absurd to me.
>>
>> Matt
>>
>>
>> On Friday, December 29, 2017 at 11:07:31 PM UTC-6, Matt Harden wrote:
>>
>>> I really wish Go had not chosen to propagate Hoare's billion-dollar 
>>> mistake. I do realize it's all tied up with the idea that initialization is 
>>> cheap and zero values should be useful when possible, and therefore 
>>> pointers, interfaces, channels, etc. need zero values.
>>>
>>> I wonder how different Go would have been if we had required all 
>>> pointers and interfaces (only) to be initialized, and made the zero value 
>>> for maps a writable empty map. In cases where nil pointers and interfaces 
>>> are useful, it seems to me that sentinel values would serve the purpose 
>>> equally well. For example, comparing errors with (ok) would be (one 
>>> character) shorter, more meaningful and less confusing than comparing with 
>>> nil, which can be so confusing for newcomers that we have an FAQ for it. 
>>> Few would be surprised to find (e != ok) when (e == (*myerror)(nil)) -- and 
>>> if there were no nil pointers, it wouldn't even be a valid question to ask. 
>>> We could still use pointers as stand-ins for Optional types, just with 
>>> sentinel values like sql.NullInt64 to serve the purpose nil does.
>>>
>>> I know this is likely a non-starter for Go2, for good reasons - 
>>> virtually all Go code would need significant, probably manual refactoring, 
>>> and interoperability with other languages would suffer, to name two that 
>>> come to mind.
>>>
>>> I think what I really want is Haskell plus all the benefits Go has 
>>> relative to it, including Go's incredibly simple language spec, standard 
>>> library, short compile times, etc. Is that too much to ask? :-)
>>>
>>> On Fri, Nov 3, 2017 at 9:30 AM  wrote:
>>>
>> This thread helped me to understand better the current scenario and the 
 implications of a future change.

 I would be glad to recognize if this conversation had changed my mind, 
 but it didn't.

 Some programmers discovered that they could use this "valid nil 
 interface" to do some smart tricks, as Jakob kindly has shown. While I do 
 recognize that was indeed smart, Jakob offered another easy way of 
 attaining the desired effect for his constructor. It would be pretty easy 
 if he had to code that way to begin with.

 I consider unfortunate the fact that I can't safely use an interface 
 where previously I used a pointer. To me, at least, that is a natural 
 evolutionary path for a piece of software as soon as the developer 
 discover 
 opportunities to leverage the commonality of an interface. I think such 
 possibility would be more broadly useful than what we can do now.

 Go has a bunch of interesting tricks and useful idioms, but this trick 
 is proving costly.

 Thanks to everyone.

 -- 
 You received this message because you are subscribed to the Google 
 Groups "golang-nuts" group.

>>> To unsubscribe from this group and stop receiving emails from it, send 
 an email to golang-nuts...@googlegroups.com.
>>>
>>>
 For more options, visit https://groups.google.com/d/optout.

>>> -- 
>> You received this message because you are 

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

2017-12-30 Thread Matt Harden
I don't know what you mean by "reference type" - as I understand it, that's
not a meaningful phrase in Go. Did you mean "interface"? If so, we store
pointers in interfaces all the time in Go. When we set an interface
variable i to x, we are semantically making a copy of x and storing it in
i. We won't be able to modify x using i (because it has a copy of x, not a
pointer to the original). If x is a pointer to something, then we *will* be
able to modify that something using i.

On Sat, Dec 30, 2017 at 8:08 AM  wrote:

> Storing a pointer in a reference type seems absurd to me.
>
> Matt
>
>
> On Friday, December 29, 2017 at 11:07:31 PM UTC-6, Matt Harden wrote:
>
>> I really wish Go had not chosen to propagate Hoare's billion-dollar
>> mistake. I do realize it's all tied up with the idea that initialization is
>> cheap and zero values should be useful when possible, and therefore
>> pointers, interfaces, channels, etc. need zero values.
>>
>> I wonder how different Go would have been if we had required all pointers
>> and interfaces (only) to be initialized, and made the zero value for maps a
>> writable empty map. In cases where nil pointers and interfaces are useful,
>> it seems to me that sentinel values would serve the purpose equally well.
>> For example, comparing errors with (ok) would be (one character) shorter,
>> more meaningful and less confusing than comparing with nil, which can be so
>> confusing for newcomers that we have an FAQ for it. Few would be surprised
>> to find (e != ok) when (e == (*myerror)(nil)) -- and if there were no nil
>> pointers, it wouldn't even be a valid question to ask. We could still use
>> pointers as stand-ins for Optional types, just with sentinel values like
>> sql.NullInt64 to serve the purpose nil does.
>>
>> I know this is likely a non-starter for Go2, for good reasons - virtually
>> all Go code would need significant, probably manual refactoring, and
>> interoperability with other languages would suffer, to name two that come
>> to mind.
>>
>> I think what I really want is Haskell plus all the benefits Go has
>> relative to it, including Go's incredibly simple language spec, standard
>> library, short compile times, etc. Is that too much to ask? :-)
>>
>> On Fri, Nov 3, 2017 at 9:30 AM  wrote:
>>
> This thread helped me to understand better the current scenario and the
>>> implications of a future change.
>>>
>>> I would be glad to recognize if this conversation had changed my mind,
>>> but it didn't.
>>>
>>> Some programmers discovered that they could use this "valid nil
>>> interface" to do some smart tricks, as Jakob kindly has shown. While I do
>>> recognize that was indeed smart, Jakob offered another easy way of
>>> attaining the desired effect for his constructor. It would be pretty easy
>>> if he had to code that way to begin with.
>>>
>>> I consider unfortunate the fact that I can't safely use an interface
>>> where previously I used a pointer. To me, at least, that is a natural
>>> evolutionary path for a piece of software as soon as the developer discover
>>> opportunities to leverage the commonality of an interface. I think such
>>> possibility would be more broadly useful than what we can do now.
>>>
>>> Go has a bunch of interesting tricks and useful idioms, but this trick
>>> is proving costly.
>>>
>>> Thanks to everyone.
>>>
>>> --
>>> You received this message because you are subscribed to the Google
>>> Groups "golang-nuts" group.
>>>
>> To unsubscribe from this group and stop receiving emails from it, send an
>>> email to golang-nuts...@googlegroups.com.
>>
>>
>>> For more options, visit https://groups.google.com/d/optout.
>>>
>> --
> 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.
>

-- 
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] How to know if interface{} data is nil w/o reflecting?

2017-12-30 Thread matthewjuran
Storing a pointer in a reference type seems absurd to me.

Matt

On Friday, December 29, 2017 at 11:07:31 PM UTC-6, Matt Harden wrote:
>
> I really wish Go had not chosen to propagate Hoare's billion-dollar 
> mistake. I do realize it's all tied up with the idea that initialization is 
> cheap and zero values should be useful when possible, and therefore 
> pointers, interfaces, channels, etc. need zero values.
>
> I wonder how different Go would have been if we had required all pointers 
> and interfaces (only) to be initialized, and made the zero value for maps a 
> writable empty map. In cases where nil pointers and interfaces are useful, 
> it seems to me that sentinel values would serve the purpose equally well. 
> For example, comparing errors with (ok) would be (one character) shorter, 
> more meaningful and less confusing than comparing with nil, which can be so 
> confusing for newcomers that we have an FAQ for it. Few would be surprised 
> to find (e != ok) when (e == (*myerror)(nil)) -- and if there were no nil 
> pointers, it wouldn't even be a valid question to ask. We could still use 
> pointers as stand-ins for Optional types, just with sentinel values like 
> sql.NullInt64 to serve the purpose nil does.
>
> I know this is likely a non-starter for Go2, for good reasons - virtually 
> all Go code would need significant, probably manual refactoring, and 
> interoperability with other languages would suffer, to name two that come 
> to mind.
>
> I think what I really want is Haskell plus all the benefits Go has 
> relative to it, including Go's incredibly simple language spec, standard 
> library, short compile times, etc. Is that too much to ask? :-)
>
> On Fri, Nov 3, 2017 at 9:30 AM  wrote:
>
>> This thread helped me to understand better the current scenario and the 
>> implications of a future change.
>>
>> I would be glad to recognize if this conversation had changed my mind, 
>> but it didn't.
>>
>> Some programmers discovered that they could use this "valid nil 
>> interface" to do some smart tricks, as Jakob kindly has shown. While I do 
>> recognize that was indeed smart, Jakob offered another easy way of 
>> attaining the desired effect for his constructor. It would be pretty easy 
>> if he had to code that way to begin with.
>>
>> I consider unfortunate the fact that I can't safely use an interface 
>> where previously I used a pointer. To me, at least, that is a natural 
>> evolutionary path for a piece of software as soon as the developer discover 
>> opportunities to leverage the commonality of an interface. I think such 
>> possibility would be more broadly useful than what we can do now.
>>
>> Go has a bunch of interesting tricks and useful idioms, but this trick is 
>> proving costly.
>>
>> Thanks to everyone.
>>
>> -- 
>> You received this message because you are subscribed to the Google Groups 
>> "golang-nuts" group.
>> To unsubscribe from this group and stop receiving emails from it, send an 
>> email to golang-nuts...@googlegroups.com .
>> For more options, visit https://groups.google.com/d/optout.
>>
>

-- 
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] How to know if interface{} data is nil w/o reflecting?

2017-12-29 Thread Matt Harden
I really wish Go had not chosen to propagate Hoare's billion-dollar
mistake. I do realize it's all tied up with the idea that initialization is
cheap and zero values should be useful when possible, and therefore
pointers, interfaces, channels, etc. need zero values.

I wonder how different Go would have been if we had required all pointers
and interfaces (only) to be initialized, and made the zero value for maps a
writable empty map. In cases where nil pointers and interfaces are useful,
it seems to me that sentinel values would serve the purpose equally well.
For example, comparing errors with (ok) would be (one character) shorter,
more meaningful and less confusing than comparing with nil, which can be so
confusing for newcomers that we have an FAQ for it. Few would be surprised
to find (e != ok) when (e == (*myerror)(nil)) -- and if there were no nil
pointers, it wouldn't even be a valid question to ask. We could still use
pointers as stand-ins for Optional types, just with sentinel values like
sql.NullInt64 to serve the purpose nil does.

I know this is likely a non-starter for Go2, for good reasons - virtually
all Go code would need significant, probably manual refactoring, and
interoperability with other languages would suffer, to name two that come
to mind.

I think what I really want is Haskell plus all the benefits Go has relative
to it, including Go's incredibly simple language spec, standard library,
short compile times, etc. Is that too much to ask? :-)

On Fri, Nov 3, 2017 at 9:30 AM  wrote:

> This thread helped me to understand better the current scenario and the
> implications of a future change.
>
> I would be glad to recognize if this conversation had changed my mind, but
> it didn't.
>
> Some programmers discovered that they could use this "valid nil interface"
> to do some smart tricks, as Jakob kindly has shown. While I do recognize
> that was indeed smart, Jakob offered another easy way of attaining the
> desired effect for his constructor. It would be pretty easy if he had to
> code that way to begin with.
>
> I consider unfortunate the fact that I can't safely use an interface where
> previously I used a pointer. To me, at least, that is a natural
> evolutionary path for a piece of software as soon as the developer discover
> opportunities to leverage the commonality of an interface. I think such
> possibility would be more broadly useful than what we can do now.
>
> Go has a bunch of interesting tricks and useful idioms, but this trick is
> proving costly.
>
> Thanks to everyone.
>
> --
> 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.
>

-- 
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] How to know if interface{} data is nil w/o reflecting?

2017-11-03 Thread ojucie
This thread helped me to understand better the current scenario and the 
implications of a future change.

I would be glad to recognize if this conversation had changed my mind, but 
it didn't.

Some programmers discovered that they could use this "valid nil interface" 
to do some smart tricks, as Jakob kindly has shown. While I do recognize 
that was indeed smart, Jakob offered another easy way of attaining the 
desired effect for his constructor. It would be pretty easy if he had to 
code that way to begin with.

I consider unfortunate the fact that I can't safely use an interface where 
previously I used a pointer. To me, at least, that is a natural 
evolutionary path for a piece of software as soon as the developer discover 
opportunities to leverage the commonality of an interface. I think such 
possibility would be more broadly useful than what we can do now.

Go has a bunch of interesting tricks and useful idioms, but this trick is 
proving costly.

Thanks to everyone.

-- 
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] How to know if interface{} data is nil w/o reflecting?

2017-11-03 Thread Jakob Borg
I often do nil checks on interfaces in places like constructors that may or may 
not have received optional parameters. In some cases as a parameter that may be 
nil if no implementation is required, in some cases where a functional option 
setting the interface was not given. Typically this looks something like:

func Walk(ctx context.Context, cfg Config) (chan protocol.FileInfo, error) {
w := walker{cfg}

if w.CurrentFiler == nil {
w.CurrentFiler = defaultCurrentFiler{}
}
…
}

where the field is set to some default implementation when nil. It’s also not 
uncommon to have nil implementations of that interface, especially in tests:

type mockCurrentFiler struct{}

func (*mockCurrentFiler) CurrentFile(string) whatever {
return nil
}

var testCurrentFiler *mockCurrentFiler // nil

…

cfg.CurrentFiler = testCurrentFiler // == nil in the new regime
Walk(ctx, cfg)

This would break, in a surprising way as the default implementation would be 
used instead of the given mock implementation. Clearly the test can be 
refactored:

cfg.CurrentFiler = {} // not nil

but yes, the change would break code.

I’m not saying that having this change in Go 2 would necessarily be a bad idea, 
but the current Go 1 behavior makes sense in Go 1 and there is definitely code 
that depends on it.

//jb

On 3 Nov 2017, at 11:09, oju...@gmail.com wrote:

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.

-- 
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] How to know if interface{} data is nil w/o reflecting?

2017-10-30 Thread Jesse McNelis
On Tue, Oct 31, 2017 at 2:25 AM,   wrote:
> I found this a little bit non sequitur - if I want to call interface
> function I have a perfect business to check if underlying object is not nil
> before call just to avoid panic on call. Besides underlying nil in interface
> may be used to signal condition for variety of types implementing this
> interface, and since there is no inheritance in Go - sometimes it's the only
> proper way to indicate such condition.

In Go you can call a method on nil without a panic, this means that
unless you know the type you don't know if a nil value of that type is
a valid value to call a method on or not. You would be making a big
assumption about the type contained within the interface{} if you
checked that value for nil.

Of course since you don't know the type of the value inside the
interface{} it might not even be a value comparable to nil, in which
case should the comparison return false or panic?

-- 
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] How to know if interface{} data is nil w/o reflecting?

2017-10-30 Thread tmpbox
I found this a little bit non sequitur - if I want to call interface 
function I have a perfect business to check if underlying object is not nil 
before call just to avoid panic on call. Besides underlying nil in 
interface may be used to signal condition for variety of types implementing 
this interface, and since there is no inheritance in Go - sometimes it's 
the only proper way to indicate such condition.

On Monday, June 4, 2012 at 7:54:17 PM UTC-4, Jesse McNelis wrote:
>
> On Tue, Jun 5, 2012 at 8:50 AM, Jonathan Gold  > wrote: 
> > I'm a bit stumped and wondering if I'm overlooking some way, besides 
> reflection, 
> > to determine whether the data pointed at by an interface{} is actually a 
> nil 
> > pointer: 
>
> You just use a type assertion. If you don't know the type, then you 
> don't know if nil is a valid value for it and thus have no business 
> checking for it. 
>
>
> -- 
> = 
> http://jessta.id.au 
>

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