News for hackers. Stuff that matters.
Re:Golang generics proposal has been accepted by cies on Wednesday February 10, 2021 @03:09PM (#26094024)
This was to be expected. But I'm glad for Go.

In some years a language that interops with Go comes out, where all the Go types have a ?-suffix indicating they are nullable. The language will be mostly null-safe. Also it will sport sumtypes and pattern matching/ destructuring in switch statements.

It will be called: Gotlin.

Re:Golang generics proposal has been accepted by cies on Wednesday February 10, 2021 @03:15PM (#26094105)
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.

Re:Golang generics proposal has been accepted by zzbzq on Wednesday February 10, 2021 @03:42PM (#26094478)
Now 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.

Re:Golang generics proposal has been accepted by pkulak on Wednesday February 10, 2021 @04:08PM (#26094833)
> and your program code which treats this as impossible is just literally wrong

That's fine though. The program that treats it as possible but fails to handle it in every possible spot is wrong too, but wrong in a completely unpredictable place, way and even number of times.

It's freeing to start out assuming "title" can never be null. If it is, you get a quick failure at the very edge of your application where the data comes in. You make it nullable, and the compiler tells you all the places where you made the wrong assumption and now need a fix. Or even better yet, you give it a default value, even an empty string, and nothing more is required.

Re:Golang generics proposal has been accepted by cactus2093 on Wednesday February 10, 2021 @03:55PM (#26094650)
> copy things into different structs all over the place

Sanitizing input is a very common pattern and I don't see why this option is such a deal breaker. And it would normally just be needed at the system boundary, rather than "all over the place".

Or, you share types between different services using something like grpc or thrift, and then you really can trust that the values coming in are not going to be null.

I definitely don't agree that settling for implicit null is the best option.

Re:Golang generics proposal has been accepted by slammin on Wednesday February 10, 2021 @06:03PM (#26096048)
> 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.

i don't really understand this part. you can't treat it as impossible, because `Optional[T]` is a different type than `T`. anywhere you try to use an `Optional[T]` as a `T` is a type error.

i think you're saying "there are some cases where `T` can also be null that are now unaccounted for," which i don't think is really relevant. that's more a matter of API design; a hypothetical function that receives data from a server should return an `Optional[T]`. one that treats the operation as infallible would throw an exception just like in an implicitly null language, right?

Re:Golang generics proposal has been accepted by mc10 on Wednesday February 10, 2021 @03:51PM (#26094594)
I don’t see how any of the points you made is a great defense of keeping nulls around.

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

Your program and the other program has to agree on some protocol. That can have optionality built into it if you expect them to not send certain fields. If that protocol is violated then either you made a mistake (protocol was not accurate) or they did (sent poorly formatted data); either way, you can handle the error without nulls.

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

I think what’s being described here could be easily encoded as variants/sum types, or you could have functions that give optional fields default values. Without a specific example it’s hard to discuss what you’re really trying to say.

Re:Golang generics proposal has been accepted by novok on Wednesday February 10, 2021 @05:53PM (#26095940)
> 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.

Re:Golang generics proposal has been accepted by acoard on Wednesday February 10, 2021 @03:59PM (#26094708)
>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.

If you mean `unknown`, that's a TypeScript thing.[0]

And personally I love working on a code-base and with coders that differentiate between null and unknown. But there's no denying it's a footgun and many get no value besides bugs from these two. It's kind of similar to how JS gets boolean comparisons weird, which is worked-around by convention

[0] https://www.typescriptlang.org/docs/handbook/release-notes/t...

Re:Golang generics proposal has been accepted by cies on Wednesday February 10, 2021 @03:51PM (#26094593)
> 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).

Re:Golang generics proposal has been accepted by alisonatwork on Wednesday February 10, 2021 @08:21PM (#26097107)
I kind of agree, when working on a large team.

Adding optional arguments everywhere is a bit like declaring checked exceptions everywhere. It's true that optionals make the code more explicit, and they force developers to handle every situation, but in the end you still need developers who actually care about writing readable and maintainable code for it to be a net gain.

Something I have come across a fair bit is code where too many values are declared as optional, so the developers try to build an elegant solution by mapping functions over these optional values, returning a default at the end. If there is a value, then the expected code path gets called, else it just silently skips the rest of the code and returns back up to the top layer. This causes a similar issue to what can happen with promises - you lose the context of where the first "error" happened. This could be avoided by eagerly throwing an exception in the first absent case, but that takes us back to where we started with null.

I think the "best practice" way of using optional values is to get buy-in from all the developers on the project that basically nothing should be optional, ever. The goal, then, is to explicitly throw an exception (or return an error) at the very top level and ensure that only actual values enter into the main part of the project's code. But enforcing that is more of a management problem than a technical problem.

Re:Golang generics proposal has been accepted by dragonwriter on Thursday February 11, 2021 @01:21PM (#26105192)
> 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.

No, it doesn't; there's a couple easy, obvious ways to do that depending on how you get the data components and how far it is useful to pass them as a group without ensuring none are null. It's not even mildly challenging, much less impossible.

Re:Golang generics proposal has been accepted by pjungwir on Wednesday February 10, 2021 @03:52PM (#26094612)
I've been experimenting with Rust's Rocket webapp framework, and as much as I like it, I agree it's very annoying how a struct can't permit nulls in one context but not another. I wish there were an easy solution that didn't require near-identical struct definitions and excess copying memory from one place to another.
Re:Golang generics proposal has been accepted by sdfsfsf3kjdf on Wednesday February 10, 2021 @04:18PM (#26094949)
In Rust you can solve this via derive or a macro. Typescript's conditional types and the associated utility types are a nice solution to this problem as well. You can do a ton with Partial, Required, Pick, Omit, Exclude etc.
Re:Golang generics proposal has been accepted by pjungwir on Thursday February 11, 2021 @12:42PM (#26104655)
Thank you both for these tips. I'll see what I can figure out! :-)
Re:Golang generics proposal has been accepted by wtetzner on Wednesday February 10, 2021 @04:11PM (#26094863)
Seems like a good opportunity for a custom derive.
Re:Golang generics proposal has been accepted by beoh on Wednesday February 10, 2021 @05:57PM (#26095986)
This is not an issue with Option at all. When you receive data from an external system, you should always parse it before making assumptions. By parsing I don't mean read property x as string, but make it a CustomerId for example, considering your constraints before accepting the value.
Re:Golang generics proposal has been accepted by baby on Wednesday February 10, 2021 @03:32PM (#26094353)
Golang needed sum types (for options) and match statements (python got it after all...) way before it needed generics. CHANGE MY VIEW.
Re:Golang generics proposal has been accepted by zeugmasyllepsis on Wednesday February 10, 2021 @03:39PM (#26094430)
Sum 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.
Re:Golang generics proposal has been accepted by cies on Wednesday February 10, 2021 @03:46PM (#26094536)
> 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.

Re:Golang generics proposal has been accepted by sdfsfsf3kjdf on Wednesday February 10, 2021 @04:12PM (#26094877)
How 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.
Re:Golang generics proposal has been accepted by alecbz on Wednesday February 10, 2021 @05:48PM (#26095871)
It could have been built in to the language. Tons of builtin features (slices, maps, channels) are already "generic".
Re:Golang generics proposal has been accepted by baby on Thursday February 11, 2021 @06:14PM (#26108806)
This
Re:Golang generics proposal has been accepted by cies on Wednesday February 10, 2021 @03:37PM (#26094408)
Yes. 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.

Re:Golang generics proposal has been accepted by jasperry on Wednesday February 10, 2021 @03:47PM (#26094543)
Wait, 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.
Re:Golang generics proposal has been accepted by sdfsfsf3kjdf on Wednesday February 10, 2021 @03:50PM (#26094579)
> 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.

Re:Golang generics proposal has been accepted by cies on Wednesday February 10, 2021 @03:55PM (#26094653)
Really? 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?
Re:Golang generics proposal has been accepted by sdfsfsf3kjdf on Wednesday February 10, 2021 @04:01PM (#26094744)
> 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.

Re:Golang generics proposal has been accepted by shakow on Wednesday February 10, 2021 @07:10PM (#26096591)
No, 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.

Re:Golang generics proposal has been accepted by floxy on Wednesday February 10, 2021 @05:46PM (#26095861)
There 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/Ad_hoc_polymorphism

https://wiki.haskell.org/Generics

Re:Golang generics proposal has been accepted by eeperson on Wednesday February 10, 2021 @03:44PM (#26094512)
I 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).
Re:Golang generics proposal has been accepted by merb on Wednesday February 10, 2021 @04:34PM (#26095136)
btw. 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/expl...
Re:Golang generics proposal has been accepted by dragonwriter on Thursday February 11, 2021 @01:16PM (#26105106)
Python 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.
Re:Golang generics proposal has been accepted by coder543 on Wednesday February 10, 2021 @03:36PM (#26094406)
> 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
Re:Golang generics proposal has been accepted by cies on Wednesday February 10, 2021 @03:39PM (#26094436)
When 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).

Re:Golang generics proposal has been accepted by coder543 on Wednesday February 10, 2021 @03:43PM (#26094487)
You 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.

Re:Golang generics proposal has been accepted by cies on Wednesday February 10, 2021 @04:03PM (#26094771)
> I wish that Go would adopt Sum Types

And then make a Maybe sum type? But then it is too late as the std lib communicates with nils instead of Maybes

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

I'm not doing this, I'm using an API that does! I cannot choose what some code returns, all I can do is --sigh-- add another null guard.

If it is my discipline to add null guards or have runtime explosions I consider the nulls to be implicit.

That you find as much runtime problems with unwrap/expect in Rust (which have a lot of red tape on them in API docs) as with "missing null guards" in Go, is great for you, but to me that does not make it a good design choice in Go.

Re:Golang generics proposal has been accepted by coder543 on Wednesday February 10, 2021 @04:05PM (#26094790)
> If it is my discipline to add null guards or have runtime explosions I consider the nulls to be implicit.

But they're still explicit nulls.

You seem to be saying that only implicit nulls require null guards, but that's just not what that means (as far as I have learned).

You seem to hate nullability as a concept, which is fine, but that's different from hating implicit nullability.

> That you find as much runtime problems with unwrap/expect in Rust (which have a lot of red tape on them in API docs) as with "missing null guards" in Go, is great for you, but to me that does not make it a good design choice in Go.

It's also a comment on how NPEs are just not a common hazard in Go compared to my past experiences with Java, especially when combined with good editors and linters.

Re:Golang generics proposal has been accepted by wtetzner on Wednesday February 10, 2021 @04:13PM (#26094897)
> But they're still explicit nulls.

Except that there may be other reasons to use pointers than just nullability. And in that case, there's no mechanism to specify whether or not the thing being pointed to is nullable.

I think that's where the implicitness in question comes in.

Re:Golang generics proposal has been accepted by cies on Thursday February 11, 2021 @02:52AM (#26099260)
Explicit to me is when I can see from the return type it is or isnt nullable AND that i have to deal with the null case explicitly (so nullableUser.lastName() errors out as I cannot call lastName() on null).

But I might well be mistaken.

Re:Golang generics proposal has been accepted by shric on Wednesday February 10, 2021 @03:54PM (#26094634)
> Go doesn't even implicitly de-reference things

Except when accessing a field via a pointer to struct.

https://tour.golang.org/moretypes/4

Re:Golang generics proposal has been accepted by creata on Wednesday February 10, 2021 @03:51PM (#26094595)
I don't like your definition of "implicit nullability". Following that logic, Java integers can't be null either, and C has no implicit nullability! In practice, when we say we don't want implicit nullability, we mean that we want nonnullable everything, including pointers. After all, Tony Hoare called null references his billion dollar mistake.
Re:Golang generics proposal has been accepted by cies on Wednesday February 10, 2021 @04:08PM (#26094823)
If I return a struct pointer in C, I can also return null. The return type does not communicate this to me: this is what I call implicit nullability.

It is just a bad contract, as it is often misunderstood, and it allow for runtime errors that could easily have been caught at compile time.

Re:Golang generics proposal has been accepted by coder543 on Wednesday February 10, 2021 @03:54PM (#26094627)
That's not implicit nullability, in my opinion.

I agree that non-nullable references are wonderful, and Go will probably have to grapple with that eventually. I just don't want people to get the wrong idea. Go has value types -- not everything is a reference that is implicitly nullable.

C isn't implicitly nullable, you are correct.

Re:Golang generics proposal has been accepted by creata on Wednesday February 10, 2021 @04:03PM (#26094760)
I feel like we're just using different definitions of implicit nullability, and by your definition, no language with value types is implicitly nullable, whereas by my definition, every language without nullable references is implicitly nullable. I think your definition is bad and uncommon, but that's not a very fruitful line of discussion.
Re:Golang generics proposal has been accepted by coder543 on Wednesday February 10, 2021 @04:09PM (#26094840)
You're referring to how some languages have non-nullable references, which is fine. That's probably a better term to be using, since it is more clearly defined and less contentious in this discussion.

I agree that Go should consider adopting non-nullable references.

Re:Golang generics proposal has been accepted by p2detar on Wednesday February 10, 2021 @03:47PM (#26094547)
Putting 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.

Re:Golang generics proposal has been accepted by cies on Wednesday February 10, 2021 @03:53PM (#26094618)
Plenty 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.

Re:Golang generics proposal has been accepted by andreygrehov on Thursday February 11, 2021 @01:12PM (#26105067)
What 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).
Re:Golang generics proposal has been accepted by dragonwriter on Thursday February 11, 2021 @01:14PM (#26105091)
> 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.

Re:Golang generics proposal has been accepted by andreygrehov on Thursday February 11, 2021 @01:25PM (#26105231)
What would be a better design?
Re:Golang generics proposal has been accepted by dragonwriter on Thursday February 11, 2021 @02:36PM (#26106063)
Statically 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.

Re:Golang generics proposal has been accepted by Arnavion on Wednesday February 10, 2021 @03:20PM (#26094170)
A more apt comparison is TypeScript to JavaScript, perhaps. Kotlin and Java interop at the bytecode level, but Golang doesn't have that. Gotlin would have to compile to Golang with the same shimming hairiness as TS downleveling to JS.
Re:Golang generics proposal has been accepted by cies on Wednesday February 10, 2021 @03:26PM (#26094267)
Well spotted. Though typescript does not fix some of the biggest horrors of JS. Interop is really good as one would expect.
Re:Golang generics proposal has been accepted by mssundaram on Wednesday February 10, 2021 @03:47PM (#26094549)
I'd say it depends on how you tune your tsconfig and linting. You can really crank all the knobs avoid nearly all of the JS pitfalls
Re:Golang generics proposal has been accepted by cies on Wednesday February 10, 2021 @04:11PM (#26094868)
Agreed. But this is not very beginner friendly (sadly JS is more and more the first lang being taught), and is not an example of great design.
Re:Golang generics proposal has been accepted by AlphaSite on Wednesday February 10, 2021 @04:00PM (#26094730)
Considering that go is only really used in a statically compiled context, thats not really necessary.
Re:Golang generics proposal has been accepted by lordofgibbons on Wednesday February 10, 2021 @03:12PM (#26094077)
Will it requires a VM to run?

Also, how fast will this language build large projects?

Re:Golang generics proposal has been accepted by cies on Wednesday February 10, 2021 @03:18PM (#26094139)
It will be like Go: no VM. And have great interop with Go!

> Also, how fast will this language build large projects?

Slightly slower.

I wonder what the implementation of generics will do to Go's otherwise stellar compile times. A code base heavily using generics can easily be double the compile time. Not sure how this will be sold, probably "but then simply do not use it!"

Re:Golang generics proposal has been accepted by erik_seaberg on Wednesday February 10, 2021 @03:41PM (#26094458)
I'm made out of meat, the compiler is always going to be millions of times faster than that. Are generics actually slower than codegen plus parsing the same method body over and over with different types?
Re:Golang generics proposal has been accepted by cies on Wednesday February 10, 2021 @04:12PM (#26094887)
> meat

Flesh to me. (vegan) :)

Re:Golang generics proposal has been accepted by erik_seaberg on Wednesday February 10, 2021 @04:35PM (#26095157)
Re:Golang generics proposal has been accepted by cies on Thursday February 11, 2021 @02:58AM (#26099286)
Thanks for the reference. I chuckled :)
Re:Golang generics proposal has been accepted by pier25 on Wednesday February 10, 2021 @03:43PM (#26094500)
For a brief moment I read Goblin