Maybe Mr. Pike actually has some well-deserved reputation when it comes to real-world software and engineering projects that are about handling large scale data in real time?
Maybe Mr. Pike actually has some well-deserved reputation when it comes to real-world software and engineering projects that are about handling large scale data in real time?
I think there is a tendency to create an unneccessary barrier between ”real-world” software and ”useless” academic theory. I’ve spent most of my career working with java, php, python and js, and I absolutely agree with Rob that class hierarchies and inheritance is a bad way to program, but there’s a lot more to types than oop type systems with limited type inference.
It’s of course always a trade off, which is why I build frontends in Elm, backends in Haskell and play with proofs in Agda, but why throw away types altogether?
Software that runs the world utilizes parametric polymorphysm in C++, Java, Ada, D, Swift, OCaml, Haskell etc, hell, even C [1].
I also tend to consider some mission critical Ada/C++ software a real engineering, not some webshit.
[1] https://github.com/jiixyj/libebur128/blob/master/ebur128/ebu...
What are the credentials to back this up? Otherwise, the languages he makes fun of actually are used to deliver large scale systems in real time. Google is built on C++ and Java, so are most of the other top tech companies, not to mention banks and HFT firms.
Compare to Leslie Lamport for instance, and the tremendous effect he had on large scale systems and software engineering correctness.
Or are you just being disrespectful?
When it comes to complexity, large systems tend to be complex, so you either push some of that complexity into your language, to give you expressiveness and modeling capability, or you simplify your language so much (golang) such that the code base becomes complex and verbose due to repetition, not to mention error prone.
Readability? Compare:
var a int
if foo() {
a = bar()
} else {
a = baz()
}
to final int a = foo() ? bar() : baz()
or even val a = if foo() { bar() } else { baz() }
the latter two are shorter by a factor of 6, clearer, and less error prone. This is a feature that both improves readability, and reduces complexity.The funny thing is, the golang code bases I worked with would be quite a bit shorter in a supposedly verbose language like Java, not to mention something like Kotlin.
Do you want a practical reason why golang is popular? Because it has Google behind its name. The language that he worked on before he was at Google, which were similar to golang, went nowhere.
Let it be said that I'm not actually a Go but a C programmer, and there might be about 1 legitimate use of this syntactic construct per few thousand lines in my code (you are free to checkout my language project from github and verify my claim). It's not that I don't know the construct, but more that most experiments with it end up being reverted again to the longer form, to preserve the rhyme and rhythm of my code.
I won't take sides, but I guess their idea was that like so many other features, this little syntactic sugar construct does not carry its own weight.
> I read the slides, but didn't hear the talk
You absolutely should hear it! The slides probably do not contain actual experience reports, opinions, and arguments.
> the golang code bases I worked with would be quite a bit shorter in a supposedly verbose language like Java
that's hard to believe. Any code samples for illustration? (I invite you to cherry pick!).
There's also something called "argument from fallacy". Either refute the points I raised, otherwise there's no point bringing up fallacies :)
> Let it be said that I'm not actually a Go but a C programmer,
I have been using golang at my current employer for several months now. That being said, that's your experience, and it doesn't necessarily mean that everyone else has your use case.
The shorter form is (1) more readable, and (2) less error prone - fact. Less code also means less room to make errors. It was pretty laughable on the golang mailing list when someone asked why there wasn't a max/min implementation for all number types in golang, someone replied why do you need it? You can just implement it yourself like so, and proceeded to write a max implementation where the comparison operator was flipped. It's quite ironic really.
> but I guess their idea was that like so many other features, this little syntactic sugar construct does not carry its own weight.
It does, it reduces the probability of error by making sure that assignment happens only once. They weigh things very arbitrarily, like how one of the golang authors doesn't think compile checked enums are worth it because hey, they're just enums checked by the compiler to ensure coverage. It shows they don't have experience with other languages, or with features that reduce error rates.
> that's hard to believe. Any code samples for illustration? (I invite you to cherry pick!).
I already listed the lack of a ternary operator or its equivalent, and this extends to other constructs which can be expressions. Java is getting switch expressions in the upcoming release, and in Kotlin, try/catch is an expression, it's quite nice. The most obvious other one is error handling, "if err != nil" checks everywhere, which makes the code base much longer.
Others include the lack of map/fold/etc functions. The code base I work with is littered all over the place with functions to do what effectively are maps or maps+filters. Those functions end up being 8 lines or so, whereas they could be fit in 1-2 lines, inline at the call site, without the reader having to jump to the function implementation. This gets tiring very quickly, and makes it take longer to understand the code at hand.
Another example is needing to explicitly assign to a temporary variable if you need to take its address to pass it as an argument.
a := foo()
b := bar()
c := baz()
qux(&a, &b, &c)
as opposed to for example Rust: qux(&foo(), &bar(), &baz());
or Java qux(foo(), bar(), baz()); 1. Rob Pike doesn't have a strong grasp of type theory.
2. Rob Pike is an accomplished programmer.
To me, this conflict of opinions is structurally indistinguishable from 1. That shape over there is a square.
2. That shape over there is blue.
IOW, there is no argument to see here.1. Go doesn't have generics because the authors didn't have strong grasp of type theory.
2. Go doesn't have generics, not from a lack of knowledge, but because the authors' real world software engineering experience had shown to them it wasn't important.
Though, in that case, I think the argument is more like:
1. That shape is equilateral
2. That shape is equiangular
It turns out it's a square. Rob Pike's public comments on the subject do seem to betray a weak grasp of actual type theory. Or at least one that is about as strong as it could ever get if your knowledge is primarily informed by practical experience with C++ or Java-style deeply broken type systems. But it's also true that Go's found an alternative approach that gets the job done. Or at least, gets the job done if you're writing the types of programs that he's writing.So, even with the alternative statement, I still see no argument here.
I have used Go extensively and would disagree with the idea that the lack of generics in go was ill-informed (and therefore a mistake). I find that Go's limited number of features leads to simpler libraries that are much easier to comprehend and use effectively. And in situations where I previously would have reached for generics I am forced to find a different approach and the end result is often better. Yes it does have its drawbacks and is not a perfect solution, but as far as engineering decisions go, I feel it was a successful one.
What do you mean by "real world software engineering experience", Acme or Plan9? These are silly academic projects with tens of installations at best.