Earlier quoted context omitted.
They don't have the same feature of "I can call a method on a null value", at least, not that I've seen... You are calling them identical features when the fact is that they aren't. C# and Java both have generics, do they perform identical? Haskell has generics too, but I bet they'd throw a shit-fit if you tried to say "Oh, C# has generics too, so why would I bother with Haskell?"
The ability to call a method on a nil receiver doesn't have anything to do with what comparisons should do. Semantically, the question is whether == should compare the values or the vtables. In no other language I know of does it compare vtables.
Having fun with Go's nil, interfaces and errors
41–50 of 52 posts
Re: Having fun with Go's nil, interfaces and errors
#42Earlier quoted context omitted.
It's a stunningly difficult and surprisingly low-value proposition to create abstractions that don't leak. That's not the goal anyway: The goal is to leverage abstractions to build things. The implementation details frequently do matter. Even if your abstraction is airtight, it has to run on a real machine. When possible, it's preferable to design abstractions that have a clear implementation in terms of the lower le…
The behavior of Go's nil does not make the language any simpler to implement in any meaningful sense. The only thing it affects at the machine level is which cmp instructions are generated.
Re: Having fun with Go's nil, interfaces and errors
#43Earlier quoted context omitted.
> Except it's not a language implementation detail, it's part of what the language is. Okay, but what was the rationale for designing the language like that?
An interface being equal to nil just because the value it contains is nil would be even more confusing. For example, imagine if you had two interface values, one holding a nil * T and one holding a nil * S. They would both be equal to nil, but not equal to each other, losing transitivity of equality. Also, sometimes nil is a perfectly valid value of something and can implement interfaces. You can call methods on nil…
Re: Having fun with Go's nil, interfaces and errors
#44Re: Having fun with Go's nil, interfaces and errors
#45> This is a very interesting situation (and not a very common one for me) because it is where Go’s simple errors as values decisions shines. Doing this kind of thing with exceptions would be pretty clumsy, [...] Just because a language supports exceptions does not mean you always have to use them. You can always use a helper function to catch any error and return it as a value.
Wouldn't that basically be replicating a return value-error approach, in a more cumbersome way though? You could argue that Go can use Exceptions in the same manner as X lang too, by using panic and recover... but most people seem to not like that. With Go and Rust, return value error handling is just simply nice. There's no question about if a function might error out, just look at the signature.
This would not be "replicating" anything, exceptions already are values in most languages. The only thing to do is wrap your call with a function, like "err = catch-all(expr)".
> ou could argue that Go can use Exceptions in the same manner as X lang too, by using panic and recover...
Except that it would be cumbersome ;-) because panic/recover works only in combination with defer[0].
> With Go and Rust, return value error handling is just simply nice.
Using non-exceptional control flow for errors can be useful depending on the circumstances. Using exceptions is simply nice in many other cases.
> There's no question about if a function might error out, just look at the signature.
Just look at the documentation. Code defensively.
Re: Having fun with Go's nil, interfaces and errors
#46A man orders coffee in a restaurant.
"Would you like it with or without cream?"
"Without"
A few minutes later the waiter returns.
"I'm sorry sir, we've run out of cream. Would you like it without milk instead?"
Re: Having fun with Go's nil, interfaces and errors
#47I love the idea of a "read only" map (or any other type), but it seems it is just a side-effect landmine in this case. Yuck...almost strikes me as a bug as described in the article
var m map[T]T
you're basically writing var m *runtime.hmap
which is a nil pointer. Go has sane zero values, so it makes sense that reading from a nil map returns the zero value for whatever type its values are.However, there's a trade-off: either Go's maps allow nil assignment (in a similar fashion to slice's `append') _or_ it retains its "reference" (forgive me for using that term) semantics.
Go's designers decided that maps should differ from slices in that regard, and I tend to agree. I think it'd be a mistake to have to always return a map _just_ in it's newly allocated.
Re: Having fun with Go's nil, interfaces and errors
#48Earlier quoted context omitted.
Wouldn't that basically be replicating a return value-error approach, in a more cumbersome way though? You could argue that Go can use Exceptions in the same manner as X lang too, by using panic and recover... but most people seem to not like that. With Go and Rust, return value error handling is just simply nice. There's no question about if a function might error out, just look at the signature.
> Wouldn't that basically be replicating a return value-error approach, in a more cumbersome way though? This would not be "replicating" anything, exceptions already are values in most languages. The only thing to do is wrap your call with a function, like "err = catch-all(expr)". > ou could argue that Go can use Exceptions in the same manner as X lang too, by using panic and recover... Except that it would be cumber…
err = catch-all(expr)
If your language does not provide a similar tool, you can't just use a function because "expr" is evaluated before the function is called. I had Lisp macros in mind when writing this. A poor man's approach that is still generic is to wrap the expression in a closure: err = catch-all(() -> expr)
Not too cumbersome, but YMMV.Re: Having fun with Go's nil, interfaces and errors
#49Earlier quoted context omitted.
They don't have the same feature of "I can call a method on a null value", at least, not that I've seen... You are calling them identical features when the fact is that they aren't. C# and Java both have generics, do they perform identical? Haskell has generics too, but I bet they'd throw a shit-fit if you tried to say "Oh, C# has generics too, so why would I bother with Haskell?"
The ability to call a method on a nil receiver doesn't have anything to do with what comparisons should do. Semantically, the question is whether == should compare the values or the vtables. In no other language I know of does it compare vtables.
It the types don't match, the operands are not considered equal. Type and value have to match for two interface values to be equal. How does that not make sense?
For mismatched dynamic types you can't meaningfully compare the values in the general case, so of course you need to consider types.
Re: Having fun with Go's nil, interfaces and errors
#50Earlier quoted context omitted.
An interface being equal to nil just because the value it contains is nil would be even more confusing. For example, imagine if you had two interface values, one holding a nil * T and one holding a nil * S. They would both be equal to nil, but not equal to each other, losing transitivity of equality. Also, sometimes nil is a perfectly valid value of something and can implement interfaces. You can call methods on nil…
Couldn't they also be equal to each other? If equality was defined only in terms of the value and not the vtable (to borrow pcwalton's terms), they would be equal. Are there any problems which would arise from this?