Live data from Hacker News

Replacing Clever Code with Unremarkable Code in Go

vividcortex.com

101–110 of 140 posts

Re: Replacing Clever Code with Unremarkable Code in Go

#101

For the love of Thor, please provide a few code examples illustrating the content, hard to get an idea of how to simplify things with Go with mere words and ideas.

Definitely. I'm left with no idea how Go actually helps. You can trivially implement 'pipelines' in any language by making a handful of queue structures and using them to feed your functions. Why were there callbacks in the first place?

My thought exactly. The whole thing strikes me as a case of: Have a hammer and everything looks like a nail. First with callbacks, and second with channels.

Re: Replacing Clever Code with Unremarkable Code in Go

#102
post #73

Earlier quoted context omitted.

> He expanded on this dilemma with examples from major languages: http://research.swtch.com/generic My god, this is such completely dishonest bullshit strawman I'm impressed he had the balls to post that garbage. Java's boxing does not come from its generics, it's the other way around (java's non-Array collections have never been able to hold unboxed values), and C++'s template are pretty much unique in their complex…

I'm super pro generics and love me some Haskell and ML. However, generics really do have a cost. Since the size of the objects in a generic container can vary, you either need to take the ML route of making everything a pointer (which add runtime cost) or the C++ (yeah, not really generics, but still) route of duplicating the code for every size object you store in the container. While I think Go made the wrong choic…

I'm curious what the cost would be of implementing generics by having an (implicit) parameter for the element size. It would certainly be a bit slower than the fully specialized version, but it avoids boxing and doesn't duplicate code.

Re: Replacing Clever Code with Unremarkable Code in Go

#103

Earlier quoted context omitted.

Reminds me of this old Zed Shaw essay: http://zedshaw.com/essays/master_and_expert.html I think at least two of Go's designers, Ken Thompson and Rob Pike, are true programming masters. Note: When I posted this comment before, I accidentally pasted the wrong URL.

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.

Re: Replacing Clever Code with Unremarkable Code in Go

#104
post #98
post #86

So, Go has message passing. Just like Erlang, since 1986. Only without per-process heaps, which make crashing processes safe. And without process linking and supervision, which helps systems built using Erlang/OTP achieve nine nines of uptime. Instead, it includes null references, also known as Hoare's Billion Dollar Mistake. But it's not enough to scorn the industry; Go's designers also look down their noses at acad…

Erlang and Go are very different programming languages. They have a similar form of message passing, but the semantics are very different. Go's concurrency model still exists within a single process with a shared heap, which is very different to Erlang's model. > it includes null references, also known as Hoare's Billion Dollar Mistake. The very notion of null references being inherently bad is highly contentious. Ju…

> Go's concurrency model still exists within a single process with a shared heap, which is very different to Erlang's model.

I've already mentioned Go doesn't have per-process heaps, and I consider this a step backwards from shared-nothing message passing.

I don't understand how can you argue that facilitating the threads-and-locks model leads to "simple code that is obviously correct". Writing correct multithreaded code is widely recognized to be difficult.

> The very notion of null references being inherently bad is highly contentious.

If by this you mean people keep[1] pointing[2] out[3] the problems with nulls, and other people keep ignoring them, then I fully agree. Otherwise, please direct me to a discussion offering a pro-null argument.

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.

Alternatively, in a language with option types, only values explicitly marked as optional must be checked, and forgotten checks are pointed out by the compiler. Less code, more safety.

Tell me again, how does allowing null references lead to "simple code that is obviously correct"?

> If you don't have null pointers or [do have] generics, then you need a more complex type system.

Certainly. More complexity for the language implementers; less complexity for the language users.

1. http://qconlondon.com/london-2009/presentation/Null+Referenc...

2. http://www.dcs.warwick.ac.uk/~hugh/TTM/TTM-TheAskewWall-prin...

3. http://www.ccs.neu.edu/racket/pubs/dissertation-cobbe.pdf

Re: Replacing Clever Code with Unremarkable Code in Go

#105
post #104
post #98

Earlier quoted context omitted.

Erlang and Go are very different programming languages. They have a similar form of message passing, but the semantics are very different. Go's concurrency model still exists within a single process with a shared heap, which is very different to Erlang's model. > it includes null references, also known as Hoare's Billion Dollar Mistake. The very notion of null references being inherently bad is highly contentious. Ju…

> Go's concurrency model still exists within a single process with a shared heap, which is very different to Erlang's model. I've already mentioned Go doesn't have per-process heaps, and I consider this a step backwards from shared-nothing message passing. I don't understand how can you argue that facilitating the threads-and-locks model leads to "simple code that is obviously correct". Writing correct multithreaded…

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

Re: Replacing Clever Code with Unremarkable Code in Go

#106
post #105
post #104

Earlier quoted context omitted.

> Go's concurrency model still exists within a single process with a shared heap, which is very different to Erlang's model. I've already mentioned Go doesn't have per-process heaps, and I consider this a step backwards from shared-nothing message passing. I don't understand how can you argue that facilitating the threads-and-locks model leads to "simple code that is obviously correct". Writing correct multithreaded…

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

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

Re: Replacing Clever Code with Unremarkable Code in Go

#107
post #86

So, Go has message passing. Just like Erlang, since 1986. Only without per-process heaps, which make crashing processes safe. And without process linking and supervision, which helps systems built using Erlang/OTP achieve nine nines of uptime. Instead, it includes null references, also known as Hoare's Billion Dollar Mistake. But it's not enough to scorn the industry; Go's designers also look down their noses at acad…

Is your criticism of Go based on actual experience using it, or simply the fact that it lacks certain features that you deem critical in a modern programming language?

Re: Replacing Clever Code with Unremarkable Code in Go

#108
post #86

So, Go has message passing. Just like Erlang, since 1986. Only without per-process heaps, which make crashing processes safe. And without process linking and supervision, which helps systems built using Erlang/OTP achieve nine nines of uptime. Instead, it includes null references, also known as Hoare's Billion Dollar Mistake. But it's not enough to scorn the industry; Go's designers also look down their noses at acad…

Is your criticism of Go based on actual experience using it, or simply the fact that it lacks certain features that you deem critical in a modern programming language?

I enjoy using Go, otherwise I wouldn't waste energy discussing it.

Re: Replacing Clever Code with Unremarkable Code in Go

#109
post #106
post #105

Earlier quoted context omitted.

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

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

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

Re: Replacing Clever Code with Unremarkable Code in Go

#110
post #109
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…

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

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

Post reply on HN