17 ms·
Learning Go as a Python Developer: The Good and the Bad
- erik_seaberg 4y agoTooling aside, Python is a more powerful language, so I’m wondering whether he started generating code to work around stuff like try/except and defaultdict and itertools and decorators.
- linsomniac 4y agoTL;DR: Python is hard because of library dependencies, go is better about that because of compiling to an executable, but is pickier about code quality ("I just want to try something"), and has more issues with library quality.
- LtWorf 4y agoI've encountered input libraries in go tha for some reason just grab all the signals and whatnot, so you can't ctrl+c, sighup, sigterm, use ctrl+z to return to the shell… the only option is to do a kill -9 from a different shell. Great library indeed :D
- linsomniac 4y agoMaybe there's a go library that implements that "kill but make it look like an accident" functionality on HN a few days ago? :-)
- brodouevencode 4y agoOrganizing a golang-based project is also something that, while documented, is not front of mind for most new golang users, nor does the "beginning go" posts out there do a good job of how to lay out a project for success.
- morelisp 4y agoIs Python significantly better in this regard? I don't think so, especially with the differentiation between modules which are directories with an __init__.py and modules which are files you import directly but if not in the same directory also still need an __init__.py which has tripped up probably 80% of the people I try to teach Python to. In Go you can at least get pretty far with a totally flat namespace and there's nothing wrong with that, up to at least 50kloc or so. That's less true in any language where files become a unit of modularization.
- Scarblac 4y ago> modules which are files you import directly but if not in the same directory also still need an __init__.py which has tripped up probably 80% of the people I try to teach Python to. Not necessary anymore since Python 3.3 (released in 2012).
- kccqzy 4y agoWith python you can also go pretty far without __init__.py IMO. Just put everything in a single directory.
- morelisp 4y agoBeginners trying this are still liable to make import cycles, which... sort of work? Depending on what you do with them? I feel like Go and Java have much better (and different) answers here; I wonder what a Python equivalent of the Java style would look like.
- tptacek 4y agoI hated the "damnable use requirement" (the error you get on unused imports) for years, but I've been keeping a count of how many bugs they've caught (I was surprised the first time this happened) and I'm up to 3-4 now. What people who code in Go seriously do is just hook `goimports` up to their editor, and then never think about this again.
- morelisp 4y agogoimports seems an endless source of absolutely bizarre bugs unless your packages' terminal path element exactly matches the package name (even sometimes if it does e.g. https://github.com/golang/go/issues/29041 https://github.com/golang/go/issues/29041). These do get addressed over time but also seems to break in a new way at least a couple times a year.
- bobbylarrybobby 4y agoHow is this better than downgrading the error into a warning? You'd be able to build but would still know something was wrong-ish. Certainly a warning would be sufficient to chase down any bugs, and is very freeing compared to an error.
- nouveaux 4y agoThis. Better yet, make this a --strict requirement you can turn on in CI and leave it out for normal development.
- xboxnolifes 4y agoTurned around, what's the benefit of allowing someone to build something that may potentially break, when the alternative is an easy to fix error instead?
- bobbylarrybobby 4y agoThe benefit is not needing to make any additional source changes when you go from using an import to not using it to using it again.
- ActorNightly 4y ago>sharing your code is even pain with colleagues even if they are using the same operating system, mainly because the Python requirement file doesn't pin dependencies, wat? Pretty sure you can use == in requirements.txt Also, its very possible, and quite easy to just include the code for the library in your package, which effectively "locks in" the version. We did this all the time when building AWS lambda deployments.
- AlphaSite 4y agoI recommend using poetry and just moving on with your life, it’s far easier than trying to use pip (which is totally doable, but not clean).
- LtWorf 4y agoBut poetry requires pip… you can't use it without using pip
- gen220 4y agoPoetry requires pip in the way that `go mod` requires `go get`, i.e. Poetry allows one to operate at a higher level of abstraction, where it's harder to make mistakes and generally easier to manage your dependency tree.
- LtWorf 4y agoAbstractions are amazing until they break and you have to fix them.
- gen220 4y agoSure, this is true for every abstraction: some are more air-tight or leaky than others, but IME Poetry and go mod are fairly solid. I haven’t had to use pip in a long time. Just like I haven’t had to use `go get` in a while. I mean it’s not the most rock solid abstraction, but introducing sane package management in an OSS environment with a decade plus of history is very hard. Against that background, they are doing pretty well, IMO.
- deleted 4y ago[deleted]
- loosescrews 4y agoWhile the documentation of many open source Go libraries is definitely lacking, I find that the combination of types and links to readable source in the generated docs more than make up for it. While the documentation for Python libraries is often better, it is generally much harder to answer questions not answered by the docs yourself.
- akpa1 4y agoI agree with this. I also derive quite a lot of value from having a consistent way of reading and navigating documentation for every library too. I can have an applet in my browser's toolbar and hit it when I'm looking at the Git repo and it'll almost always take me to the right place to ser the docs.
- barefeg 4y agoHow to combine both languages as he suggests? I.e. creating python binds for the go binary? What about the opposite?
- arccy 4y agoyou could do something like https://www.datadoghq.com/blog/engineering/cgo-and-python/ https://www.datadoghq.com/blog/engineering/cgo-and-python/
- kitd 4y agoNim operates in the same space as Go, but with a syntax very much in the spirit of Python. https://nim-lang.org/ https://nim-lang.org/
- vippy 4y ago"I felt I was constantly fighting the compiler/borrow checker/whatever. I just want to write some code, dammit" Well here's your problem. Type safety helps you avoid avoidable bugs. Try Haskell or Scala next.
- returningfory2 4y ago> I had heard of Go for many years, but never stuck with it; it gets constant negative press on Hacker News/Reddit I think on Hacker News it's really fashionable to criticize Go, and this has led to a culture where Go gets significantly more negativity than it deserves. As technologists, one of our most important jobs is to see through such fashions and judge languages/tools/technologies based on their actual merit. While gauging sentiment about things on a forum like Hacker News is generally really helpful, it should not be the main basis of our decisions.
- tempest_ 4y agoGo is getting used in places where Java would have been used in the past. Java complaints go down, Go complaints go up.
- Xeoncross 4y agoIf Go hadn't come along, I would be using and complaining about C# or Java for sure.
- erik_seaberg 4y agoSome of the HN audience had already been reading PG’s essays for years, and our expectations of new languages were shaped by http://www.paulgraham.com/avg.html http://www.paulgraham.com/avg.html.
- notduncansmith 4y ago“There are only two kinds of languages: the ones people complain about and the ones nobody uses.” - Bjarne Stroustrup
- tialaramex 4y agoI own a T-shirt which says "Haters gonna make some good points". People do indeed only complain about the things which are used and not the things they don't care about because nobody uses them. But, we should not think this means the complaints just signify success. People are complaining because they care, but also because it's not good, or it's not as good as it should be.
- maerF0x0 4y agoAll the docs are easily found here: https://pkg.go.dev/ https://pkg.go.dev/ The complaint about aws-sdk-go (presumably v1) is legitimate, it seems to me that code was generated and therefore the repo can be less than ideal w/ Go. I suspect that is improved/ing in v2. using goimports as your formatter solves the complaint about unused imports There was a significant portion of time where python 2.x and earlier releases of Go overlapped, and finding UTF-8 safe python libraries was non-trivial. Go makes utf-8 the default. As I understand it many companies still have python2 w/o a EoL plan. One thing I really miss about working with python is list/dict comprehensions and lambdas
- kelvie 4y agoIt's still valid for v2. While it's a bit easier to use in almost all respects, the documentation is still kind of crazy because it's mostly autogenerated. In Go, the first thing you run into when making an API call is figuring out how to handle the errors, and the aws-sdk-go docs still don't give you much help there --you have to still dive into the official REST docs, or worse, the Java docs via google, and sort of guess how each exception/error code gets mapped into what Go error. Jumping into the library code works for most Go libraries, but with the autogenerated REST bindings that is the AWS SDK, it usually isn't much more illuminating.
- nathants 4y agoi dragged my feet on go for a long time. i also thought that skipping go and moving to rust was the play. a few years later, i still write python often, but i don’t build systems with it. python i now use like bash, to glue things together and automate random things. it’s a fantastic language and i will never drop it. the verbosity of go is the biggest hurdle for a pythonista. the thought of giving up context managers, decorators, iterators, comprehensions, exceptions, coroutines, it’s unthinkable. in comparison go is ugly. your aesthetic mind screams in protest. write go full time. dive in. as months pass, not only will those aesthetic objections fade, your mental model from python cleanly transforms to go. go is what mypy tried to be. the cost was aesthetic changes. the benefit is worth it. the zen of python says if it’s easy to explain it might be a good idea. this is go, and it is. i rebuilt a reasonably sized project from python[1] to go[2] over the last few years. i also have a system that i maintain both python[3] and go[4] implementations for, sharing a test suite in python. squint at the implementations. consciously ignore aesthetic objections. they are basically the same, not very different from a python codebase with and without type annotations. go, like python, is fantastic. use both in whatever amount works for you. don’t read about them, build with them. you won’t regret it. 1. https://github.com/nathants/cli-aws/tree/bb78e529e7d1d3f95acc62dd0fbe21cadc822928 https://github.com/nathants/cli-aws/tree/bb78e529e7d1d3f95ac... 2. https://github.com/nathants/libaws https://github.com/nathants/libaws 3. https://github.com/nathants/s4/tree/python https://github.com/nathants/s4/tree/python 4. https://github.com/nathants/s4 https://github.com/nathants/s4
- jerf 4y agoObviously the closest thing in the general sense to Python is Ruby. But I think a case can be made that in practice, the closest thing to Python on the static language side is Go. The list of superficial differences is a mile long, I don't deny, nor will I exhaust my audience's patience with actually writing them out. But the interface orientation of Go captures the essence of how you design in Python surprisingly well. Of all the static languages, Go has the closest thing to duck typing, in particular the ability to declare a "duck type" for an existing third-party thing that you don't want to or can't change, and integrate it into your code as a compile-time checked member of that "duck type".
- 120photo 4y agoI tried porting a Python utility I wrote to Go specifically because I did not want people to have to install any 3rd party libraries (in this case just one). If anything I had a much deeper appreciation as to how much Python does for you and just lets you work. I would still like to port someday. For now I can containerize my app but that would still require people to install docker and learn how to use docker.
- zozbot234 4y agoYou don't need docker to bundle an app with custom libraries. You can use AppImage which is pretty much just an ordinary app install rolled into a single file.
- LtWorf 4y agoi guess he's not using linux, otherwise python dependencies would be no problem
- zozbot234 4y agoDocker is linux specific. It can only run in a VM on non-linux platforms.
- wizofaus 4y agoIt requires a linux subsystem, true, but not a fully fledged VM. The subsystem still shares the file system with the primary OS, for a start. And while I haven't tried it, the instructions for installing AppImage on WSL (for example) don't look trivial.
- DenseComet 4y agoWSL is a fully fledged VM under the hood, it's just well integrated.
- 4y ago
- benhoyt 4y agoThis roughly matches my experience, though he doesn't really discuss the language differences in this article. Here's a similar kind of article I wrote a few years ago, "Learning Go by porting a medium-sized web backend from Python": https://benhoyt.com/writings/learning-go/ https://benhoyt.com/writings/learning-go/ -- mine focuses more on language and standard library differences.
- Areibman 4y ago> I especially struggled with the DynamoDb library for Go; so much so I wrote a Python script to query Dynamodb, and called it from Go. This seems like a compelling enough reason to stick with Python
- atwood22 4y agoThe official AWS SDK contains a perfectly good DynamoDB client, especially when combined with this utility library (also part of the AWS SDK): https://docs.aws.amazon.com/sdk-for-go/api/service/dynamodb/dynamodbattribute/ https://docs.aws.amazon.com/sdk-for-go/api/service/dynamodb/...
- wodenokoto 4y agoI was kinda hoping an article with a headline like that would present some code and tooling and explain it in terms of how a Python programmer sees the world.
- bumper_crop 4y ago> I hate how it forces to you create a module everytime. This affected me recently, so I have sympathy for the author. Trying to upgrade an older project I had to the module system meant trying to find out how to import modules which don't have reachable URLs and were only on the GOPATH. At I hate how it forces to you create a module everytime. some point programming in Go stopped being for fun.
- aidenn0 4y agoI only use python casually, but it seems to me that python library authors are always refactoring and breaking interfaces. Recently, there was a bug in a second order dependency, and the version that fixed this bug was after a version that moved a function into a submodule. So I had to make a local patch to my dependency that changed all of the imports. Was the new interface more consistent? Yes, but could they have left a shim for backwards compatibility, or just lived with the old slightly less consistent interface? Seems to me like they could.
- takeda 4y agoI think that depends on library. The ones I use seem to use appear to not do that. In fact I think I actually have seen that more in Go. What goes for Go though is that you won't compile your code until you fix it. In Python you could use mypy, but unfortunately is optional and will work only if you and library author uses annotations.
- atwood22 4y agoI don't understand how the author struggled to find a good DynamoDB library. The official AWS SDK has a very useable DynamoDB client and provides utility classes for marshaling and unmarshaling Go types: https://docs.aws.amazon.com/sdk-for-go/api/service/dynamodb/dynamodbattribute/ https://docs.aws.amazon.com/sdk-for-go/api/service/dynamodb/...
- pojzon 4y agoAbout unused imports, cannot you simply use formatter on build hook ?
- travisgriggs 4y agoI realize that Go's original release is later than Python's, but they still feel roughly the same vintage to me. Usually, these articles have a "old to newer" feel, but these two ecosystems feel just different to me. Which is not bad. What would be fascinating is to see some HN links to articles where the journeyman programmer went backwards in time, e.g. "Learning Fortran as a Python developer" or something like that.
- Uptrenda 4y agoI don't think Python packaging is as bad as people make out (if packages only stick to the basic features of Python!) A far bigger issue I see is despite Python supposedly being 'cross-platform': the language introduces so many small, backwards-compatibility breaking changes that you really need to use the most up to date interpreter you can. For instance: there is now a really cool operator that lets you do expressions where you assign a value and evaluate the result in one line. So you can write the C equivalent of something like while(buf = recv(...)) ... and it will work. Well, any program that uses this new feature won't run on anything but the most bleeding edge Python versions. Despite a program only needing a small fix to remove such expressions. It wouldn't run at all. I think the Python interpreter needs to be 'smarter' and add the capability to automatically install parallel Python versions if it detects a package using a more recent interpreter. Would honestly solve so many issues.
- rtev 4y agoWhile I do see the value in something like that, I can’t help but feel like that would just bake in more complexity. The python ecosystem is fragmented with micro fixes and half-solutions without anything truly addressing the major confusing aspects.
- bborud 4y agoThere's what people think and then there is observed reality. Observed reality informs us that this is a big problem with Python, so we'll just have to accept that. What people could do isn't the issue - what people do is. Also, you don't fix a problem by adding complexity and unpredictability. Again, as reality informs us, this hasn't worked for Python. It is still a mess.
- diarrhea 4y agoPython 3.8 and its walrus operator is 2.5 years old, it's not bleeding edge, at least not anymore. That being said, I'm worried about the language in that complexity increases through the introduction of new language features without much benefit at all.
- morelisp 4y ago
- JustSomeNobody 4y agoOn the subject: What is a good, idiomatic, Go project to study? Something big enough to be a good example of code organization, yet small enough not to become a new hobby.
- jimsmart 4y agoGo's stdlib is often given as an example for this, and I personally found it to be useful learning material. I wouldn't advise trying to study it all (it's quite big): just study some pieces of it.
- deleted 4y ago[deleted]
- mountainriver 4y ago> The libraries for Go aren't as good as for Python– certainly, the documentation is lacking Huh, Go has some of the best autodoc features of any language. Also the library assertion is insane to me. I switch back and forth from Go to Python all day and generally Go has more stable better maintained libs
- Zopieux 4y agoSadly I agree with the author on the general feel of Go libraries. I can feel the language design itself and non-written philosophical identity of Go strongly affects what APIs people write in it. Most often, they suck. They feel monolithic, unforgiving, and impossible to extend. I don't belive we can only blame the lack of generics for that, it runs deeper. On documentation, I've never seen a language community that comes with so little examples most of the time. Take any random Python library RTD, it's full of it. You can skim through said examples to understand the overall features and capabilities before you dive into the API reference. No such luck in Go: here is the bare-bones godoc, good luck!
- mountainriver 4y agoThe bare bones godoc is generally fine because the language is so easy. Python needs the examples because most of the libraries have no types so you would have no idea whats happening without examples
- dragonwriter 4y ago> The bare bones godoc is generally fine because the language is so easy. No, it's not. > Python needs the examples because most of the libraries have no types so you would have no idea whats happening without examples That’s not the main reason examples and narrative explanations in documentation are useful, but if the false belief that it is has helpe to fuel the Python documentation culture, I’m not going to complain too much.
- bitcurious 4y agoAutodoc is great when you want to know "how do I use this function" but I find that projects that rely on it inevitable fail to answer "why do I use this function" which is usually the harder question.
- cookiengineer 4y agoI've been reimplementing a tool that was done in nodejs before and ported it to golang. I have to say that a lot of programming paradigms are different in golang, a few parts are annoying, and some parts are "getting there" with generics. The most annoying part if you do a lot of parsing is the golang mandated rule of what is public and what is private in a package. If you want to parse lots of JSON into a struct, mess is on you, always have to implement a custom marshal/unmarshal for it. If you always have to implement a custom JSON marshalling method, and abuse annotations for mapping upper/lowercase properties...why was the uppercase rule mandated in the first place? I wish golang had gone for an export keyword instead. Structs would have been so much cleaner. The second issue I have with golang is that struct properties (as all data types) aren't nullable except via pointers, which makes consuming JSON APIs a fustercluck to deal with some times. I wish there was a nullable string data type instead of having to use dozens of helper functions. The last issue is lack of functional ideas (as of now) but they are coming. lo is a lodash inspired library that makes a lot of things easier. [1] I hope that a lot of these helpers will at some point be part of the core libraries, so that datatypes can be easily mapped, casted and filtered. [1] https://github.com/samber/lo https://github.com/samber/lo
- usmannk 4y agoPersonally I find struct field tags a nice way to encode the json fields. They also allow you to use upper case names for all struct members. I’ve never had an issue with the way json is done in golang, and I’m kind of confused by this rebuke. What’s wrong with using string pointers? What helper methods are necessary to write? This kind of feels the same as reading a rant against strict types.
- binwiederhier 4y agoIf you do a lot of JSON parsing for unknown or large structs, you can use gjson: https://github.com/tidwall/gjson https://github.com/tidwall/gjson
- craigching 4y agoHaving done both Python and Go for quite some time now, yes, Python modules are a mess, but it wasn’t so long ago that the same could be said for Go (glide-> dep -> go mod anyone else?) Go mod is finally maturing, but there are still some painful edges as well.
- peterbe 4y agoShameless plug if it helps anybody else, like it helped me; http://govspy.peterbe.com/ http://govspy.peterbe.com/
- thebigspacefuck 4y agoSimilarly helpful, pytago is a source to source transpiler for python to go https://pytago.dev/ https://pytago.dev/
- remix2000 4y agoI don't understand the criticism on "shared environments" which the author latter voids himself, but what I do know is that Go makes a fairly good choice for extending Python, but isn't really in the same ballpark as Python. Some thoughts: - Go singlecore is actually slower than Python (nb Stackless[0] [still stands], but not only that: graalpython/loom is even faster, much faster) - Prototyping is always slower in most AoT-compiled languages, obviously. I'd be more convinced to try Go if it had something like Cling[1]. - CSP is (in my opinion) less palatable than Actors and makes Go feel somewhat... dated? Matter of taste? - Go doesn't use libc which can be awkward at times. [0] https://entitycrisis.blogspot.com/2009/11/go-vs-stackless.html?m=1 https://entitycrisis.blogspot.com/2009/11/go-vs-stackless.ht... [1] https://root.cern/cling/ https://root.cern/cling/
- damagednoob 4y ago> Go singlecore is actually slower than Python This is news to me. Do you have something newer then a 13 year old blog post that shows this?
- Havoc 4y agoA bit of both is my answer. For some usage cases eg cloud functions go does seem superior. Yet the convenience of hacking stuff together with python has its appeals too
- jbirer 4y agoSo the biggest complaints, from what I read here, is "it does not allow me to write bad code or make mistakes, I want something I can hack together without having to worry about conciseness", and based on groupthink "HN was negative about it". Languages like Rust and Go were designed to keep this sort of thinking away.