6 ms·
I don't like this at all. This is a classic example of a feature where, in the right hands its very powerful, but in the wrong hands it will ruin the simplicity
by 013a 7y ago
I don't like this at all. This is a classic example of a feature where, in the right hands its very powerful, but in the wrong hands it will ruin the simplicity of the logic it touches. Go's magic was really in its ability to be placed in the wrong hands and still end up with a serviceable program.
- dgellow 7y agoI've seen wrong hands doing terrible things with combinations of `interface{}` and reflections!
- stcredzero 7y agoThis has been a story in programming for literally decades.
- ailideex 7y agoI find the position that the real solution to incompetence is to just give people blunt knives to be utterly unsatisfactory. If someone cannot understand how exceptions work for example I have a hard time seeing how removing this massive burden from their minds will result in good outcomes. Being easy to use for people that probably would be better off doing something else is not a solid design principle. Java went down this route, ah, we will remove operator overloading, that will make it simpler, because nobody can ever write a function named equals which does not do what you expect it to... and the end result is horrible and does not prevent people from doing amazingly dumb things.
- tfha 7y agoAs a reliability engineer I disagree. It's nice to know that your code has few antipatterns in it by design. "Blunt knives" is a really bad way to think about it. You have plenty of very sharp knife, and they are easy to use and have clearly defined scope and purpose. A knife that's sharp and unweildly makes me nervous even in the hands of an expert. Keep unweildly constructions out of go!
- ailideex 7y ago> It's nice to know that your code has few antipatterns in it by design. But does making the language incredibly simplistic really do this? The way I see it some devs will have more antipatterns than other devs - and this will be the case even if you make the language as simplistic as possible. The solution here is not to make the language simpler, but to rather look at why people are using anti-patterns. > "Blunt knives" is a really bad way to think about it. Is it? Most of these things result in having to write more code and does not really prevent you from doing something stupid. I'm not even sure it reduces the surface area of all possible stupid things in a meaningful way. > Keep unweildly constructions out of go! What makes a construct unweildly?
- jerf 7y ago"Most of these things result in having to write more code and does not really prevent you from doing something stupid." I see this accusation a lot, but it does not manifest in my code after years of usage (and, yes, I know Haskell and am pretty good with it, so it is not a lack of knowledge of the possibilities). If you write Go in Go, it's a pretty good language for production code. It doesn't give you all the goodies, but it's got some stuff of its own that's pretty cool, like it's baby structural typing (I think it is still massively underestimated how useful this is in practice over languages that require you to declare conformance to an interface, this has major second- and third-order consequences to code bases), the syntactic ease of composition, and the select statement (channels on their own, meh, but put them in a select statement and they're very nice). On the whole I'd say it's usually a bit less slick than Python but noticeably more pleasant to work with than Java. If you, on the other hand, want to write Haskell in Go, or C++ in Go, or Javascript in Go, you're in for a bad time. Certainly from this angle Go is a nightmare. It's not a good idea in any language, but it's fatal in Go. (I'll also say it's hard to put a finger on all the details why, but it's a really easy language to refactor in. I've been handed 5,000-ish lines of "sorta OK code" from various code bases in Perl, Python, Go, and Java in my job, and of the four, Go is by far the easiest to go into and brush it up to a higher quality level.)
- stcredzero 7y ago
- Crinus 7y agoJava reversed that route around Java 5 when they added a crapton of language features (generics, annotations, autoboxing, enumerations, varargs, foreach) that considerably increased its complexity and made Java to not be just a very simple OOP language. Before that Java had very minimal changes in the language itself and all enhancements were on the library side. All the forces around (and especially outside but still influencing it) Go seem to push it alongside the same path. So far the Go designers are resisting bloating the language, but i wonder for how long that will be the case. There is this mindset that a language can never be good enough and stick with its existing features but instead it must always get new features - which ends on an inevitable bloat. This sort of need for featuritis is like locusts moving from one project to another.
- unscaled 7y agoI keep hearing this myth about how Java pre-5 used to be a pristine language, until it was touched by annotations and generics - and I doubt it, because I was there. Before annotations, Java libraries were basically using gigantic XML files to configure things like dependency injection and routing. I don't like the way Java libraries use exceptions at all, but you can't seriously say you want to get to the early J2EE days. Look at the mess that was required to create an Employee entity: https://docs.oracle.com/cd/A97688_16/generic.903/a97677/ejb11cmp.htm https://docs.oracle.com/cd/A97688_16/generic.903/a97677/ejb1... Before generics, foreach and autoboxing Java was code was littered with ugly code like this: List incrementIntList(List input) { List result = new ArrayList(); for (int i = 0; i < input.size(); i++) { Object obj = input.get(i); if (obj instance of Integer) { Integer int = (Integer)obj; int i = int.intValue() + 1; obj = new Integer(i); } result.add(obj); } return result; } While in Java 5 you could finally write: List<Integer> incrementIntList(List<Integer> input) { List result = new ArrayList<Integer>(); for (Integer i : input) { result.add(i + 1); } return result; } with Java 8, we even got arguably better: List<Integer> incrementIntList(List<Integer> input) { return list.stream().map(i -> i + 1); } I fail to see how the first version is more readable. Yes, the Java compiler had to become more complex to accommodate this, but every other Java codebase in existence became considerably simpler. I can't see how this is not a win. The forces pushing for the same kind of ergonomic improvements in Go are not outside forces, but very much the Go designers themselves. This draft your written by Ian Lance Taylor and Robert Griesemer and it looks like a complete overhaul of the contract mechanism proposed by Russ Cox. These people are part of the Go core team.
- logicchains 7y agoTo quote Rob Pike: >The key point here is our programmers are Googlers, they’re not researchers. They’re typically, fairly young, fresh out of school, probably learned Java, maybe learned C or C++, probably learned Python. They’re not capable of understanding a brilliant language but we want to use them to build good software. So, the language that we give them has to be easy for them to understand and easy to adopt. If Google, with its intensive algorithmic interviews, can't manage to hire people capable of understanding something like: func max(T: Comparable)(a, b T) { if a < b { return b } else { return a } } } And why we'd prefer that over having to rewrite the function for int8, int16, int32, int64, uint8, uint16..., then what hope is there for anybody else?
- ailideex 7y agoIf this is too complex for them to understand I would be really worried with "good software" they are building. I agree hiring good people is hard, but structuring your process for people that cannot understand the concept of Go Contracts may not be the optimal solution to this problem - at least in my view it is not.
- pjmlp 7y ago> If this is too complex for them to understand I would be really worried with "good software" they are building. Go have a look at all the Android architecture issues, rebooted at every IO, build performance problems and constant regressions in Android Studio. Or since we are on a Go thread, how the Kubernetes code actually looks like (they did a talk about it at FOSDEM).
- 013a 7y agoThe funny thing is; your code has a syntax error (two, actually). Its dumb to nitpick, but its symbolic of the problem; even if you're so sure that you have no mistakes, that what you've written is well designed and will work well... you're probably wrong. Even the simplest blocks of code will have issues, and the language should do everything it can to help this. No one likes to be told that all they deserve is a blunt knife, but frankly, it's more true than it isn't. I'll gladly wield that blunt knife if it means I get to build awesome products that don't break at 2am. (Edit) I made a mistake in my analysis of your code; there's actually three errors. Everyone makes mistakes. Our tools shouldn't encourage us to make more.
- apta 7y agoIt is an interesting problem to try to balance out. Java and C# are two very similar languages, but the latter decided to add so many different features into the language. It would be nice to do a study to see how people write code in those languages, and pick up existing code bases. I don't think operator overloading is the best example to give here. It can mask things to make it less clear what's going on. I think Kotlin strikes a good balance, where they overloaded math operators for things like `BigInteger` without going overboard. Other than that, Java has way more features than anything golang even hopes to offer. Golang literally dumbed down the language to such an extent that many people find it frustrating to work with. Whereas Java is getting some very cool features in the near future (pattern matching, record types, etc.)
- ailideex 7y ago> I don't think operator overloading is the best example to give here. It can mask things to make it less clear what's going on. I think Kotlin strikes a good balance, where they overloaded math operators for things like `BigInteger` without going overboard. What Kotlin does (AFAIK) is map operators to functions: https://kotlinlang.org/docs/reference/operator-overloading.html https://kotlinlang.org/docs/reference/operator-overloading.h... Kotlin allows us to provide implementations for a predefined set of operators on our types. These operators have fixed symbolic representation (like + or *) and fixed precedence. To implement an operator, we provide a member function or an extension function with a fixed name, for the corresponding type, i.e. left-hand side type for binary operations and argument type for unary ones. Functions that overload operators need to be marked with the operator modifier. Say I have a custom type that I want to be able to compare to other instances of the same type (>, <, ==, etc). Java gives you the Comparable interface and then you use the compareTo method. What prevents me from just also using this in a way that makes things less clear? If I need to support addition for my types (+) - I have to make some method, add(), but I can also similarly make an add method that does not do what someone expect it to. Sure, I should not, but you should also not use operators in that way, and you should not do many other dumb things. As long as a language is turing complete people will be able to do dumb things with it. The solution to this problem is not to make the language more verbose or blunt. The solution is to make the language more conducive to static analysis.
- munificent 7y ago> I find the position that the real solution to incompetence is to just give people blunt knives to be utterly unsatisfactory. I always think about it like this: When designing a tool, you can make one that prevents behavior from users on the low end of the bell curve, but only by also preventing behavior on the high end as well. I think about this a lot in the context of teaching. The kind of classes that ensure no child gets left behind also tend to prohibit any child from racing ahead.
- ailideex 7y ago> I always think about it like this: When designing a tool, you can make one that prevents behavior from users on the low end of the bell curve, but only by also preventing behavior on the high end as well. If both tools are turing complete then I'm not sure you can - and I would like to understand why people think it is possible - I have seen incompetent people do horrendous things in every language I have ever used. I think this whole avenue of trying to dumb down languages is a dead and and I think a much better option is to focus on making languages that allow more static analysis.
- d0100 7y ago> If someone cannot understand how exceptions work for example I have a hard time seeing how removing this massive burden from their minds will result in good outcomes. Most software doesn't need scientists, just bricklayers. And they must lay those bricks fairly easily and without making it undecipherable for their supervisors.
- AlexeySoshin 7y agoGo had no magic to begin with.