On Mon, Mar 28, 2022 at 12:39 AM Sam Hughes <sam.a.hug...@gmail.com> wrote:

> @Axel, I really did mean what I said.
>

So did I.

FTR, if OP would have asked for changes to the type-system to be able to
represent non-nilable types, my response would have been different. I
didn't read their original message as asking for that.

I didn't say "it's impossible" or "it's a bad idea" to have a programming
language which is more strict about nil-references. I said that it's
impossible to have the Go compiler force you to check for nil-pointers and
a bad idea to have vet do it. I consider every discussion on this list as
starting from the language as it is today.

The more convenient approach is to implement a type like below. If you
> disagree? So help me....I'll.... I'll disagree with you?
>
> ```Go
> type Box[T any] *T
>
> func (ptr Box[T]) Raw() *T {
>   return (*T)(ptr)
> }
>
> func (ptr Box[T]) IsNil() bool {
>   return ptr.Raw() == nil
> }
>
> func (ptr Box[T]) Value() (checked T) {
>   if blind := ptr.Raw(),  ok := !IsNil() bool; ok {
>     checked = *blind
>   }
>   return checked
> }
>

To me, this seems like it reduces robustness for most programs (assuming
you meant to write `Box[T any] struct { p *T }`, otherwise it's at best the
same). For one, if you have a pointer, you usually want to do something
with that value - getting a new value every time it is dereferenced would
make it really easy to write broken programs. It's also easy for functions
to have non-sensical behavior when applied to the zero value of some type.

In short, the semantics of "nil-pointers dereference to a new zero-value of
the type" seems extremely brittle and a bad idea to me.


>
> I recently saw a talk called "It's all about Tradeoffs". This is an
> excellent example of that. Maybe the above could be improved by static
> checking and optimization, but it's never as cheap as just trusting there's
> something there, so long as there actually is something there.
> On Friday, March 25, 2022 at 1:41:07 PM UTC-5 Michael Toy wrote:
>
>> The discussion is quite informative for me to read, thanks for
>> responding. Go uses nil in a way which I don't quite yet grok, and so I had
>> no idea if it was even a reasonable thing to wish for. Today I am writing
>> in Typescript, and the way null is integrated into the type system now
>> (after a while) feels natural and helpful to me.
>>
>> Sam is correct, there is bug in my Go snippet in the post. For humor
>> value only, I would like to point out that the imaginary Go compiler I was
>> wishing for would have found that bug!
>>
>> I think Brian gets to the heart of my question, which is "If I really
>> understood Go, would I want something like this". I am hearing, "No, you
>> would not"
>>
>> I think if I were to have a long conversation with Axel about "what is it
>> that makes programs robust and maintainable" we'd go round in circles a
>> bit, as should happen any time you talk about something complex and
>> important. I think I disagree with some statements, but even the
>> disagreement is super helpful.
>>
>> Thanks for the discussion!
>>
>> -Michael Toy
>>
>> On Thursday, March 24, 2022 at 12:22:44 AM UTC-10 Brian Candler wrote:
>>
>>> The OP hasn't said specifically which language or feature they're
>>> comparing with, but I wonder if they're asking for a pointer type which is
>>> never allowed to be nil, enforced at compile time.  If so, a normal
>>> pointer-which-may-be-nil would have to be represented as a Maybe[*T] or
>>> union { *T | nil }. To use such a pointer value at runtime you'd have to
>>> deconstruct it via a case statement or similar, with separate branches for
>>> where the value is nil or not-nil. I am sure there have been proposals
>>> along those lines floated here before.
>>>
>>> I don't think this would negatively affect code readability, because a
>>> function which takes *T as an argument can be sure that the value passed in
>>> can never be nil (the compiler would not allow a value of type Maybe[*T] to
>>> be passed).  Conversely, a function which accepts Maybe[*T] as an argument
>>> is explicitly saying that the value passed may legitimately be nil, and
>>> hence it needs to check for this.
>>>
>>> I like this idea in principle, but in the context of Go it would mean
>>> that *T does not have any valid zero value, so you would not be able to use
>>> it in any variable or struct which is not explicitly initialized.  This
>>> would definitely not be Go any more.
>>>
>>> type T ....
>>> var t T  // ok
>>>
>>> var p1 Maybe[*T]  // ok
>>> var p2 *T = &t  // ok
>>> var p3 *T  // fails to compile (no zero value is available)
>>>
>>> type A struct {
>>>     a Maybe[*T]
>>> }
>>> var q1 A // ok
>>>
>>> type B struct {
>>>     b *T
>>> }
>>> var q2 B = B{b: &t} // ok
>>> var q3 B  // fails to compile (cannot create zero-valued instance of
>>> this struct, because it includes a member which cannot have a zero value)
>>>
>>> On Thursday, 24 March 2022 at 09:41:23 UTC axel.wa...@googlemail.com
>>> wrote:
>>>
>>>> One thing to be clear: It is very different if we are talking about
>>>> "emit a warning if a value is known to be nil" and "emit a warning unless a
>>>> warning is known not to be nil". The former seems fine to me - it is IMO
>>>> fine for this code to cause a vet-failure:
>>>>
>>>> var x *int
>>>> y := *x
>>>>
>>>> What I'm opposing is the original idea, for this code to cause a
>>>> vet-failure:
>>>>
>>>> func (x *int) { *x }
>>>>
>>>> Importantly, whether or not a value is `nil` is *always* going to be a
>>>> heuristic <https://en.wikipedia.org/wiki/Halting_problem>.
>>>> If we complain about "known to be nil", every finding will always be a
>>>> bug. I don't think it's objectionable to find them statically.
>>>> If we complain about "not known not to be nil", a significant number of
>>>> findings will be non-bugs, leading to changes as OP suggested. So, I'm
>>>> assuming that's the situation we are talking about.
>>>>
>>>> On Thu, Mar 24, 2022 at 9:40 AM Sam Hughes <sam.a....@gmail.com> wrote:
>>>>
>>>>> @axel, it my feel counter-intuitive, but a possible runtime panic
>>>>> converted to a compiler error is an increase in how robust the code is.
>>>>>
>>>>
>>>> Of course. But that's not what we are talking about. We are converting
>>>> *some* runtime bugs into compiler errors (really, vet checks, we can't fail
>>>> to compile because of backwards compatibility).
>>>> But most of them, where it's not clear from the code that a particular
>>>> pointer is going to be nil, will get the treatment suggested by OP. Which
>>>> ends up exploding the state-space of possible behaviors of a program,
>>>> making it exponentially harder to know what it's doing.
>>>>
>>>> That's IMO the less intuitive thing. People tend to think "crashing
>>>> code is unreliable". But really, crashing is quite a safe and easy to
>>>> reason about behavior. But having to constantly program against any
>>>> possible bug leads to unmaintainable, brittle, impossible to reason about
>>>> code. If every index-expression, every pointer-dereference and every method
>>>> call needs to be wrapped in a conditional, it becomes impossible to really
>>>> understand where a failure is coming from and how a program behaves in
>>>> different failure modes.
>>>>
>>>> The weird part, at least, why it might feel weird, is that you might
>>>>> never encounter the issue as a runtime panic, but as a compiler error, it
>>>>> will hit you every time. This will make exploring and experimenting with
>>>>> unfamiliar imports, features, and patterns more complicated, but it is the
>>>>> entire point, to my mind, of having a type-system.
>>>>>
>>>>> P.S. Bug in the snippet given by OP? I expected to see "x != nil"
>>>>> instead of "x == nil", or else change comments around.
>>>>>
>>>>>
>>>>> On Wednesday, March 23, 2022 at 4:15:13 PM UTC-5
>>>>> axel.wa...@googlemail.com wrote:
>>>>>
>>>>>> Personally, I think this leads to very unreadable code, for no real
>>>>>> benefit.
>>>>>> If a nil-pointer dereference happens unexpectedly, that's always a
>>>>>> bug. A panic is the correct signal to tell me about that bug, so I can go
>>>>>> ahead and fix it. So, making my code less readable to get less robust 
>>>>>> code
>>>>>> seems like a lose-lose proposition to me.
>>>>>>
>>>>>> Of course, people can always choose to write/use whatever static
>>>>>> checker they want. I'm not opposed to this existing. I just don't think 
>>>>>> it
>>>>>> should be in the compiler or in `go vet`.
>>>>>>
>>>>>> On Wed, Mar 23, 2022 at 10:01 PM 'Michael Toy' via golang-nuts <
>>>>>> golan...@googlegroups.com> wrote:
>>>>>>
>>>>>>> I barely understand Go, so this is likely a stupid idea. Since Go
>>>>>>> uses nil for a lot of things, lots of things can be nil.
>>>>>>>
>>>>>>> I am not a huge fan of the null safe accessor. (
>>>>>>> https://github.com/golang/go/issues/42847 )
>>>>>>>
>>>>>>> I am a huge fan of the compiler telling me the places where I have
>>>>>>> not checked for nil ... It took me a while to get used to languages 
>>>>>>> which
>>>>>>> do this, but now I can't imagine living without it.
>>>>>>>
>>>>>>> Is it crazy to wish for ...
>>>>>>>
>>>>>>> if x == nil {
>>>>>>>   // this does not produce an error because x is known not to be nil
>>>>>>>   x.interfaceFunc()
>>>>>>> }
>>>>>>> // this DOES produce an error/warning if y is possibly nil
>>>>>>> y.interfaceFunc()
>>>>>>>
>>>>>>> --
>>>>>>> You received this message because you are subscribed to the Google
>>>>>>> Groups "golang-nuts" group.
>>>>>>> To unsubscribe from this group and stop receiving emails from it,
>>>>>>> send an email to golang-nuts...@googlegroups.com.
>>>>>>> To view this discussion on the web visit
>>>>>>> https://groups.google.com/d/msgid/golang-nuts/5a700cd9-9274-4756-80a6-9d322232afebn%40googlegroups.com
>>>>>>> <https://groups.google.com/d/msgid/golang-nuts/5a700cd9-9274-4756-80a6-9d322232afebn%40googlegroups.com?utm_medium=email&utm_source=footer>
>>>>>>> .
>>>>>>>
>>>>>> --
>>>>> You received this message because you are subscribed to the Google
>>>>> Groups "golang-nuts" group.
>>>>> To unsubscribe from this group and stop receiving emails from it, send
>>>>> an email to golang-nuts...@googlegroups.com.
>>>>>
>>>> To view this discussion on the web visit
>>>>> https://groups.google.com/d/msgid/golang-nuts/14f6ade8-fe5b-4876-b692-ed98764eaa55n%40googlegroups.com
>>>>> <https://groups.google.com/d/msgid/golang-nuts/14f6ade8-fe5b-4876-b692-ed98764eaa55n%40googlegroups.com?utm_medium=email&utm_source=footer>
>>>>> .
>>>>>
>>>> --
> 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/adb3260f-d6a8-4672-9a42-52d39a6a3bd9n%40googlegroups.com
> <https://groups.google.com/d/msgid/golang-nuts/adb3260f-d6a8-4672-9a42-52d39a6a3bd9n%40googlegroups.com?utm_medium=email&utm_source=footer>
> .
>

-- 
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/CAEkBMfE8omAVr%3DKV1K6my9fckwFp_LEKDWn4hSUFsCz5O_rmxg%40mail.gmail.com.

Reply via email to