4 ms·
"Go does not support operator overloading or keyword extensibility." Very much working as intended, I believe. Experience from languages that support those fea
by fixermark 11y ago
"Go does not support operator overloading or keyword extensibility."
Very much working as intended, I believe. Experience from languages that support those features has shown that what we gain in the very few situations where those extensions make sense (such as defining mathematical operations on vectors using the same symbols that are used in vector mathematics), we lose in too many developers thinking they have a clever shortcut that an existing operator would be perfect for, to the detriment of readability and comprehensibility.
This is also the era of code-analysis-by-search-engine, and operator overloading harms that feature significantly. If I need to find all instances of vector addition in my code and I'm searching for '+', I'm going to have a bad time.
- cmrdporcupine 11y agoI agree that operator overloading is probably a feature not wanted in a language with this target problem domain. However "working as intended" I think is also the response of Go to their lack-of-generics, which I think is kind of crap.
- gendoikari 11y agoAbout generics, this is highly debatable. This is a design choice, it's not a decision made by accident. You'll surely gonna have boilerplate code in some cases, but all the language will be a lot more readable, and simple. Simplicity it's the most wanted feature of Go, from the designers perspective, I think. In the long term it's preferable to have explicit and simple code, instead of complex magic. This is a correct view? We'll see. Honestly I'm starting to appreciate that. They may have a good point.
- moultano 11y agoWithout generics, you can never write a type safe datastructure. I can't imagine the hubris that thinks the language already contains all of the datastructures it needs.
- kyledj 11y agoThis isn't true. You can write a type safe data structure. It is simply for one type; you can't share it. That inability to share is the part that generics fixes, but saying you can't write type safe structures is inaccurate.
- mercurial 11y agoHow is code with generics more complex than without it?
- rbjorklin 11y agoThey're talking about the compiler and the language spec not Go code.
- mercurial 11y agoThat's not how I interpret parent's comment.
- gendoikari 11y agoFor example the C++ templates rules are themselves a turing-complete language. If by generics you meant some really basic features, I think you can do pretty well with interfaces. They're already in the language. If by generics you meant the full-package, i think you could end up with something pretty complex all the time.
- mercurial 11y agoMost generic implementations are not Turing-complete, and looking at C++, this doesn't sound like a particularly tempting proposition. And while I'm not particularly familiar with Go, I don't see how you can get a feature set equivalent to a simple implementation like Java's out of Go interfaces ("you can just cast" is not a good answer).
- gendoikari 11y agoI'm probably missing the use case. What is the problem that you are thinking of, you can't solve with a Go interface?
- mercurial 11y agoSay, a generic container.
- TuringTest 11y ago> all the language will be a lot more readable, and simple. Simplicity it's the most wanted feature of Go This is what Java designers thought as well. See where this has led them.
- deleted 11y ago[deleted]
- omginternets 11y ago>I think is also the response of Go to their lack-of-generics, which I think is kind of crap. The response I've overwhelmingly observed from qualified voices isn't "boo generics!" but "generics are terribly difficult to get right, and we want to know more about Go's niche before making any design decisions in that realm". I suspect you're reading a lot of drivel from web programmers who discovered net/http last Thursday. It's hard not to be frustrated with the internet, I concede...
- TillE 11y agoA huge variety of other languages have successfully implemented generics. The Go team seems to be looking for some mythical ideal solution with no tradeoffs, and will therefore never do it.
- omginternets 11y ago>A huge variety of other languages have successfully implemented generics Completely irrelevant; the argument isn't "generics are hard [full stop]". The argument is "generics are hard" AND "we don't know Go's niche well enough to commit to any specific approach".
- mike_hearn 11y agoBut how can they not know that, after so many years?
- omginternets 11y agoYou'd have to ask them, but I suppose it takes years to carve out a niche. What I can say is that I recently interviewed a Google engineer who was conducting a survey of Go's usage, so it seems they're at least studying the question.
- thegeekpirate 11y ago> However "working as intended" I think is also the response of Go to their lack-of-generics, which I think is kind of crap. Where the hell did you get that from? https://news.ycombinator.com/item?id=9622417 https://news.ycombinator.com/item?id=9622417
- necessity 11y agoAgreed. Explicit is better than implicit in this case (and most, if not all, cases).
- masklinn 11y agoOperators are no more or less explicit than functions or methods. "+" and "Add" are just as explicit. A difference is that operators tend to have semantic baggage, which can be a huge boon when using operator overloading for e.g. calculations. C++ has demonstrated that it was a very bad idea to overload operator against their semantic baggage, but the lesson to draw from it is "don't do that" not "operator overloading is the devil".
- pcwalton 11y ago> If I need to find all instances of vector addition in my code and I'm searching for '+', I'm going to have a bad time. This is true of methods too. If you're searching for vector addition and you grep for "Add()", you're also going to have a bad time. To have a reliable code indexing scheme, you need typechecking/name resolution information, and once you have that you can easily handle operator overloading as well.
- fixermark 11y agoThe difference is that "Add" is not a term that many search engines will drop on the floor. When you get out of the range of plain ASCII strings, you're leaving the range of symbols you can assume your tool of choice will be indexing into search for you. This is likely a short-term reality, but it's the current reality.
- pcwalton 11y agoHow many code indexing tools are in use that aren't grep/ack/ag (because you can grep for +) and don't do semantic analysis? I can't think of any. Visual Studio, DXR (what I've used), all documentation tools, etc. can all handle overloaded operators, and have been able to for years. (Hasn't Visual Studio been able to index overloaded operators for, like, at least a decade?)
- fixermark 11y agogithub.com
- pcwalton 11y agoThat's fair. Though I've always found GitHub's code search to be less than useful in general. I think it doesn't really make sense to not have overloading because GitHub doesn't support semantic indexing in 2015, especially since you can easily just not use GitHub for code search.
- 11y ago
- ltbarcly3 11y ago>> Experience from languages that support those features has shown that what we gain in the very few situations where those extensions make sense Nope, this is just incorrect. The C++ is completely dominant in large swaths of the software industry largely because operator overloading allows the writing of generic algorithms (which allows you to write large scale software without losing C-like performance). Without operator overloading, it is much harder to write a function that can be specialized on types that weren't specifically designed for such use. In Python, Numpy, the Decimal class, I could really give examples for days of cases where operator overloading is essential. Go doesn't have it, Go doesn't have a lot of things, and Go will always be an also-ran language that isn't adopted outside of a very narrow domain. The fact that built in types are 'special' and only they can support operators such as [] is enough for me to avoid the language. The complete lack of generic programming is more than enough.
- fixermark 11y agoI think we're talking about different things. Can you give an example of how operator overloading improves one's ability to write a function that can be specialized on types that weren't specifically designed for such use?
- justin_vanw 11y agoType 1 defines: .add(x) Type 2 defines: .plus(x) Type 3 defines: .vector_add(x) Now, implement a function 'average' that can work on any of these three types. If you can get everyone in the world to agree to a convention of how to express 'addition', then there is no difference, except we already have a convention for 500 years, and it is the '+' operator. Why you think the '+' operator is confusing but .plus() is not, that is what confuses me. Or how about 'minimum'. In C people end up writing a minimum C macro, because there's not even a way to write one function that works on int, long, float! What a sad world that is, where you have to meta program to implement min(x,y).
- coldpie 11y ago> Now, implement a function 'average' that can work on any of these three types. I'm not convinced this is such a large problem that its solution is worth the myriad downsides that operator overloading is chained to. There's lots of schoolbook examples like this, but I've almost never seen operator overloading used well in practice. There's a few examples, like boost shared pointers are somewhat easier to read, but they're few and far between
- coldpie 11y agoThis is a well-written objection and I completely agree. Operator overloading is consistently one of the worst ideas I see in programming languages, C++ being the prime offender. Programmers think they're being clever when they write crap like boostfs::path path("/some/path"); path /= "yourfile.txt"; Meanwhile, reading your code without being familiar with boostfs::path, my brain grinds to a halt while I try to understand what in the hell dividing by a string is supposed to do. This is one of those "well intentioned" features that turns into a quagmire in practice.
- masklinn 11y ago> Operator overloading is consistently one of the worst ideas I see in programming languages Except when not having it is the worst. Working with BigDecimal in Java is hell because it does not have operative overloading, meaning while you avoid boostfs::path path("/some/path"); path /= "yourfile.txt"; you get saddled with bullshit like x.add(x.add(ONE).pow(2).subtract(x))
- coldpie 11y agoEh, there's already no language symbols for exponentiation (unless you're really going to overload XOR in which case you're already part of the problem).
- masklinn 11y ago`.pow` is the least problematic part of my example by a fairly long shot. Even keeping it, with operator overloading you'd get x + ((x + ONE).pow(2) - x) or x + (pow(x + ONE) - x)
- pcwalton 11y agofunc SameSideOfTriangle<N>(p0 Point2D<N>, p1 Point2D<N>, a Point2D<N>, b Point2D<N>) bool where N: Number { ba := Point2D(b.x.Sub(a.x), b.y.Sub(a.y)) p0a := Point2D(p0.x.Sub(a.x), p0.y.Sub(a.y)) p1a := Point2D(p1.x.Sub(a.x), p1.y.Sub(a.y)) cp0 := ba.x.Mul(p0a.y).Sub(p0a.x.Mul(ba.y)) cp1 := ba.x.Mul(p1a.y).Sub(p1a.x.Mul(ba.y)) dot := cp0.x.Mul(cp1.x).Add(cp0.y.Mul(cp1.y)) return dot >= 0 } Versus: func SameSideOfTriangle<N>(p0 Point2D<N>, p1 Point2D<N>, a Point2D<N>, b Point2D<N>) bool where N: Number { ba := Point2D(b.x - a.x, b.y - a.y) p0a := Point2D(p0.x - a.x, p0.y - a.y) p1a := Point2D(p1.x - a.x, p1.y - a.y) cp0 := ba.x * p0a.y - p0a.x * ba.y cp1 := ba.x * p1a.y - p1a.x * ba.y dot := cp0.x * cp1.x + cp0.y * cp1.y return dot >= 0 }
- habitue 11y agoThe way Haskell and rust solve this is that they constrain the types of the overload. If you want to overload +, you implement the Add trait, which has to be a certain type. The Add trait is googleable, and it provides a hint as to how the operator is to be used. In practice Rust and Haskell have much less of a problem than C++ in this respect. Additionally, having a strong culture helps (which Go obviously does). Python has no restrictions on overloading, but it's much less abused than in C++ because there's a cultural aversion to making operators do crazy stuff
- BinaryIdiot 11y agoWhile I think your point about using them improperly is good (I know I've seen some weird shit back in the day I did C++) I still think there is merit to allowing operator overloading. Many times you may create units that should work when added together but need unique logic to make it happen and that just can't happen in GO today (you have to make an add() method or something similar). So I think operator overloading can be exploited pretty horribly but can also make code far more intuitive. It's certainly not something that can't be worked around but I always err on the side of letting it happen and the community can direct people to using them most properly.