Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

i personally can't get past it. i've hated every second of developing in python in my jobs, and i just sit there wondering how nice it would be if i could move off of it, especially when debugging and finding yet another inane design decision in python or something that doesn't work. there's never been a reason to use it other than that's what someone unfamiliar with better choices chose for the project, and there's typically a very objective multiplier in risk and time in the development by sticking with python. moving to clojure, racket, f#, elixir, etc. would almost always be a better choice aside from certain uses of python-specific libraries (like for machine learning).


The vast ecosystem of python libraries is an incredibly powerful argument for using it. One major library could dramatically cut the development time of your project.

You’ve not spelt out actual reasons why Python is so bad, could you give your top three?


One thing I have felt is that python doesn't embrace the functional way of thinking, even to the extent that JavaScript does. I personally find that once I have been exposed to a modern functional approach like in Clojure, etc, I find python lacking. Not just syntactically, but conceptually. For example, IIRC, many list methods in python modify the list they are working on, instead of returning a new list.


In line with this, list comprehensions are one area of python I find particularly clunky. They work fairly well for a single map or filter operation, alright for both mapping and filtering, and are absolutely unreadable for anything more complicated. A big part of this in my opinion is how they scramble the flow. Instead of taking a piece of data and performing successive operations on it, both in logic and in syntax, you have their 'literate' mess that requires you to start reading in the middle of the line and alternate moving your cursor back and forth.

Consider:

getNumbers() .map(x => x×2) .filter(x => x % 6 == 0) .map(x => x^2)

get numbers. double them. filter for divisibility by 6. square them.

versus

[x^2 for x in x×2 for x in getNumbers() if x % 6 == 0]

get the square of the doubles version of getNumbers values, but only if those doubles are dividable by 6. But wait are the doubles dividable by 6 or the squares?

Maybe some people are fine with looking at what operations are being performed on the data before even knowing what the data itself is, but that for me seems incredibly backwards. Plus it also gives rise to order of operations ambiguities. Nobody could mistake the ordering in JS, but I honestly have no clue how that python would evaluate.

(using carats because hn cant format code)

Edit- This came to mind because of a flattening list comprehension I encountered earlier today:

#flatten the lists

flattened_list = [y for x in list_of_lists for y in x]

I've spent quite some time staring at this and I still have no clue what it's actually doing. I've never had that with JS operator chains.


Python’s list comprehension syntax is based on the set-builder notation from mathematics. However, I think it would have been better to break with tradition and use a different order, one which matches the order of the equivalent nested loops:

    flattened_list = [for x in list_of_lists: for y in x: y]
This is essentially the same re-arrangement that was made in C#‘s LINQ: it uses from-where-select instead of SQL’s select-from-where.


Isn’t set builder notation done in the opposite direction at least? Ie given these things which are elements of blah, take these values. In Python it’s reverse, which makes sense in English but is harder to read as a sequence of steps: take these values from this set but only if... Kinda like SQL: select from where

I prefer it as a sequence of steps that get performed one after the other like a pipeline.


This looks nice for this case but I don’t think filter would work properly. JS is much more similar to Linq and people seem to love linq. I don’t know of anyone else that does it like python, but plenty do it like JS. For me that tells you all you need to know about whether it’s actually a good idea.

Edit: SQL does it a bit like python and it’s a massive pain in my opinion (and the opinions of many others I’ve talked to). Msft agreed so they made Kusto which does it like JS and everyone I’ve spoken with vastly prefers it.

(Work at msft, no info on the actual business reasons behind kusto, etc etc.)


map(lambda x:x^2, filter(lambda x:x%6==0, map(lambda x: x*2, getNumbers())))

Would probably be a more pythonic way to do that, avoiding list comprehensions. Easier to read with added lines and indentation.

But tbf I do appreciate the ability to chain operations in JS without subclassing objects like list.


Funny how 'pythonic' can mean different things to different people. I've been developing in python on and off for the best part of a decade, and in my world comprehensions are considered far more 'pythonic' than map/filter/lambda.


Also this is still confusing because you need to read it backwards. Pipelines are just better in every way, if you ask me.


You’re saying it’d be more Pythonic to not use list comprehensions? I find that doubtful.


Quick example off the top of my head is the built-in sorted function. That returns a new list if I'm not mistaken.


What I had in mind was the append function, it modifies the list instead of creating a new list.


> The vast ecosystem of python libraries is an incredibly powerful argument for using it.

vast ecosystems exist in other languages as well. python is not magically the only language that has libraries. in my experience, python libraries exist but aren't great and lead to issues. also in my experience, .net libraries often exist alongside the python libraries, and in many cases companies often provide C/C++ DLLs or .NET assemblies more often than Python APIs.

> One major library could dramatically cut the development time of your project.

in my experience, the half-baked nature of python libraries actually increased development time.

> You’ve not spelt out actual reasons why Python is so bad, could you give your top three?

thanks for asking this rather than indiscriminately downvoting. my reasons are:

* the module system is a mess and can hardly be called a system. anything greater than a few scripts and modules becomes a mess, whereas other languages have much better module and project systems (the latter of which python doesn't even have). the module system in python is little more than a hack just barely exceeding file path linking.

* pip is a mess.

* the python 2 vs 3 issue is trivialized by people, but it is anything but trivial in practice. the first python codebase i worked against was using an internal tool at a large company. they were actually using python 2.6, and it was me, a new user, who pushed them to use 2.7 (which didn't happen before i left). the next system i worked on was also using 2.6 at another company, and i upgraded them to 2.7. the installation procedure for the python packages was a mess (see the module system and pip being a mess). upgrading them to python 3 was a non-starter and on further projects, they ignored my suggestions to them (i wasn't working on the system) to upgrade to python 3 because they didn't see the reason to. next system was also in python 2.7, and due to package obsolescence and deprecation and version jumps, the entire codebase basically required being rewritten in python 3 and newer packages.

* the ecosystem isn't as complete or robust as people imply. even python's built-in XML parsing library has many issues and lack of features, and i have even seen differing behavior between linux and windows.

* python the language is most simply described as unprincipled. there are surprises and gotchas everywhere. for example, the following generates a run-time error:

  def now():
    return "now"

  def usage():
    now = now()
    return now + "!"
the error is "UnboundLocalError: local variable 'now' referenced before assignment". now do the same in f# or racket or any other sane language in which expressions return values which are then bound sanely to identifiers. python is full of stuff like this. if you've used more sanely defined languages, coming to python is actually quite complicated because it is so unprincipled. it does not have a small core base layer that allows for predictable code.

* python has no consistent way to write asynchronous or concurrent code and has major limitations on whether the code you write is actually concurrent. i've done a lot of concurrent code. when i learned elixir/erlang, it was so easy to understand (many python people probably consider elixir/erlang to be more complicated than python), but when i tried to learn asyncio in python, it felt very complicated. there are tons of caveats right off the bat, and it is completely different than other ways of writing concurrent programs in python.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: