There are two reasons I am not in favor of python. First and foremost its packaging sucks.
I have wasted far too much time wrangling pythons packaging systems. Incompatibilities between pip, setuputils, distutils, virtualenv, eggs, C modules, and wheels I have literally given up. I love and use python but I no longer package it and deploy it for others to consume. Try to package a protobuf3/grpc system these days into a .deb, its a nightmare. Even the grpcio devs use docker containers to build packages because python has such a nightmare of a system.
I'll leave the second reason out for the sake of context
Bad example IMHO as grpc building is painful even with 0 involvement of Python. That is, If you have any prerequirements either for build environment or 3rd party libraries. And while I did get things done in reasonable time, while doing research I noticed quite a lot of people where echoing about same thing.
Ruby has one packaging format that is essentially unchanged since 2004: RubyGems. There have been improvements in making it easier to convert a gem to a native package since then (even though I think that’s a fool’s errand), but the fundamental packaging system hasn’t changed (although indexing and serving has).
As someone who mainly works with other programming languages, I feel like the "obvious way to do it" was always the way Pipenv and its Pipfiles handle things, and it finally arrived.
It's not the first time I say this, but I think it's crazy how long some package ecosystems live without a "sane" package manager, and how recently those even appeared.
Pipenv is definitely a game changer. Soon enough the Anaconda distribution wouldn't be necessary to get the SciPy stack installed on Windows[1], pipenv would just work™. This would enable sharing of Jupyter Notebooks backed by deterministic environments that work even on Windows, which is awesome :)
[1] -- http://abhirag.in/articles/pipenv_win.html
Haha. I tried to dig up a change note for it but couldn’t find one quickly on mobile. I think at least it only hit the Debian stable repos within the past month or two.
There is one -- and preferably only one -- obvious way to do it[1]. The trouble is that it's steeped in 1990s assumptions about system administration, user knowledge, and deployment environments.
[1]: You put the third party code in /usr/local/lib/pythonX.Y/site-packages.
We knew[1] it was wrong in the 1990s, but /usr/local is a "best practice", and these people who believe "best practices" are more important than solid engineering breed faster.
The Zen of Python just says that there is one and preferably only one obvious way to do it. It doesn't say anything about whether that way is right or wrong.
Funny to see the name Alice in the context of Python. Alice [1][2] is a Python-based environment for creating animated, interactive 3D scenes, created by Randy Pausch and his students. They picked python intentionally for its simplicity at a time when it wasn't yet well known.
I write both python and haskell for my day job. I think the latter has much better project management when it's paired with Nix. Even without Nix, stackage and even just dealing with Cabal is much easier than the mess in the Python ecosystem.
The stability of the Haskell ecosystem is something I just can not understand.
It's not enforced by policies, the tooling isn't much more helpful than in any other language, and it is not more mature than any widely used ecosystem. It feels like Haskell libraries just need less changes.
In my opinion it's because Haskell sits at the intersection of a lot of high power-to-weight-ratio features that let you build very robust and expressive pieces of functionality at any abstraction level. That means that libraries can easily build on each other. A lot of cool gadgets in Haskell would have to be built into Python at the language level to be usable (note the proliferation of keywords in Python..).
(I've never seriously used Haskell) I wonder if the strong static typing has something to do with that. That eliminates many if the common bugs found in Python programs.
Perhaps because someone got into the (bad) habit of returning Nones instead of raising errors. Errors should never pass silently, etc. The older Python APIs have that C habit of sentinel values, but more modern style is to raise an error on failure.
Functions implicitly returns None if you forget to provide a return value on any of the branches. This is an error that can easily slip past eyeball reviews, since this is caused by the absence of something.
I don't think it's strong types either. It is not about the libraries having less bugs, but about they keeping compatibility for much longer (and when they break it, they tend to break in smaller ways).
Could be because of extra flexibility those types grant you, but it's not about bugs.
Come on, you only have to take a look at the javascript ecosystem to know what I´m talking about. Tenths of bundlers, a cuple of good dependency resolvers, a myriad of test frameworks, etc... In python you are lucky if you have one of each.
Very good writing indeed. However, the metaphor here gives me the feeling of "enough internet today"...
Btw, the anchor link to #project-structure don't work. Hope you (if you are the author) fix that soon.
Yeah, it's written slightly badly, but it means if you don't include that block then nothing will run. The way it's written makes it seem like using the ifmain construct isn't optional, which isn't a terrible thing to teach.
The "python hides the hurt" example isn't great. First, he's missing the imports on the python side (which can be just as verbose as java imports). Second, he's talking 10 lines of code in java (plus closing braces) vs 6 in python, but with a little bit of tweaking you could easily drop 2 of those lines in Java. Third, if you were to import guava or some other library that makes handling files more streamlined, you could get to an equivalent number of lines in the Java example.
> Third, if you were to import guava or some other library that makes handling files more streamlined, you could get to an equivalent number of lines in the Java example.
You don't even need that. The Files[1] class - which has been in the standard library since at least Java 7 - makes this really easy to do.
Why are you optimizing the LOC only for Java? With a little bit of tweaking, Python can do the whole thing in 2 lines -- no imports, libraries or closing braces needed:
with open('alice.txt') as inp, open('new_alice.txt', 'w') as out:
out.write('\n'.join([line.rstrip().replace('Alice', 'Dora the Explorer') for line in inp]))
The author's point is that Java is verbose and requires a lot of boilerplate, which has benefits and drawbacks. I think her example does a decent job of illustrating that.
This was really helpful for me, someone who does Ruby most of the time. The programming parts of Python aren't hard, but I'm simply unfamiliar with the layout of things.
https://en.wikipedia.org/wiki/Zen_of_Python