Live data from Hacker News

Replacing Clever Code with Unremarkable Code in Go

vividcortex.com

121–130 of 140 posts

Re: Replacing Clever Code with Unremarkable Code in Go

#121
post #114
post #106

Earlier quoted context omitted.

> 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 fo…

The 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 susp…

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

Re: Replacing Clever Code with Unremarkable Code in Go

#122
post #44

http://www.paulgraham.com/avg.html Programmers get very attached to their favorite languages, and I don't want to hurt anyone's feelings, so to explain this point I'm going to use a hypothetical language called Blub. Blub falls right in the middle of the abstractness continuum. It is not the most powerful language, but it is more powerful than Cobol or machine language. And in fact, our hypothetical Blub programmer w…

I think this basically nails the attitude of every single go convert that I have spoken to. I am starting to get tired of hearing lines like "that lisp stuff is too complicated, I am a go programmer" or "why would you do x in y way, it's so much better in go". I don't think I have ever seen such unrelenting fanboyism in a programming language. It very well may be a fantastic language but its not an end all be all, we…

I'm a Go convert. And I have learned and understood the concepts of a lot of other programming languages before, including Haskell, Scala, Rust, C++, Scheme, Common Lisp, Smalltalk, Ruby, Python, Perl, PHP, Lua, JavaScript, Groovy, CoffeeScript, Dart, Java, C#, Objective C, C, Pascal, Basic. I understand higher-order functions, currying and sectioning, parametric polymorphism, monads (including the option/maybe monad), product and sum types, pattern matching, multiple dispatch, meta-programming etc. Yes, Go lacks most of these, it's a "dull", imperative programming language without parametric polymorphism or an ML-style type system (which is not "modern", btw, it's from the early 70s just like C) and with nil pointers. Nonetheless, Go is the most enjoyable programming language I've ever used. It strikes the right balance between features and their cost. I'm tired of being told that I'm just too stupid to see the light.

Re: Replacing Clever Code with Unremarkable Code in Go

#123
post #120
post #119

Earlier quoted context omitted.

So "right" Go code ignores checking references that can be null so that it can blow up at run time? That can't be safe.

No, it's just that's not how it works. For instance, s, err := server.New() if err != nil { // handle error } s.Foo() You're not going to check that s != nil before calling s.Foo, even though s is probably a *server.Server and could be nil. But it won't be, if the New function is correct. Yes, the compiler doesn't guarantee that New gives you a non-nil pointer, but it also doesn't guarantee a lot of things about the…

I was mainly referring to function arguments. Any function that takes a pointer type has to have null checks at the beginning, since any of the pointer arguments may be null.

Re: Replacing Clever Code with Unremarkable Code in Go

#124
post #118
post #117

Earlier quoted context omitted.

The 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 referen…

What I get from your comment is that option types work well in Haskell and Scala. This doesn't surprise me, as both languages places a strong emphasis on the type system, and so they are easily supported. For option types to work well in Go you would need to add more support to the type system. But we don't want a more complex type system. That's a tradeoff we made. Again, I'm not really sure why people keep getting…

I can't speak about the others. However, I feel that we have reached an unfortunate state in the industry when a sub-par technology starts to get picked up because of brand names, and not on inherent merits.

Re: Replacing Clever Code with Unremarkable Code in Go

#125
post #123
post #120

Earlier quoted context omitted.

No, it's just that's not how it works. For instance, s, err := server.New() if err != nil { // handle error } s.Foo() You're not going to check that s != nil before calling s.Foo, even though s is probably a *server.Server and could be nil. But it won't be, if the New function is correct. Yes, the compiler doesn't guarantee that New gives you a non-nil pointer, but it also doesn't guarantee a lot of things about the…

I was mainly referring to function arguments. Any function that takes a pointer type has to have null checks at the beginning, since any of the pointer arguments may be null.

"has to" is a bit strong. The standard assumption is that pointer arguments should be set (or the function is documented otherwise), and the responsibility is left with the caller. It just bubbles out from there.

Re: Replacing Clever Code with Unremarkable Code in Go

#126
post #75

Earlier quoted context omitted.

The built-in collections can remain built-in if that gets you off. Same deal for manually specialized collections, except those aren't generic, so they remain not generic.

I think those are both rather bad solutions; I want generics precisely because they can provide equal performance to the built-in collections without the obvious drawbacks of a limited set of primitives or manually copying code. I'm just saying that "very little compiler costs and little to no runtime costs" is somewhat misleading, because there are significant runtime costs compared to those alternatives; Go needs c…

> I want generics precisely because they can provide equal performance to the built-in collections

That is most definitely not the core use case for generics. They can be lifted into type-specialized collections, but the core point of generics is type safety.

Re: Replacing Clever Code with Unremarkable Code in Go

#127
post #118
post #117

Earlier quoted context omitted.

The 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 referen…

What I get from your comment is that option types work well in Haskell and Scala. This doesn't surprise me, as both languages places a strong emphasis on the type system, and so they are easily supported. For option types to work well in Go you would need to add more support to the type system. But we don't want a more complex type system. That's a tradeoff we made. Again, I'm not really sure why people keep getting…

> What I get from your comment is that option types work well in Haskell and Scala. This doesn't surprise me, as both languages places a strong emphasis on the type system, and so they are easily supported.

Option types need no type system support beyond having option types at all. Think of an option type as a container. It's either empty, or it has a single element inside it.

You can manipulate your container by checking if it's empty, getting the value out, manipulating the value and putting the value in a new collection. That's the basic low-level primitives of interacting with an option type.

And you can also use higher-order operations, e.g. map over the collection which will only "do things" if there's a value and will just return an empty collection if there isn't. These are the higher-level combinators on option types. They require no type system complexity outside of having option types in the first place.

Re: Replacing Clever Code with Unremarkable Code in Go

#128
post #75

Earlier quoted context omitted.

I think those are both rather bad solutions; I want generics precisely because they can provide equal performance to the built-in collections without the obvious drawbacks of a limited set of primitives or manually copying code. I'm just saying that "very little compiler costs and little to no runtime costs" is somewhat misleading, because there are significant runtime costs compared to those alternatives; Go needs c…

> I want generics precisely because they can provide equal performance to the built-in collections That is most definitely not the core use case for generics. They can be lifted into type-specialized collections, but the core point of generics is type safety .

Fair enough. Although my priorities somewhat differ from the norm, the document you criticized elsewhere does cite runtime overhead as a significant obstacle.

Re: Replacing Clever Code with Unremarkable Code in Go

#129

Earlier quoted context omitted.

Great essay, but Shaw is mistaken about one thing: our art is old enough indeed. Unix and C in particular were created precisely as he describes.

I don't think Unix is quite what he had in mind. Not all simplicity comes from mastery.

But Unix did, specifically from hard lessons learned from the failure of Multics. Sure, we now know some aspects of Unix to be suboptimal design, but that's with further decades of collective experience and even today the right answers are not yet entirely clear.

Re: Replacing Clever Code with Unremarkable Code in Go

#130
post #118
post #117

Earlier quoted context omitted.

The 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 referen…

What I get from your comment is that option types work well in Haskell and Scala. This doesn't surprise me, as both languages places a strong emphasis on the type system, and so they are easily supported. For option types to work well in Go you would need to add more support to the type system. But we don't want a more complex type system. That's a tradeoff we made. Again, I'm not really sure why people keep getting…

I disagree with you on the relative complexity of type systems, and, as someone passionate about my craft, I despair Go is merely good not great, due to what appears to be uninformed design decisions.

You may prefer to write in Go, but you don't work in a vacuum. Your creation is out there, gaining mindshare, and propagating mistakes made half a century ago. As a language designer, you have the power to shape human thought for years to come, and the responsibility to remain intellectually honest. This is the meaning of Hoare's apology. He didn't know better. You have no such excuse.

Post reply on HN