[HN Gopher] Learning Go as a Python Developer: The Good and the Bad ___________________________________________________________________ Learning Go as a Python Developer: The Good and the Bad Author : shantnutiwari Score : 137 points Date : 2022-07-18 18:22 UTC (4 hours ago) (HTM) web link (new.pythonforengineers.com) (TXT) w3m dump (new.pythonforengineers.com) | 120photo wrote: | I 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 wrote: | You 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 wrote: | i guess he's not using linux, otherwise python dependencies | would be no problem | zozbot234 wrote: | Docker is linux specific. It can only run in a VM on non- | linux platforms. | wizofaus wrote: | It 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 wrote: | WSL is a fully fledged VM under the hood, it's just well | integrated. | wizofaus wrote: | MS call it a "lightweight utility virtual machine", and | "not a traditional VM experience", whatever that means. | Docker also works on MacOS, with a basic linux distro | running under hypervisor that again, I'm not sure | qualifies as a 'fully fledged VM' (at least in terms of | user access to it). | deivid wrote: | The easiest way to do this is to use shiv[0] if you don't mind | asking people to have Python itself installed; if you want a | truly "one file bundle" you should use PyInstaller[1] (which | bundles a Python interpreter) | | [0]: https://shiv.readthedocs.io/en/latest/ | | [1]: https://pyinstaller.org/en/stable/ | [deleted] | cookiengineer wrote: | I'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 | binwiederhier wrote: | If you do a lot of JSON parsing for unknown or large structs, | you can use gjson: https://github.com/tidwall/gjson | usmannk wrote: | Personally 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. | returningfory2 wrote: | > 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_ wrote: | Go is getting used in places where Java would have been used in | the past. | | Java complaints go down, Go complaints go up. | Xeoncross wrote: | If Go hadn't come along, I would be using and complaining | about C# or Java for sure. | erik_seaberg wrote: | Some 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. | 37ef_ced3 wrote: | As an engineer who uses Go and appreciates it as a replacement | for most purposes where you might use C or C++, the complaints | just seem bizarre. | | You've got people who argue against explicit error checking and | people who don't understand the important role of nil pointers | and people who don't see the massive net win of garbage | collection in concurrent programs, and so on. | | Endlessly. | | It feels like a waste of time defending the language when the | people criticizing it seem to hold such a vastly different | point of view. It's like trying to convince people that Natural | Born Killers is a good movie or that Primus makes good music. | There's an unbridgeable chasm between you and the people you're | trying to convince. | frazbin wrote: | > people who.. don't understand the important role of nil | pointers | | ... I guess you're right; I really do not understand | LtWorf wrote: | But C++ had generics ages ago already... You never used | those? | obviouslynotme wrote: | Go has always been a Java, C#, Python, and Ruby killer. It | has not and never will be a C or C++ killer. C is the | language of libraries and embedded, neither of which Go is | good for. C++ is the language of large systems that need | extreme control over resource allocation. Go is not good for | this either. | wizofaus wrote: | Is Go really killing C# though? I've rewritten Go | components in C# (the initial version only had basic | functionality requirements, but as they expanded, Go made | less and less sense given the rest of our codebase), but | can't readily imagine wanting to rewrite C# in Go. Maybe | once they add proper exceptions... | obviouslynotme wrote: | No. C# is usually used by Microsoft shops, and half the | reason to use C# is so you can use Visual Studio. | wizofaus wrote: | That implies that if a better alternative to VS came | along, C# developers wouldn't choose it! I certainly | would, for one, and I'm a long-term VS user, well aware | of its failings (but also yet to come across another IDE | that's noticeably superior. And coding with a text editor | and command line compiler is something I spent 10+ years | doing when it was all that was available, and nothing I | have any great hankering to go back to - even if it's | something I still resort to as an emergency measure, e.g. | when on some remote system with text-only access etc.) | vsnf wrote: | My current project was switched from C# to Go almost 2 | years ago. It was a management decision, and while the | team all generally has found something or another to like | about Go, we all miss C#. | tptacek wrote: | It is too easy for people to forget that C was not _always_ | the language of "libraries and embedded", and that writing | large systems programs in C, of the sort that nobody would | realistically consider writing that way in 2022, was a | norm. Displacing C doesn't just mean rewriting existing C | dependencies, but also changing the balance of decisions | about which _new_ programs to write in C. Go has had a | tremendous amount of impact there. Without Go, Docker would | almost certainly be a large ball of C code. | ledauphin wrote: | I agree with you that Go does not replace C or C++, but I | strongly disagree that Go is an obvious replacement for | most uses of Python, C#, Java or Ruby, all of which are, | frankly, _much_ higher level languages than Go. | | Go gets used for two main reasons that I've been able to | observe: | | 1) a desire for a very specific type of concurrency 2) a | desire for a fast compiled language with a minimalistic | feature set that scales well to large teams. | | Switching to Go from one of those languages is very much | giving up a kitchen sink for a purpose-built tool. It may | be the right decision under lots of different | circumstances, but it doesn't directly compete with any of | the languages you've mentioned because of how minimalistic | it tries to be. | | Overall, in fact, I think Go does something far more | interesting: it's legitimately an attempt to carve out a | whole separate niche for software development. Whether it's | ultimately been successful there is for a different comment | thread, though. :) | obviouslynotme wrote: | Go has always been a high level language, and is even | more so now with generics. I would even argue that Go, | correctly done, is halfway between the Java tier and the | Lisp tier. Due to Go's quick and easy parsability, | generation, and compilation. It is very easy to write | tools for Go. Code generation and struct tags are even | part of the standard, but very people use them beyond the | basic serialization libraries. It's not quite lisp, but | it is very close in many ways. | | Very few people rewrite projects. Most change happens by | new projects adopting one language over another. The fact | that I hear of Python rewrites to Go is honestly amazing. | adra wrote: | Languages generally aren't stuck in time. If we actually want | languages to evolve and in ways that are actually valuable to | real people (not a small subset of those developers writing | it), then these pieces should be an invaluable resource to | help steer the language in the direction that will most | reward adoption, longevity, etc. | bogeholm wrote: | > Natural Born Killers ... Primus ... | | We should have a beer sometime! | devonkim wrote: | I think there's a lot of disagreements about what people | think is desirable in a language in the first place and then | start complaining without understanding the design concepts | that shaped its creation nor even agree the problems are even | problems to begin with. Many even seem to think that bad | ergonomics are to be accepted and want to create a higher | barrier for programming productivity (there are some merits | to this attitude honestly but that's not the point I'm | interested in). | | I think it's more akin to trying to talk to people about | Quentin Tarantino movies. Lots of people enjoy them, many | critics like his stuff, and then there's a relatively small | group of people that disparage everything he does because he | isn't ascribed to any artistic school of filmmaking and under | a lot of such critical analysis his films are pop fodder. | It's not like he ever makes his movies to please critics is | the thing, he's basically a super fan that just winged it | all. Many fairly sane and measured, learned critics "get" | Tarantino and appreciate him for what he tries to do and all | is fine there. But it won't matter what Tarantino does going | forward with the other crowd - it's because they have | diametrically opposed ideas of wtf movies even are supposed | to be. | [deleted] | notduncansmith wrote: | "There are only two kinds of languages: the ones people | complain about and the ones nobody uses." | | - Bjarne Stroustrup | zozbot234 wrote: | Go is a vastly preferable language to Python or Ruby for most | things. The "negative press" is quite overstated, it does get | plenty of favorable advocacy as well. | metadat wrote: | Use an appropriate tool for the job, Python is useful for | tons of things that would be a nightmare to pull off in | golang, and vice versa. | suremarc wrote: | Indeed, try doing any sort of data analysis in Go, it's | maddeningly verbose. | mountainriver wrote: | > 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 wrote: | Sadly 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! | maerF0x0 wrote: | All the docs are easily found here: 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 wrote: | It'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. | benhoyt wrote: | This 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/ -- mine focuses more on | language and standard library differences. | atwood22 wrote: | I 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/... | nathants wrote: | i 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/bb78e529e7d1d3f95ac... | | 2. https://github.com/nathants/libaws | | 3. https://github.com/nathants/s4/tree/python | | 4. https://github.com/nathants/s4 | jerf wrote: | Obviously 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". | nathants wrote: | very true! to be a WriteCloser[1], you have to be able to | Write[2] and to Close[3]. quacking confirmed. | | 1. https://pkg.go.dev/io#WriteCloser | | 2. https://pkg.go.dev/io#Writer | | 3. https://pkg.go.dev/io#Closer | vonseel wrote: | Do Go programmers also not like capitalization? Just a tease, I | noticed the readme and your comment don't have any Capitalized | Letters. Well, the readme has a few but you know what I mean. | nathants wrote: | i can only speak for myself. i reserve raising my voice for | where it's APPROPRIATE. as with the python/go debate, | aesthetics are subjective. | corrral wrote: | Breaking basic language norms in this way is the equivalent | of CONSTANTLY RAISING YOUR VOICE. It's distracting and | attention-getting. Which may be your goal, but if your goal | is to be easily understood and sympathetic to your reader, | it's counterproductive. | nathants wrote: | this is exactly correct. | | i sincerely apologize to any who have been harmed, even | slightly, by my oddity. | tptacek wrote: | I 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. | bobbylarrybobby wrote: | How 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. | tptacek wrote: | I'm not offering any opinion about the use requirement other | than to say that it has caught 3-4 bugs for me. | xboxnolifes wrote: | Turned 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 wrote: | The 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. | morelisp wrote: | goimports 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). | | These do get addressed over time but also seems to break in a | new way at least a couple times a year. | ActorNightly wrote: | >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. | pletnes wrote: | Sure can pin versions, it's easy too, if you just use <<pip | freeze>>. | pid-1 wrote: | Now you lost track of which are your top level dependencies | and which are dependencies of dependencies. | anyfactor wrote: | Better option is to use pipreqs. | | Virtual Environment gets on my way. Looking at you Jupyter | notebook. | ska wrote: | That only solves part of the problem. | | something like poetry's approach is the right one here; you | need a list of core dependencies (not derived ones), you need | a solver for when anything changes to find a new set of | viable versions, and you need a lock file of some sort to | uniquely & reproducible construct an environment. | paulsef11 wrote: | There's lots of cases where you wouldn't want to pin your | requirements.txt, the main one being if you're authoring a | package. You need to leave the versions unpinned, preferably | just bound to a major version, allowing some variability for | the users of your package in case there's a shared dependency. | I have a feeling that's what the author is describing here, | because Poetry solves this dilemma by introducing a poetry.lock | file which pins the dev versions of all the dependencies, but | publishes a package with unpinned deps. | giantrobot wrote: | The issue is transitive dependencies. A dependency you pin | isn't guaranteed to pin its own dependencies. A bug somewhere | in a grandchild dependency can manifest for you even if you | have a version pinned but the dependency did not. | | It's not automatically a problem but it certainly can become | one. | linsomniac wrote: | I'm a huge, long time, python fan. I don't tend to have a lot | of problems with dependencies, but it clearly is something that | certain situations have problems with. | | As I understand the post, the author is saying "It sure is nice | to be able to just hand off a go executable and be done with | it." And I think we can agree that the Python runtime situation | is far from this. | | I largely control my work environment, so this isn't a huge | issue for me. But I'm right at this very moment converting a | "python" to "python3" in a wrapper script because the | underlying code got converted to py3 and can't "import | configparser". (Actually, I'm removing "python" entirely and | adding a shebamg). | | I've been looking at writing a small tool in Python and then | porting it to Go (I don't know go, so seems like a reasonable | way to approach it), because the main target of the app is my | developers, who probably don't have the right Python | environment set up, and I just want them to be able to use it, | not give them a chore. | alexanderh wrote: | This is what I came to the comment section to say... You | absolutely can pin dependencies.... da fudge? | | Sounds like this guy needs to finish learning Python before he | learns something else. | | From what you suggested, to containerizing things with | something like Docker, there are ways to make Python more | easily distributable. | anacoluthe wrote: | What if the depedencies you pinned have non-pinned | depedencies? | | packageA==1.0.0 depends itself on packageB | | Therefore, you can find yourself with a different set of | deps. Had a bug like this once. | im3w1l wrote: | Pip freeze will pin explicit as well as transitive | dependencies | fnord123 wrote: | It's a hassle to do this correctly and upgrade the | dependencies. Use poetry. | robertlagrant wrote: | pip freeze > requirements.txt | shrimpx wrote: | > Pretty sure you can use == in requirements.txt | | You can, but one of those packages that you depend on will have | a loose version spec for one of _its_ dependencies, making your | `pip install -r requirements.txt` non-deterministic. | | Poetry and Pipenv solve this, though, by pinning all | dependencies in a lock file. | ActorNightly wrote: | Pip freeze will grab all of the versions that are installed. | AlphaSite wrote: | I 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 wrote: | But poetry requires pip... you can't use it without using pip | biorach wrote: | They clearly mean using pip on its own, presumably by `pip | freeze > requirements.txt` | gen220 wrote: | Poetry 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. | ryanianian wrote: | Kind of. It's intended to be a system package/tool. In that | regard you can use, wait for it, yet another python tool - | pipx. So instead of installing poetry to a venv or whatever | using pip, you can use `pipx run poetry`. Now you have to | install pipx... | jeremydw wrote: | This comment section itself clearly shows how crazy dependency | and environment management is in Python. In this thread alone, | we've received instructions to... | | - poetry | | - "Just pin the dependencies and use Docker" | | - pip freeze | | - Vendoring in dependency code | | - pipreqs | | - virtualenv | | This is simply a mess and it's handled much better in other | languages. I manage a small agency team and there are some | weeks where I feel like we need a full-time devops person to | just help resolve environment issues with Python projects | around the team. | okasaki wrote: | Sometimes I feel people are using Python very differently | than me. I just use pip freeze and virtualenv (these are | Python basics, not some exotic tools) and I feel it works | great. | | Granted, you don't get a nice executable, but it's still | miles ahead of C++ (people literally put their code into | header files so you don't have to link to a library), and | even modern languages like rust (stuff is always broken, or I | have some incompatible version, even when it builds it | doesn't work) | | By the way if you're a Python user, Nim is worth checking | out. It's compiled, fast and very low fuss kind of language | that looks a lot like Python. | fiddlerwoaroof wrote: | When I was a Python dev, I never saw that happen in ten | years or so of work. Pip freeze and virtualenv just worked | for me. | | I will say, though, that this only accounts for times where | you're not upgrading dependencies. Where I've always run | into issues in Python was when I decided to upgrade a | dependency and eventually trigger some impossible mess. | pdimitar wrote: | > _and even modern languages like rust (stuff is always | broken, or I have some incompatible version, even when it | builds it doesn 't work)_ | | Been working on and off with Rust for the last 3 years, | never happened to me once -- with the exception of the | Tokio async runtime that has breaking changes between | versions. Everything else always worked on the first try | (checked with tests, too). | | Comparing Python with C++ doesn't make do argument any | favours, and neither does stretching a single Rust accident | to mean the ecosystem is bad. | mcronce wrote: | This is consistent with my experience. Semantic | versioning is very very widely used in the Rust | ecosystem, so you're not looking at breaking changes | unless you select a different major version (or different | minor version, for 0.x crates) - which you have to do | manually, cargo will only automatically update | dependencies to versions which semver specifies should be | compatible. | | For crates that don't follow semver (which I'm fairly | certain I've encountered zero times) you can pin a | specific exact version. | tempest_ wrote: | Comparing anything to C++ is a very low bar. | | I have rarely encountered issues in rust. Most rust crates | stick to semver so you know when there will be a breaking | change. My rust experience with Cargo can only be described | as problem free(though I only develop for x86 linux). | | As for pip freeze and virtualenv things start to fall apart | especially quickly when you require various C/C++ | dependencies (which in various parts of the ecosystem is a | lot) as well as different python versions (if you are | supporting any kind of legacy software). This is also | assuming other people working on the same project have the | same python yadda yadda the list goes on, its not great. | fiddlerwoaroof wrote: | The issue I've encountered in rust is looking at a | library and seeing that it requires a nightly build of | the compiler. | ksdnjweusdnkl21 wrote: | I agree that it is handled better in many other languages. | However, Go has some weird thing with imports going on. When | I tried to learn it I just could not import a function from | another file. Some env variable making the program not find | the path. Many stackoverflow/reddit threads condecendenly | pointed to some setup guide in official docs which did not | fix or explain the situation. | | After an few hours or so of not making much progress in AOC | day 1 I just gave up and never continued learning Go. | Bullfight2Cond wrote: | one more that supports the latest standards: | https://pdm.fming.dev/ | SloopJon wrote: | This has indeed been eye opening. We got bit by a dependency | problem in which TensorFlow started pulling in an | incompatible version of protobuf. After reading these | comments, I don't think that pip freeze is quite what we | want, but poetry sounds promising. We have a relatively small | set of core dependencies, and a bunch of transitive | dependencies that just need to work, and which we sometimes | need to update for security fixes. | chpmrc wrote: | - Poetry is a 3rd party package manager, I'm sure it's great | but it's not widely used (yet) | | - Pip freeze just pins all dependencies at once to | requirements.txt | | - I don't know what "vendoring in dependency code" means | | - I've never used pipreqs in my life (and 80% of my work has | been in Python) | | - Virtualenvs are just a convenient way to keep project | runtimes separated | | And for 90% of Python projects in existence the following is | sufficient (assuming Python3 is installed): | | - python -m venv .venv | | - source .venv/bin/activate | | - pip install -r requirements.txt | | That's it. And all of that requires a single dependency: | Python. Could it be better? Sure. But to call that a "mess" | is an exaggeration. | linsomniac wrote: | "Vendoring" means including the library in your package. So | instead of listing it in requirements.txt, you copy the | code of the library. | korijn wrote: | Is it a mess? Yes. But, is the problem to be solved perhaps | much simpler "in other languages"? Do you interface with C++ | libraries, system-managed dependencies, and perhaps your GPU | in these other languages? Or are all your dependencies purely | coded in these other languages, making everything simpler? | | Of course the answer to these questions could be anything but | to me it feels like attacks on Python's package management | are usually cheap shots on a much much more complicated | problem domain than the "complainers" are typically aware of. | pdimitar wrote: | Or the "complainers" work with Rust and Elixir and giggle | at Python's last-century dependency-management woes, while | they run a command or two and can upgrade and/or pin their | dependencies and put that in version control and have | builds identical [to those on their dev machines] in their | CI/CD environment. | | -\\_(tsu)_/- | | Your comment hints that you are feeling personally attacked | when Python is criticized. Friendly unsolicited advice: | don't do that, it's not healthy for you. | | Python is a relic. Its popularity and integration with | super-strong C/C++ libraries has been carrying it for at | least the last 5 years, if not 10. There's no mystery: it's | a network effect. Quality is irrelevant when something is | popular. | | And yes I used Python. Hated it every time. I guess I have | to thank Python for learning bash scripting well. I still | ended up wasting less time. | Zopieux wrote: | It's a bit ironic to pick someone's up on "taking things | personally upon criticism", then proceeding to display a | deep, manichean, unfounded hatered for a language that, | despite its numerous flaws, remains a popular and useful | tool. | pdimitar wrote: | Hanging people upon dawn was popular as well; people even | got their kids for the event and it was happening | regularly. Popularity says nothing about quality or even | viability. | | Use Python if it's useful for you, obviously. To me | though the writing is on the wall -- it's on its loooong | and painful (due to people being in denial) way out. | | EDIT: I don't "hate"; it was a figure of speech. Our work | has no place for such emotions. I simply get "sick of" | (read: become weary of) something being preached as good | when it clearly is not, at least in purely technical | terms. And the "hate" is not at all unfounded. Choosing | to ignore what doesn't conform to your view is not an | argument. | ActorNightly wrote: | Its not a mess, people just make it a mess because of the | lack of understanding around it, and getting lazy with using | a combination of pip install, apt install, and whatever else. | Also, the problem is compounded by people using Mac to | develop, which have a different way of handling system wide | python installs from brew, and then trying to port that to | Linux. | takeda wrote: | Keep in mind that Python is 31 year old (it's even older than | Java) it was created around the same time as world wide web. | So it started when no one even knew they would need | dependency management and evolved over time from people | posting packages on their home pages, to a central website to | what we now call PyPI. Similarly the tooling and way of | packaging the code evolved. | | What you described are multiple tools that also target | different areas: | | > - poetry | | from what you listed this seems like the only tool that | actually takes care of dependency management | | > - "Just pin the dependencies and use Docker" | | this is standard fallback for all languages when people are | lazy and don't want to figure out how to handle the | dependencies | | > - pip freeze | | all this does it just lists currently installed packages in a | form that can be automatically read by pip | | > - Vendoring in dependency code | | this again is just a way that applies to all languages, and | it is still necessary even if there's a robust dependency | management as there are some cases where bundling everything | together is preferred | | > - pipreqs | | this is just a tool that scans your code and tells you what | dependencies you are using. You are really lost if you need a | tool to tell you what packages is your application is using, | but I suppose it can be useful for one offs if you inherit | some python code that wasn't using any dependence management. | | > - virtualenv | | this is just a method to have dependencies installed locally | in project directory instead per system. This was created | especially for development (although it can be used for | deployment as well) as people started working on multiple | services with different dependencies. It's now included in | python so it's more like a feature of the language. | feet wrote: | Even using conda to manage reqs is an absolute nightmare. Did | a subreq get updated? Did the author of the library pin that | subreq? No? Have fun hunting down which library needs to be | downgraded manually | MonkeyMalarky wrote: | I used a couple of tricks to solve this. First, make cond | env export a build step and environment.yml an artifact so | you've got a nice summary of what got installed. Second, | nightly builds so you aren't surprised by random package | upgrade errors the next time you commit code to your | project. | MonkeyMalarky wrote: | Don't forget Anaconda because you're on windows and have no | idea how to compile random packages that are really C++ code | with Python bindings! | jjoonathan wrote: | Solving environment | Solving environment / | Solving environment - Solving environment \ | Solving environment | ... | | One day it takes 10 seconds, next month it takes 10 | minutes, and the month after that it takes 30 minutes and | then fails entirely. | darkarmani wrote: | Are you using conda-forge? Solving from over 6TBs of | packages can take quite a while. Conda-forge builds | _everything_. This isn 't a criticism, but because of | that the number of packages is massive. | MonkeyMalarky wrote: | That's half of why from 2017 to 2021 I had a yearly | "uninstall Anaconda and start fresh" routine. The other | half is because I'd eventually corrupt my environments | and have no choice but to start over. | jjoonathan wrote: | Me too. In 2021 it got so egregious that I finally jumped | ship. Pip or bust. | | Since you specifically mentioned 2021 instead of 2022, I | half suspect you had the same experience. | punnerud wrote: | Not a mess, but options. That's what's encourage innovation | and open up for new ideas. | | This Fortran vs Python example is worth reading: | https://cerfacs.fr/coop/fortran-vs-python | throwawaymaths wrote: | Now try installing tensorflow. Treat yourself to ice cream if | you get it to install without having to reinstall Linux and | without borking the active project you're on. | derac wrote: | The major issues you'll see involve library version | mismatches. It's a very good idea to use venv with these | tools since there are often mismatches between projects. | raffraffraff wrote: | And unless things have gotten a lot better in the 2 years | since I last did `pip install numpy` on ARM, prepare for a | very long wait because you'll be building it from source. | Gordonjcp wrote: | It's not crazy at all. You use requirements.txt to keep a | track of the dependencies needed for development, and you put | the dependencies needed to build and install a package into | setup.py where the packaging script can get it. | | These are two different things, because they do two different | jobs. | | It's really very simple. | dagw wrote: | _Also, its very possible, and quite easy to just include the | code for the library in your package_ | | This only works if installing on exactly the same os and | architecture. It can also make the installer for your quick | little command line tool hundreds of megabytes. | | That being said packing up the python interpreter and all | dependencies is the approach I ended up using when shipping | non-trivial python applications in the past. | iasay wrote: | That's fine until it wont compile on someone else's machine. | Had that many times before with python. | | SciPy is a bastard on macs for example. | geraneum wrote: | On the other hand tools on par with SciPy are not common in | other languages. | jossclimb wrote: | Yep, I have no idea how they do not even understand the basics | of python dependency management. pip freeze > requirements.txt | will do it all for you. No wonder they found rust to hard. | shrimpx wrote: | Your dismissal of the author is unwarranted. | | You can do you want you suggest, but it's an operational pain | in the ass. You need to maintain two files, the actual | requirements.txt and the `pip freeze` one that locks the | environment. And you better never `pip install` anything by | hand or you'll capture random packages in your frozen file, | or else always take care to create your frozen file in a | fresh virtualenv. And if you don't want to install your dev | packages into the production environment, then you need to | maintain two requirements.txt and two of those frozen files. | | The author mentions Poetry which does solve these issues with | a nice interface. | vietthan wrote: | recommend pipreqs | fnord123 wrote: | `pip freeze > requirements.txt` will generate a lock file. | You want a requirements listing as well as a lock file (like | rust, poetry, golang, npm, ruby). | [deleted] | syassami wrote: | You can go even further now with PEP508 | https://peps.python.org/pep-0508/ | Areibman wrote: | > 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 wrote: | The 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/... | wodenokoto wrote: | I 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. | barefeg wrote: | How to combine both languages as he suggests? I.e. creating | python binds for the go binary? What about the opposite? | arccy wrote: | you could do something like | https://www.datadoghq.com/blog/engineering/cgo-and-python/ | kitd wrote: | Nim operates in the same space as Go, but with a syntax very | much in the spirit of Python. | | https://nim-lang.org/ | pojzon wrote: | About unused imports, cannot you simply use formatter on build | hook ? | travisgriggs wrote: | I 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. | linsomniac wrote: | TL;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 wrote: | I'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 wrote: | Maybe there's a go library that implements that "kill but | make it look like an accident" functionality on HN a few days | ago? :-) | bumper_crop wrote: | > 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. | brodouevencode wrote: | Organizing 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 wrote: | Is 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. | DandyDev wrote: | Directories with an __init__.py are not modules, they are | packages. Modules are .py files | morelisp wrote: | The __init__.py is also itself a module, which you import | by importing the package. That's confusing, and not easily | avoided! | LtWorf wrote: | Make it an empty file? | Scarblac wrote: | > 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). | tandav wrote: | Still necessary for mypy (if you want type checks) and | setuptools (if you want to publish library to pypi) | morelisp wrote: | Thanks, I went from a lifetime of Python 2.7 straight to | 3.8 and missed this. | kccqzy wrote: | With python you can also go pretty far without __init__.py | IMO. Just put everything in a single directory. | morelisp wrote: | Beginners 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. | jamal-kumar wrote: | I always felt that the official documentation is pretty | excellent (Worth a re-read if you haven't in a while): | | Code organization: https://go.dev/doc/code | | Pretty much everything else you should know: | https://go.dev/doc/effective_go | | There's one thing I think that people getting started with this | language should know and that's in the pursuit of getting the | stuff you mentioned right, is making sure the reference | material (blog post, book, whatever it is) you're reading is | something written within the past two or three years. The | official site really has enough that you need to know in order | to have good knowledge coverage, but the module system beyond | version 1.16 especially is something you need to get right and | which a ton of old information is out of date on: | | https://go.dev/doc/modules/developing | Uptrenda wrote: | I 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. | [deleted] | loosescrews wrote: | While 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 wrote: | I 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. | JustSomeNobody wrote: | On 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. | erik_seaberg wrote: | Tooling 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. | vippy wrote: | aidenn0 wrote: | I 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 wrote: | I 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. | aidenn0 wrote: | I don't use Go at all, but TFA was concerned with pinning | dependencies, and stuff like this makes dependency pinning | much more important ___________________________________________________________________ (page generated 2022-07-18 23:00 UTC)