36 ms·
Half a million lines of Go
- andrewfromx 5y agoi'm forced to work in Kotlin vs. Go sometimes at my job and I agree 100%, go is the best. Just a few items: 1) if thing vs if (thing) kotlin makes you add un-needed () 2) a string is always "" vs null! 3) you can follow the logic always 100% of the time vs. getting lost in a maze of clever kotlin.
- entire-name 5y agoIsn't item (3) more of a policy thing rather than a language thing? Granted, I actually never coded in Kotlin (and very very little in Go), so if it's "encouraged" in Kotlin, then your point (3) makes sense.
- isbvhodnvemrwvn 5y agoI've worked with systems where some of the things were defined as a DSL within Kotlin (with implicit receivers and a shitton of extension functions), so you can definitely shoot yourself in the foot.
- iudqnolq 5y agoI think it's ameliorated by being designed by an IDE developer, so all that magic has control+click to go to definition. I've debugged some hairy nested implicit receiver code with jetpack compose pointer events, and found it very easy to read exactly what was executed. I'm a beginner though, and kotlin was the first language where it occurred to me I could just read the source of a library.
- dangoor 5y agoThis is actually one of our reasons for choosing Go! We recognized that we'd have to come up with a fairly detailed style guide for Kotlin to reflect how we wanted to generally approach things so that it's possible to jump into another part of the codebase and not get lost.
- lima 5y agoYes and no - that this kind of policy is hard to enforce, and only affects your code base. The nice thing about Go is that its simplicity permeates the entire ecosystem.
- newnamenewface 5y agoI feel like go by itself is very nice but dependency management across inter-opping projects really sucks. I feel like an idiot every time I run into dependency versioning issues and have to spend half a day figuring out what mixture of versions of each dependency to set. Any advice?
- andrewfromx 5y agoi don't think dependency management is great in any language. Maybe cargo and rust win at that? But I happen to know go's well at this point. Ruby is terrible! And don't even get me started on node.js. But recently I got a go build error and had to just put in printlns: https://andrewarrow.substack.com/p/installing-go-from-source-to-debug https://andrewarrow.substack.com/p/installing-go-from-source...
- house9-2 5y ago> i don't think dependency management is great in any language. Ruby is terrible! If you use bundler and Gemfile.lock everything 'just works' in Ruby. Node/npm/yarn is a nightmare
- gher-shyu3i 5y ago> you can follow the logic always 100% of the time You can see the bare bones if conditions and for loops sure, but what are they actually trying to do? golang code is very thin - it takes a lot to write to convey a particular piece of logic. What a few lines of map/filter/accumulate/group by in a more expressive language like Java or Kotlin becomes dozens of lines in golang. It becomes challenging to extract the underlying logic and to follow it. Java and Kotlin are strictly superior.
- kubb 5y agoYou might have missed the part of the article where they describe the weaknesses of Go that they've discovered while porting their Python code, but they downplay them to make the whole thing sound more like a success.
- LanceH 5y agoIt's getting the job done, it's faster, and the developers are happy. It sounds like a success because it is.
- DangitBobby 5y agoThe developers say positive things after having spent months on this effort. It's just as likely a psychological defense mechanism against melancholy as it is an actual optimism for the new Eldritch Horror that's been unleashed on them. Especially if they weren't given a choice on what language they would be using. > Our engineers come from a variety of programming backgrounds, so we certainly do have a diversity of opinion on Go vs. other languages. That said, Go is doing the job we “hired” it to do when we started Goliath, and we’re thankful for the team driving its continued evolution and the community that has built up around it! If you were calling a reference for a potential new hire, would you consider this a glowing review?
- LanceH 5y ago> If you were calling a reference for a potential new hire, would you consider this a glowing review? Ships code on time, on spec, performance exceeding expectations. Sure.
- DangitBobby 5y agoOnly one of those was actually said. The article is not a glowing review of go. The carefully chosen snippets of text conspicuously say nothing about how the engineers, at the end of the day, like using the language.
- jniedrauer 5y ago> 2) a string is always "" vs null! This is really just semantics, because nullable strings do exist in go: *string. The difference is you pay a surprisingly severe performance penalty for them.
- unscaled 5y agoString in Kotlin can never be null. String? (with a question mark) can. Kotlin String == Go string Kotlin's String? == Go *string They're fully equivalent in this regard. If you wanted to note where Go strings are actually superior to Kotlin strings I'd give: 1. Go strings are slices. For immutable data that's pretty cool. I like it less when it comes to mutable arrays. 2. Go strings are single-byte UTF8, instead of wide-char UTF16. That's strictly superior. Both of these limitations are probably due to the JVM, not Kotlin itself.
- gct 5y agoI want to like Go but it's just too much of a mess of a language, and the power it gives you isn't enough to justify it. C++ is at least fast. You can see this in the proposal for generics[0], where they have to tap dance around the fact they didn't consider generics in the language from the beginning. [0]: https://go.googlesource.com/proposal/+/refs/heads/master/design/43651-type-parameters.md https://go.googlesource.com/proposal/+/refs/heads/master/des...
- mseepgood 5y agoThe language has barely changed since 1.0.
- andreygrehov 5y agoJust a minor note on Go vs C++. C++14 specification: 1354 pages. Go specification: 50 pages.
- ris 5y agoAnd brainfuck is 340 lines: https://github.com/brain-lang/brainfuck/blob/master/brainfuck.md https://github.com/brain-lang/brainfuck/blob/master/brainfuc...
- DangitBobby 5y agoNot sure why this is downvoted. It pretty clearly demonstrates the point that there is a such thing as being too simple, and that simplicity for its own sake is not a virtue.
- gct 5y agoR5RS is 40 pages and you can do so much more in that language.
- synergy20 5y agofor c++ spec, many are due to back compatibility. if you stick to modern c++ for new projects, it's much concise with much less pages.
- zabzonk 5y agoThe number of lines written is no measure of success, rather the reverse. How many lines of Python did this re-write replace?
- BiteCode_dev 5y ago> we needed 2.7x lines of Go to handle the same features as our Python code But it's for a rewrite, so: - you can use the most modern language features. Python 3.9 is less dense than Python 2.7 (E.G: a silly 2.7 example would be https://0bin.net/paste/xpnCov-3#3s2AgDReXpeqG4knegGwdnYNi523PqgYXKH6svrFW-5 https://0bin.net/paste/xpnCov-3#3s2AgDReXpeqG4knegGwdnYNi523... which is 37 lines, the equivalent in 3.9 is https://0bin.net/paste/b4DVZIS5#372LGWNLBJfDUNQGAMsDlJPNlkVy982luK1seDkOD+K https://0bin.net/paste/b4DVZIS5#372LGWNLBJfDUNQGAMsDlJPNlkVy..., down to 25 lines). Also note that it's not just less lines, but way shorter, yet clearer, lines. Something LoC fails to take in consideration. - you can use the most modern stack. E.G: fastapi is less dense than flask as soon as you use data validation, plus it adds typing for free. - you know very well the problem to solve so you get it right the first time.
- irjustin 5y agoI didn't take the headline to mean "success" more like "experience". In the article, they clearly measured success by 1:1 porting of the entire code base from Python to Go as closely as it makes sense.
- doggodaddo78 5y agoDepending on functionality delivered, it sounds over-engineered if their codebase is 500 KLoC. Bragging about removing LoC would be better.
- gher-shyu3i 5y agoIt's the nature of golang to be verbose like that. It has very low code density, meaning it takes writing a lot of code to express something that could have been expressed in a much more concise manner in a stronger modeling language like Java or C#.
- throwaway894345 5y agoI'm strongly of the opinion that people make much too big a deal out of line counts and character counts. I'm very doubtful that there will be a significant difference in quality between two equally-complex programs which differ only in that one is more terse.
- erik_seaberg 5y agoThe line count determines how much code I have to speed-read at 3 AM because prod is down. My issue with boilerplate is that we have lots of tools for generating it but no well-supported way to summarize it back to something human-readable. I should be focusing on a high-level description of the problem, and the compiler should be filling in as much of the solution as it possibly can. My brain is made of meat and will never get any faster, so this is the only way for the profession to progress.
- throwaway894345 5y ago> The line count determines how much code I have to speed-read at 3 AM because prod is down. I disagree, it’s purely a count of newline characters per my original point (e.g., a third of the lines are just `}` or `]`). > My issue with boilerplate is that we have lots of tools for generating it but no well-supported way to summarize it back to something human-readable In my experience, it’s pretty easy to understand `if err != nil { return err }` and the like at a glance. Similarly a for loop that maps a `[]T` to a `[]U`. I also dispute whether a long chain of .map().foldr().etc() is intrinsically more intuitive than a for loop, especially when the code needs to short circuit. Don’t get me wrong, I like using Rust-style iterator combinators in my hobby time, but it’s because they make me feel clever not because they are more readable than Go-style for loops. TL;DR, I agree that our brains aren’t getting faster and that readability is important, I just don’t think newlines or the lackthereof are the measure of readability.
- fouc 5y ago500,000 lines but it's "services written in Go", so it's not a monolith, which leads to a lot of duplication I'm guessing. What are the chances if it was a monolith written in Go, it could be closer to 300,000 lines instead?
- dangoor 5y agoI'm not sure what kind of duplication you're thinking of. _Some_ of the services tax is taken up by our use of Apollo Gateway. When the client requests data that comes from multiple services, Apollo will actually pull that data together. Beyond that, the only additional code required due to services is that it's more verbose to make a cross-service GraphQL call than it is to make a function call into another package. Through tooling, we've reduced that verbosity where we could. I don't think it's anywhere near 200,000 lines of overhead, though.
- kubb 5y agoHere's a take: Go is a language for engineering managers who occasionally contribute a ten liner. You can learn just enough in between your many meetings to make a simple change. You can feel proud and happy with how easy it was for you to contribute. And you can dump the verbose, repetitive drudgery onto the people below you in the org chart, it's their job to deal with this after all. But in a language that you can easily understand, you'll make sure to push for that.
- msplash9 5y agoIt's funny how far you are away from truth.
- throwaway894345 5y agoCounterpoint: There are lots of engineers who are pretty excited about Go. Go ranked #5 in the 2020 StackOverflow Survey's "Most Loved Languages" section, for example, and I've never even heard of an account in which the manager lobbied to use Go for a project--it's almost always bottom up. Seems like it's not just managers who appreciate being able to come into a project and quickly come up to speed and contribute. It's strange to me that you portray that property so negatively.
- ghostwriter 5y ago> Counterpoint: There are lots of engineers who are pretty excited about Go. true, there are lots of junior engineers who don't know better tooling yet and that are still excited about taking random surveys.
- ironmagma 5y agoIt was also the #21 (37% of respondents) most dreaded. For context, the “love” rating was a 62% response, so that means it’s something like a 2:1 love to dread ratio. At my current company it’s definitely leadership pushing for Go and not the other way around, and lots of startups have chosen Go early and are stuck to it inflexibly. Edit: I retract this. Looks like the metrics are simply inverses (even though they shouldn’t be).
- bilal4hmed 5y agoIs Go no longer worth it to learn? Seeing a lot of posts where over the long term go code base is not fun to manage. Was looking at my next language after python. Rust is one , should something like kotlin be the other ? For interviews python seems to be nice and fast to type.
- cle 5y agoI maintain hundreds of thousands of lines of Go code, for a few years now. I would not pick another language for that. The important properties with maintaining code bases like that are language regularity (most code is written the same way and you don’t have to make personal “taste” decisions on things), good documentation and online communities, well-maintained libraries, tooling features for versioning and namespacing, deployment simplicity, etc. Go nails those things. I agree that Python is great for interviews. I would not use it for a large codebase maintained by a bunch of people for years, unless there is a really compelling reason.
- mixmastamyk 5y agoTyping is available now, and other QA tools for years.
- kuang_eleven 5y agoPython has all of those things: - language regularity; black has been the default for years now, and if you want to enforce a different style, there are other tools - documentation and online communities; not even a contest, no language comes close to Python in extensive documentation and online support - libraries; much the same, Python standard libraries are world-class - versioning & namespacing; Depending what you need from this, Python is again more robust, namespacing in Go is a disaster. - deployment simplicity; ...alright, you got this one. Python deployment is harder than it should be. Still, I find my Docker images about the same complexity between the two; more complex deployment in Python, but no need for compilation
- cle 5y agoBy regularity I mean much more than just style. Ironically Go does “one obvious way to do something” much better than Python. When formatting a string, should I use % operator, str.format(), or f-strings? If I want to make a data obj, should I use a regular class, dict, namedtuple, dataclass, or TypedDict? If I’m changing each element in a list do I use a list-comprehension, or loop, or map()? Even unit testing in Go is mostly converged on the stdlib framework, in Python it’s constant back-and-forth between unittest, pytest, and nose. Static typing? Mypy, PyRight, Pyre, Pytype, with varying degrees of IDE support. Speaking of IDE support, which of the 3 major LSP servers should you use? How do I specify dependencies, with raw pip, Conda, pipenv, or poetry? When setting up my dev env should I use virtualenv or venv, or do I not have to use it bc of pipenv or Conda? (I only actually use one of each of those with my own code, but I have to know about them all to work in the ecosystem.) Also IMO, Python’s stdlib comes nowhere close to the quality of Go’s. Somehow despite all this I still enjoy writing Python, and use it sometimes for my personal stuff. But in a team setting on a large code base? Nah.
- azth 5y ago> Our former .NET engineer now says, “Being able to call a function that doesn’t return an error and know for sure that it must succeed is really nice.” Except when it panics. The article lacks substance honestly. That being said, it further cements the notion that golang has been a replacement for Python and Ruby, not Java/C#/C++ as originally planned.
- philosopher1234 5y agoPanics are prevented by culture, and I fail to see how a c# dev complimenting go invalidates gos competitive edge over c#?
- unscaled 5y agoExcept that every nil pointer dereference panics. Every out of bounds access panics. Is that also prevented by culture? Let's not forget that, for better or worse, exceptions in Java are checked. The types of exceptions that are errors in Go, must be explicitly handled or forwarded by the caller in Java - there is no way around it. The the type of exceptions that are panics in Go are just unchecked exceptions in Java: you don't have to explicitly handle them, but you can use the same mechanism for doing so, and handling them is more graceful, easier and culturally enforced than panic/recover. I have many criticisms of Java, but I'd argue Java culture is much more graceful in error handling there.
- zemo 5y agoout of bounds panics aren’t all that common in practice. Yeah they’re easy to write, but usually if you have a slice you’re going to range over the whole thing or loop over it up to its length anyway. It’s not common to handle slice indexes on their own and keep them hanging around outside of the context of a for loop. The major exception to this is cases where you want the first element of a slice and didn’t check that the slice is non-empty first, which sucks. But in any case, it doesn’t come up all that often in production code. You can range over a nil slice or a slice of zero items safely. Nil pointer dereferences are way more common, as is assignment into a nil map. Those I see coming up a lot in newer Go programmers’ code.
- pylon 5y agoOne of the reasons I love Go is that it's just so easy to read Go code written by other people on my team or third party libraries. There have been tons of cases where I'm working with another library and I just step into their code in my editor to understand how something works. And the code is always so easy to follow. It's very rare that I come across weird patterns or someone trying to be very clever. Its always straightforward code.
- deleted 5y ago[deleted]
- zozbot234 5y agoYup, Go is certainly easier to read than Python.
- sigzero 5y agoNot even close to being true. lol
- skj 5y agoWith big python projects it's often difficult to figure out what code is going to be executed next due to inheritance and mix-ins. With Go, it's usually pretty straightforward. Yes, there are interfaces, but they're used in places where people actually want the choice of code to be dynamic, rather than people just having fun building up crazy hierarchies in the name of DRY. So, with Go I find it very easy to read because of high code locality and the ease of following to the correct destination with function calls. For things that are already local, "ease of reading" is just code for "familiar". Go is strictly easier to read because tracing through is strictly simpler. Anything else is just spelling and those barriers disappear with only minimal experience.
- joshuamorton 5y agoThis is true for particular types of python, but not true for most of the python code I work with, for example. I'll grant you "encouraging non-complicated architecture" is a good thing, but Go swings a bit too far in the other direction, for example `set(foo) - set(bar)` in python is an extremely expressive (and efficient) way to give me the things in foo that aren't in bar. In go, you can either do this as a nested for loop, which is harder to read and n^2 instead of n, or explicitly loop over each iterator and convert to a map (which, to be fair, is exactly what python does too), and then write the map-diffing yourself, which is easy to screw up and should probably be thoroughly tested to ensure you didn't make any mistakes in your implementation. In python its one line of clear, expressive, known-to-be-correct, code. Granted the generics proposal should do a lot to improve things here, but I disagree that go is "strictly easier", because there's often far more to trace through, as there is far less abstraction provided for you by the language, so instead of having to perhaps unwind a single complex expression that uses some advanced language features, you have to unwind the pseduo-reimplementation of those abstractions in the local project.
- dkarras 5y agoI'm not very familiar with KhanAcademy besides the beginnings of it where it was just a youtube channel. What are they doing now to warrant half a mil lines of code?
- _rpd 5y agoAt least in mathematics, after each video, they have a fairly sophisticated set of tests that are quick to pass if you’ve understood the concept, or that adapt in difficulty to your level of understanding and attempt to fill in any gaps. It’s quite impressive. Kids can definitely use it to catch up or work ahead on their own if they are interested.
- dkarras 5y agoThank you, that sounds pretty cool.
- jeremy_wiebe 5y ago@kdangoor’s comment reviews most of the big features of Khan Academy: https://news.ycombinator.com/item?id=27176055 https://news.ycombinator.com/item?id=27176055 TLDR; it’s more than videos and exercises.
- ojhughes 5y agoIs rewriting everthing from scratch ever a good idea? I can understand the need to get off Python 2 but migrating the entire stack to Go sounds very risky and hard to justify.
- dangoor 5y agoI blogged about this[1] as we were starting the project. The short story is that moving from App Engine 1st Generation+Python 2 to App Engine 2nd Generation+Python 3 would have _also_ been a ton of work, but would have given us fewer benefits out the other end. We reduced risk in the project by making it very incremental[2]. All of this Go code has been incrementally put in front of users without anyone really noticing. As a non-profit, we absolutely did need to justify it to our senior leadership and board. They've been super supportive because they know exactly what we're dealing with and how this benefits us for the long term. [1]: https://blog.khanacademy.org/go-services-one-goliath-project/ https://blog.khanacademy.org/go-services-one-goliath-project... [2]: https://blog.khanacademy.org/incremental-rewrites-with-graphql/ https://blog.khanacademy.org/incremental-rewrites-with-graph...
- mwcampbell 5y agoI wonder if the Khan Academy engineering team has come to have any regrets about the change from a monolith to multiple services (micro or otherwise). Do you feel that the move away from a monolith was forced by the transition off of Python 2, and would have been best avoided otherwise? Do you miss the simplicity of an integrated application where you don't have to deal with the added complexity and failure modes of multiple communicating services? To put my cards on the table, I feel that most web applications are best implemented as a monolith with server-side rendering, not a back-end API (e.g. REST or GraphQL) plus front-end code consuming that API. My thinking on this is largely influenced by DHH's promotion of the "majestic monolith" pattern, e.g. https://m.signalvnoise.com/integrated-systems-for-integrated-programmers/ https://m.signalvnoise.com/integrated-systems-for-integrated...
- dangoor 5y agoIt is more complex, to be sure. I actually think that we're not yet getting all of the benefits that we'll ultimately get from services. For example, we have one deploy queue still, so we'll likely benefit when teams can deploy even more quickly because they're not waiting on other teams. Multiple services also makes it so that a deploy of one service gone awry is less likely to cause problems on the whole site. I also think that the maintenance will be better over time. It'll be easier to swap out the guts of an individual service. But, we haven't gotten to that yet. We _have_ already gotten benefits from certain things being in separate services. The best example of this is with our "content" service which, as you might guess, provides content data and metadata to the rest of the services. Since this is a separate service, it's able to store a whole bunch of content directly in instance memory, so it can respond to queries very quickly. This part didn't work as well in the monolith. I don't think I'd argue for services in general for a smaller team (Monolith First[1]), but I do think that splitting some bits out that have very different operational characteristics (different traffic patterns or uptime needs) can be worth it, even for smaller teams. [1]: https://www.martinfowler.com/bliki/MonolithFirst.html https://www.martinfowler.com/bliki/MonolithFirst.html
- f430 5y agoShould I learn Go and if so Why? I work with python and node.js but should I give Go a chance?
- omginternets 5y agoTry it? It'll feel a bit lower level at first, but I suspect you'll come to appreciate the concurrency model and the (not too pedantic) type system. More generally: you're getting downvoted because your question is impossible to answer without knowing what kind of work you do.
- MapleWalnut 5y agoIt seems like Khan Academy changed their blog to Wordpress and they no longer have an RSS feed.
- dangoor 5y agoWe did change to WordPress and we do have a feed. https://blog.khanacademy.org/engineering/feed/ https://blog.khanacademy.org/engineering/feed/ should work for you!
- MapleWalnut 5y agoExcellent, this works perfectly. Thanks!
- dangoor 5y agoGreat! Sorry it wasn't more discoverable. We may be able to improve that.
- MapleWalnut 5y agoIf you add a link like the following to your page, feed readers should be able to discover your RSS feed <link rel="alternate" type="application/rss+xml" href="/engineering/feed/" />
- dangoor 5y agoYeah, I knew about that. Tricky bit is figuring out the best way to plug that into our theme and have that particular feed only show up for engineering posts. Regardless, it's totally worth doing because people reading our engineering posts are far more likely than the average person to want the feed!
- emehrkay 5y agoI cant wait for that slices package. If I have to write this one more time im going to have a breakdown func inSlice(needle someType, haystack []someType) bool{}
- SergeAx 5y agoI would use hashmap and get O(1) instead of O(N).
- inertiatic 5y agoYou know, inserting N elements into a hashmap is O(N).
- ModernMech 5y agoYou're conflating Ns here. The N in O(N) is the number of elements already in the collection, not the number of items you are inserting. Since we're talking about the asymptotic case, it's always assumed that N >> the number of elements you're inserting. In general, inserting into a hashmap should be O(1) with a constant time hash. The choice of a hashmap over a list depends on whether the constant time hash is slower than searching through the entire list.
- inertiatic 5y ago>The N in O(N) is the number of elements already in the collection, not the number of items you are inserting. For a hashmap, the operation of inserting N items is O(N) and yes that N is the number of items you are inserting. So flat out wrong on that one. The rest is kind of obvious.
- ModernMech 5y ago"For a hashmap, the operation of inserting N items is O(N) and yes that N is the number of items you are inserting." This is not a proper application of big O notation. Big O notation is asymptotic. It's a shorthand for considering the performance of the algorithm as the number of elements tends to infinity. If you insert a single item into a linked list we don't say that is O(1) because it's a single item; you still need to iterate over N items already in the list before you can insert it. The more items in the list, the more items you have to iterate over before the insertion occurs. But if you don't believe me about the hash map, here's an algorithm for inserting in C++ using linked lists for collision resolution: template <class T> bool HashSet<T>::insert(T item) { // Hash the item unsigned long ix = this->hash(item); // Find the item in the appropriate bucket. If it's already there, return false. if (this->array[ix]->findItem(item) != -1) { return false; } // If the item is not in this bucket, insert it. this->array[ix]->insertAtHead(item); return true; } The only linear-time operation in this algorithm is findItem() on the linked list, but for a properly sized hash table, the linked list in question here should have very few items in it compared to the rest of the table (n_linked_list << N_hash_table). insertAtHead() is O(1) always. hash is O(1) always. The one thing missing in this example is resizing the table if it gets too full, which is O(N) and generally requires re-hashing all the items. Ideally you could make the table large enough when you initialize it to avoid this altogether, and then you can maintain that O(1) insertion time. This is why O(1) is the best case, while O(N) is the worst case. But O(1) should also be the common case. Therefore if I have 1 item in my hash table or 1 million, it's still going to take the same amount of time to insert the next item. That's what we mean when we say inserting in a hash map O(1); it will take the same amount of time to insert the first item as the millionth item. Even though, yes, you have to call insert a million times. That's obvious. But that's not what asymptotic complexity analysis and big O notation is for. With something like a linked list, if you try to insert a million items, it will be fast for the first one and slow for the millionth one (if you are inserting without a tail pointer). The rate at which it gets slower is linearly proportional to the number of items in the list. That's what we mean when we say inserting into a linked list is O(N). If you still think inserting into a hash table is O(N), then answer me this: what's even the point of a hash table?
- ebingdom 5y agoWhy would anyone want to use a programming language that uses product types instead of sum types for the return types of functions which can return errors? Or why would anyone want to use a language that doesn't even let you write a type safe hash table? Also, the fact that Go suffers from the billion-dollar mistake is downright inexcusable. Go is way too error prone for me to sleep comfortably at night, because the lack of a reasonable type system is a constant liability.
- hedora 5y agoI think of Go as a better Python. If those are your two choices, Go is the clear winner.
- linkdd 5y agoHow is Go the clear winner? Python has been around since 1994 (2 years before Java: 1996). It's heavily used in Data Science and Science in general. The C API allows you to write code in most compiled language (C, C++, Rust, ...) and Python serves as a glue between business logics. Go simply does not serves the same purpose. There is no winner/loser here, just different use cases...
- zemo 5y agohave you ever actually maintained production Go systems or are you just saying things based on assumptions
- ebingdom 5y agoYes, I've worked on several Go systems. Nothing I mentioned about the language is an assumption; these are well-documented properties of Go. I've also have experience in a handful of languages which have more disciplined type systems (Rust, Haskell, Ocaml, TypeScript, , Kotlin, ...), and it's a night-and-day difference in terms of safety and reliability. Being able to confidently know that you've handled all error cases, that null pointers aren't hiding in your data, etc. is useful for safety.
- void_mint 5y agoIt would be kind of a fun experiment to require a rough estimate of LoC written in a given language be included in feedback about that language. These comments are kind of a cesspool of poorly written feedback that wraps ambiguous complaints about "readability", "maintenance" and even the silly take of "Go is a language for engineering managers", whatever that means. I suspect most of the negative comments on any language come from people that have spent practically no time writing it, and thus are inherently uninformed. Of course, if you hate a language, you're not going to write lots of code in it (unless you have to, and then I would expect your feedback to be pretty negative but at least informed). Feedback from beginners/programmers external to a language is super important for the success of that language of course, but lots of debates about things like programming language are cluttered with feedback that isn't really made in good faith. Someone that doesn't like static typing is going to leave feedback about Go that may not directly say "I just don't like static typing", but ultimately is as simple to reconcile (and thus, should mostly be discarded).
- byronr 5y agoI have written hundreds of thousands of lines of plain old C, as well hundreds of thousands of lines of Go over a career spanning three decades. I've used Go in earnest since 2013. I would pick Go for any large project in a heartbeat. I have to concur that the haters who post to HN probably have never used this language in earnest. Here's what you get out of the box: * Extensive standard library * Cheap concurrency * Fast compilation * Built-in test/benchmark framework, including coverage and race detection * Built-in heap and CPU profiling Of all the complaints the one I understand the least is the reservations about performance. It is within 10-20% of C, and callouts to C and assembly are possible. (My 8-way multiplexed MD5 routine was written in AVX assembler and lives on in minio.) Extracting that last 10-20% is two or three sigmas away from the norm of how programming languages are used these days. The objection to generics is similar. The lack of generics shows up -- once in a long while. It doesn't prevent me from being immensely productive with this language. Looking back at the last few years I've wondered if I could have accomplished what I did in Go by using a different language (C in particular) and the answer, for me, is "not a chance".
- 5y ago
- itwy 5y agoHow many lines of Clojure would that be?
- paul_e_warner 5y agoI've written a bit of code in Go, and the problem I have with it is primarily it feels really outdated for a "modern" language - every time I use it I feel like I'm dealing with something written by someone who really hated Java in 2005. There are features that could be added to the language that would make it more readable and less error-prone without compromising the simplicity of the core language. Generics are the famous example, but the one that really gets me is the the lack of nullable type signatures. This is a great way to avoid an entire class of bugs that nearly every modern language I've used has evolved a solution for except Go. Another issue I have is the reliance on reflection. In general, I think if you have to rely on reflection to do something, that usually means you're working around some inherent limitation in the normal language - and the resulting code is often far less readable than the code would be in a more expressive language. Lots of Go libraries and frameworks are forced to use it in a lot of cases because there's just no other way to express some really basic things without it. I really want to like Go. There's a lot I like - the "only one way to do something" approach means that code always feels consistent. Errors as values is a far superior approach to exceptions. I had to write some for a job interview project a while back and it felt really refreshing, but every time I try to use it for a personal project, I don't feel like I'm getting anything out of it that I couldn't get out of say, Rust, or modern, typed Python.
- dcow 5y agoIf you’re the type of engineer who prides themselves on the raw amount of code you write, then Go is for you. If you’d rather focus on solving problems creatively and expressively, Go is not your tool. I don't mean this as slight against those people that really enjoy writing lots of (Go) code. It’s just my observation after being in a few different contexts where Go was the language of choice. Personally Go is too verbose for me and this is especially painful/apparent when you get to writing the multitude of tests required to ensure your code works since Go’s type system/compiler doesn't lend you much in the way of helping ensure code correctness. Go is essentially the new Java.
- tacitusarc 5y agoThis feels largely like a mischaracterization, and does not align with my experience. I'd change it to say, if you are focused on solving the problems creatively rather than using the language creatively, Go is a viable option. But if you're interested in creative usage of the language itself, Go is not right for you.
- baetylus 5y ago"We have an outlier case of a class containing 1,000 students that could take 28 seconds to load in Python, but only 4 seconds in Go." That's an awesome outlier.
- patneedham 5y agoWhy would an arbitrary number of lines of code be considered a milestone?
- mesaframe 5y agoSomehow it felt like he is defending use of Go than praising it.
- conradludgate 5y agoI use Go at work and Rust at home. They're very different languages but I enjoy them both. I do find that Go is more of a "get shit done" language and Rust is more on the creative side. I just wish that Go would have optionals. Pointers cause too many bugs. Is this parameter a pointer because it'll be mutated? Or because it's allowed to be null? Only way to find out is to run it or to inspect the functions code. You shouldn't need to view implementation details to find out
- tgv 5y agoI'd also rather have optionals/non-nullable types in the core syntax than generics. Although, I must say, I haven't seen a nil pointer crash for a long time.
- takeda 5y agoYou must be good at avoiding it or your programs are simple. Go is not much better than C in this particular case. I forgot specific detail how it was possible (I noticed it 1-2 years ago) but in Go you could have nil value when using references. It was somewhere around implementing an object.
- bborud 5y agoGo confronts people with the delta between what people think they want and what they actually need. It’s a language for getting things done. It isn’t for language buffs. And that is a huge plus for me.
- AtNightWeCode 5y agoI use Go for small things like CLI tools, simple web services or instead of scripting things with nodejs. I don't really miss generics as many seems to do. My main critique is the error handling and the lack of control flow handling. It is very easy in Go to accidentally let the code continue to execute after something went wrong. Exceptions don't have this problem cause you only catch them were you now the problem can be handled.