8 ms·
> For code to be correct in the presence of null references, the programmer must remember to check every nullable value of uncertain status, without support fro
by enneff 13y ago
> For code to be correct in the presence of null references, the programmer must remember to check every nullable value of uncertain status, without support from the compiler.
If you don't have null pointers then you need to push the responsibility for checking for initialization somewhere. You seem to be advocating that place is in the type system. That's fine, but you can't say it wouldn't make the type system more complex.
I see more Go code than probably anyone in the world, and I don't see anyone suffering from the scourge of null pointers, however bad people say they are. I think in certain contexts they can be problematic (SQL is a good example), but the concept of "nil" in Go is quite useful and easy to understand. For instance, unlike C++ it is quite valid to call a method on a nil receiver.
> Tell me again, how does allowing null references lead to "simple code that is obviously correct"?
It's a tradeoff. You get a simpler type system in exchange for null pointers.
> More complexity for the language implementers; less complexity for the language users.
No, not just for the implementers. For the users too.
- mietek 13y ago> No, not just for the implementers. For the users too. You haven't bothered to address option types. This sort of unqualified assertion may lead people to believe Go's questionable design decisions were, in fact, made out of ignorance. A language with null references is exactly like a language with option types, where every reference value is by default optional. Removing this default does not increase complexity for the user. Conversely, it allows the user to write less code and enjoy more safety, which is clearly a complexity decrease.
- enneff 13y ago> A language with null references is exactly like a language with option types, where every reference value is by default optional. Yes. > Removing this default does not increase complexity for the user. Yes, it does. They need to be aware of the semantics of the option mechanism, how to specify whether a type is optional, and when that is appropriate. They must also perform checks when converting values from optional to non-optional types. In Go the choice is made for you: reference types may be nil.
- mietek 13y ago> They need to be aware of the semantics of the option mechanism, how to specify whether a type is optional, and when that is appropriate. Being aware of the semantics of the option mechanism is exactly like being aware of the semantics of null references. You've just agreed one is like the other with a default. Specifying whether a value is optional is less complex than the usual way of specifying whether a reference can be null — a documentation comment. Comments aren't usually checked by the compiler. Knowing whether it's appropriate for a value to be optional is exactly like knowing whether it's appropriate for a reference to be null. However, once a value is determined to exist, subsequent code can assume the value is non-optional, avoiding subsequent checks with no decrease in safety. Less complexity. > They must also perform checks when converting values from non-optional to optional types. Surely you mean the other way around? Checking whether an optional value exists is exactly like checking whether a reference is not null. However, fewer checks are necessary. Less complexity.
- enneff 13y ago> Surely you mean the other way around? Yes, I had it backwards. Corrected. > Specifying whether a value is optional is less complex than the usual way of specifying whether a reference can be null — a documentation comment. Is it? I agree there's definite virtue in having this property checked by the compiler, but I think you and I will have to disagree on the notion of complexity here.
- azth 13y agoThe beauty of Option types is that they are mostly used as return types. Most function arguments are non-nullable pointers or references; only ones that might be None are passed as options. This makes reasoning about code much easier. I just look at the function signature, and I know the types of arguments it expects. I also don't have to litter the beginning of each function call with if !null checks to each reference parameter. > They must also perform checks when converting values from optional to non-optional types. There are multiple ways to manipulate option type variables. The following comment from a Redditor sums it up very nicely: "What is interesting is that (coming from scala and haskell) you almost never pattern-match on option types. The power of option, imho, is that you don't have to care whether it is Some or None, you write the same code regardless. If you are pattern-matching the whole time, you haven't gained all that much over checking for nil/null. Option is a container, and we can use my_var.chain(...) and my_var.map(...) to update the things in the container. And the joy of it is that these methods will automatically do the right thing, with repect to Some/None, so you can string a bunch of these calls together, and if my_var is Some(...) is will apply all of the specified functions. If it is None, it will remain None." source: http://www.reddit.com/r/rust/comments/1ewrhz/pattern_matching_and_the_option_type/ http://www.reddit.com/r/rust/comments/1ewrhz/pattern_matchin...
- azth 13y agoThe main Go authors come from a C background, and they despise C++ and Java. It seems that those languages are their main experience, and hence, Go does not look too different from them. Go was originally presented as a "systems" programming language, and as a C++ replacement. It failed to attract C++ and other systems programmers, while attracting Python and Ruby coders. In retrospect, it seems to make sense. I suspect the reason adding generics is hard in Go is a due to its weird composition system (they loathe object hierarchies too, remember?) I concur, that we should be using and developing languages that have strong, expressive type systems. Furthermore, these languages are not "complex" to use or understand. I really admire what the Rust people are doing. They are writing a browser engine while developing the language, so they can continually evaluate their design choices, and if needed, change things as they go. Go looks like it has been designed into a corner, but it is too late to back up now. The main driving force it has is that it has Google as a brand name behind it, unfortunately. Otherwise, it most likely wouldn't have gone anywhere.
- enneff 13y ago> Go looks like it has been designed into a corner, but it is too late to back up now. Not really. We had years of experience with Go—and made many changes—before we stabilized the spec with Go 1. We are happy with the major decisions we have made so far, as are a lot of Go users. Of course there are minor things we would change if given the chance today, but the basics of the type system and the presence of nil pointers are not among them. The reason generics is hard is because we want to find a way of doing it without losing the feel of the language we have right now (which we quite like, thanks).