3 ms·
Of course I'm joking, but I think implicit nullability is the worst part of Go. A language designed in a era when this was widely known as the billion dollar mi
by cies 6y ago
Of course I'm joking, but I think implicit nullability is the worst part of Go. A language designed in a era when this was widely known as the billion dollar mistake (prolly even more expensive).
But this is not easily reversed. Not as easy as tagging generics onto the language. And the parallels with Java's maturing are just lovely. Also, we have seen what Kotlin is now doing for Java: a new language was needed to truly fix that one mistake (implicit nullability), introduced in the grandparent of Java (namely C), and the great old grand uncle of Go.
- baby 6y agoGolang needed sum types (for options) and match statements (python got it after all...) way before it needed generics. CHANGE MY VIEW.
- cies 6y agoYes. But null-safety is absolute on the top (as it is soooo hard, maybe even impossible, to add later). Generics... Well, I just come from a Elm gig (knowing Haskell/C++/Java/Kotlin/Ruby) and I must say I was not too bothered with the lack of generics there.
- jasperry 6y agoWait, doesn't Elm have parametric polymorphism like other ML-family languages? That's just as powerful as most languages' generics, and with a lot fewer brackets.
- sdfsfsf3kjdf 6y ago> Well, I just come from a Elm gig and I must say I was not too bothered with the lack of generics there. Elm has generics.
- cies 6y agoReally? Why then there's List.map, Maybe.map, Array.map, and I have to select one of them? Is that not what generics would fix?
- sdfsfsf3kjdf 6y ago> Is that not what generics would fix? No. That would be fixed by having something akin to typeclasses, traits or interfaces. Elm's List, Maybe and Array are all defined using a generic type parameter.
- floxy 6y agoThere is a terminology issue here, with "generic" being overloaded to mean different things. Parametric polymorphism is what Go is adding. You'd like to see something like ad hoc polymorphism in Elm, like type-classes in Haskell. But neither of those should be confused with the datatype generic programming. https://en.wikipedia.org/wiki/Parametric_polymorphism https://en.wikipedia.org/wiki/Parametric_polymorphism https://en.wikipedia.org/wiki/Ad_hoc_polymorphism https://en.wikipedia.org/wiki/Ad_hoc_polymorphism https://wiki.haskell.org/Generics https://wiki.haskell.org/Generics
- shakow 6y agoNo, it fixes that you don't have to chose between ListOfInts, ListOfStrings and ListOfListOfArrayOfInt. BTW, one doesn't have to chose between them in Go either, but only because there are under-the-hood generics for the native types, that are only accessible to the language designers.
- zeugmasyllepsis 6y agoSum and intersection types + pattern matching feels so natural in languages like F#, OCaml, Reason, and Elixir. I know they add a significant amount of complexity to the language, but the more I use them, the more I feel that the tradeoff lands in the goldilocks "just right" zone. I find myself missing them often.
- cies 6y ago> feels so natural Yes. They are as important as records/structs a.k.a. product types. > F#, OCaml, Reason, and Elixir Haskell, Elm, PureScript, Kotlin, Idris, ... > I know they add a significant amount of complexity to the language Really? I dont think it can be so much more than generics :) Elm has 'm and the whole language is 5k lines of code.
- eeperson 6y agoI think you want generics for many useful sum types (e.g. options) so you don't have to repeat your sum type definition everywhere it is used. Also, you can have options and matching without sum types (e.g. scala).
- merb 6y agobtw. scala 3 might change that. there is a language feature which can be turned on to have explicit nulls, which will be in the form of union/sum types: https://dotty.epfl.ch/docs/reference/other-new-features/explicit-nulls.html https://dotty.epfl.ch/docs/reference/other-new-features/expl...
- sdfsfsf3kjdf 6y agoHow exactly are you going to implement a type safe option type without generics? You either have to use interface{}, which is obviously not type safe, or write/generate an option type for every type contained within it. Sum types are a lot less useful if you don't have generics.
- dragonwriter 6y agoPython has all of those things, including generics, so whatever order they are needed in, “Python got it” doesn't argue for one over the others.
- coder543 6y ago> Of course I'm joking, but I think implicit nullability is the worst part of Go. Go doesn't have implicit nullability. You have to declare that something is a pointer for it to be nullable. There are a few kinds of pointers: "normal" pointers, slices, maps, function pointers, and interfaces. Any of those pointer types are nilable. Regular structs and primitives are not nilable. var x someStruct = nil //this will not compile var x int = nil //this also won't compile
- cies 6y agoWhen i read Go code it is riddled with null guards. Any of those null guards may be removed, code compiles without additional warnings but now may blow up at runtime. Sorry, but to me that's a clear symptom of implicit nullability. Edit: clarification, to me it does not show in the type signature that something may return a null, also I do not have to unpack a possible null value (like with Maybe or Option).
- coder543 6y agoYou can't check for nil on something that isn't nilable -- it's a compile error to do so in Go. Your definition of "implicit nullability" is suspect here. Go doesn't even implicitly de-reference things, which is what I think you're intending to say that it does. (EDIT: field access does cause a dereference, as was pointed out in a response to this comment. I still think of this as an explicit action when you're specifically operating on a pointer variable, but I'll concede this point here.) Your position on this is really confusing at the moment. Go handles nullability in an extremely different way from Java. Edit for your edit: > clarification, to me it does not show in the type signature that something may return a null The best way to know something won't be null is to use value types where possible. Don't return nilable values unless you have a good reason. When you return nilable values, only return nil when the error value isn't nil. This is a common pattern in Go code. Why would you return nil if there wasn't an error? If there was an error, why would you care what else was returned, outside of some very exceptional circumstances? > also I do not have to unpack a possible null value (like with Maybe or Option). I write Rust and Go professionally... I'm familiar with the pros and cons here, and I wish that Go would adopt Sum Types, but this has nothing to do with "implicit nullability", and in practice... it's really not a big deal. I've written huge amounts of Go code, and I just don't remember encountering nil exceptions in production except once in a blue moon -- and it is similarly common in Rust to hit an "expect" or "unwrap" that you thought was statically impossible to reach. Go has good editors (like GoLand) and linters (like golangci-lint) that make it easy to avoid most of the practical pitfalls.
- zzbzq 6y agoNow that I've worked professionally in a whole bunch of languages that attempt to delete implicit nullability out of existence, I long for it's return. Option monads are a two billion dollar mistake. The fact is when you're working with any data coming from any other system, the data is or will become null, somehow, some way, and your program code which treats this as impossible is just literally wrong in a way that is complete jibberish. Additionally, programmers don't want to pass huge lists of parameters to every function, but instead bundle things into structs to be easily passed around, however this model makes it impossible to treat a value as Optional at an early part of the callstack and Non-optional later in the callstack after it's been checked and verified. So you either pass everything as a separate parameter, copy things into different structs all over the place, or just make the value Optional everywhere, deleting the usefulness of making Optionals.... Optional. Just let it be null everywhere, and if it's null somewhere it shouldn't be, the program throws an error--like it should, because there's an error. Actually, javascript is the only language that has it right. Not only can anything be null, anything can be undefined, (which isn't even remotely similar and anyone who doesn't understand why doesn't belong in the conversation,) AND values you don't know about can exist.
- novok 6y ago> Just let it be null everywhere, and if it's null somewhere it shouldn't be, the program throws an error--like it should, because there's an error. Optionals everywhere makes that explicit, vs. something implicit that you can forget.
- cies 6y ago> Actually, javascript is the only language that has it right. Not only can anything be null, anything can be undefined I think they are very similar in that there are now 2 nully things to guard for. Option types suck in Java as they were tagged on later. Maybe in Haskell, or even nicer, Maybe in Elm is were the party's at. It is build in at the center of the language. And getting a value (v) from a list by an index should give you a "Maybe v", as you could be out of bounds. That's the strong typing that basically keeps me safe when viciously attacking a code base I have not touched for some time (or is not written by me to begin with).
- 6y ago
- p2detar 6y agoPutting your rhetoric aside, you're mostly right. As someone that maintained an old Java project, a NPE was the most common type of issue that I had to deal with. The code was riddled with them and business logic often broke leaving me to deal with lots of support tickets. That being said, implicit nullability leads to mostly human type of errors and comes from our limitation to fit all the parts of a complex system in our brains. I'm curious if there are example where machines write code and use plenty of implicit nullability without that causing any NPE issues ever. Just a thought.
- cies 6y agoPlenty of the example you request exist. Here two of m: Well Haskell compiles to binary, or Elm compiles to JS. The resulting binary/JS is basically machine written and does not throw any NPE's.
- andreygrehov 6y agoWhat do you mean by implicit nullability? Go doesn't have it. A pointer can be nil, which is obvious, but a regular string or int, or even a struct type cannot be nil (unless it's a pointer).
- dragonwriter 6y ago> A pointer can be nil, which is obvious It's certainly common, but of the things which would be useful to be able to constrain only to allow explicit and non-default nillability, pointers are pretty high on the list.
- andreygrehov 6y agoWhat would be a better design?
- dragonwriter 6y agoStatically requiring a (the default case) non-nillable pointer to be assigned to a non-nil value (presumably, ultimately as a result of an operation that fails if it can't allocate, or one that either fails or returns a non-nil pointer when passed a nillable pointer) before being used? The same thing as is done for any other non-nullable value in static type systems.