11 ms·
Python is not a great programming language
- skinkestek 7y agoI think I agree. Here are a couple of more, from someone who has worked for years in a number of languages: - few limitations means you can easily make a serious mess, which means you are more dependent on good programmers to avoid the mess. - lack of typing information isn't "free solo" hard but it certainly makes life a lot less pleasant.
- JNRowe 7y ago> lack of typing information isn't "free solo" hard but it certainly makes life a lot less pleasant. One of the projects I work on has switched to full type hinting along with heavy mypy¹ usage, and it has become an absolute pleasure to work with. Along with hypothesis², I can't recommend mypy enough. It must be said that retrofitting either to an existing project is a lot of work though. 1. http://www.mypy-lang.org/ http://www.mypy-lang.org/ 2. https://github.com/HypothesisWorks/hypothesis https://github.com/HypothesisWorks/hypothesis
- totalperspectiv 7y agoWhat I can't reconcile with myself is, if I'm going to add type hinting in Python, why not use a language where my efforts of adding type hints result in performance gains? I get why it's nice for a team, but it seems like a lot of work for half the potential benefit of a typed language.
- j88439h84 7y agoI think that sort of thing is coming, with e.g. `mypyc` that compiles typed Python into C.
- mixmastamyk 7y agoCython can. However, machine performance doesn’t matter a lot of the time.
- mattlondon 7y agoI note with interest that modern python has type hints. Years ago the lack of visible types was often flouted as a benefit (i.e. terser code, less boiler plate, easier for learners to understand etc). I eagerly await the addition of optional "scope hints" of { and } ! ;-) Sarcasm aside, now that there are type hints and python programmers need to type as much as Java/golang/c# programmers, why not just write in those languages? Genuine question - what are the benefits of starting something new in python (assuming all things being equal - i.e. equal knowledge in java/golang/c# and no legacy reasons forcing you)? Why would anyone pick writing type-hinted python Vs a fully explicitly typed compiled language?
- JNRowe 7y ago> I eagerly await the addition of optional "scope hints" Scope hinting is simply called braces; `from __future__ import braces`. > Genuine question ... IMO assuming all things are equal seems to miss how things actually are. The pluses still fall on Python some times, and other languages at other times. Things do vary; developer availability, library availability, target system support, certification story, tooling, even curbside appeal can be legitimate on some occasions. I'm trying not to pick on your individual language examples, as firing digs seems to be missing the point we're discussing. Or perhaps it is the very point, as two of them wouldn't have even been in my list.
- JNRowe 7y agoI /feel/ like this gist is largely on the money, and also uninteresting at the same time. All languages suck, and often suck in different ways for different users. We just have to pick the one that is working best at the time, and that we're best at working with. I will say that I do like the act of writing a pro and con list for a language or tool though(which is why I read the linked doc), and I often push co-workers to do so when they're suggesting things. Sometimes it shakes a bad choice out just with the simple act of jotting down a 5-point list. Unless, of course, there actually is an ideal language out there. In which case I retract my point ;)
- juped 7y agoThere is, and it starts with L. (Lua, of course.)
- verdverm 7y agoI love Rob Pikes idea that is dumb to have scope determined by invisible characters
- 52-6F-62 7y agoI don’t totally mind it. Poor PEP8 implementations can drive me nuts and so can the type of indentation allowed. But otherwise I can get over it. And then there’s Bython... https://github.com/mathialo/bython https://github.com/mathialo/bython
- polotics 7y agoSpace is visible to me.
- siekmanj 7y agoPython doesn’t really have scope in that way. Variables declared inside an if statement can be accessed outside of the if statement.
- somebodythere 7y agoControl-flow blocks aren't scoped in most popular programming languages.
- mlevental 7y agoname one except python
- deleted 7y ago[deleted]
- TheOtherHobbes 7y agoIt makes scope visual and consistent. IMO it's less dumb than having scope defined by pairs of curly braces which are impossible to read without indentation and require extra effort to keep matched - unless you try to automate the matching with a good IDE.
- polotics 7y agoThis list is so deliciously sophomoric. The best one is, and I quote: """To many other weirdo bits of magic syntax, like [list comprehensions]""" Obviously without actually proposing how comprehensions could be made better one has to hope the author would say he likes the equivalent Haskell better, but there is a strong doubt that is not the case.
- Areading314 7y agoComplaining about having to cast generators to list... seems like the kind of dev that has their code randomly run out of memory until a senior dev comes and fixes it.
- nnq 7y agoIt is annoying! And doesn't always save memory. In theory a "sufficiently smart language" should have a feature to understand that `thing[3]` can be translated to "call `next()` 3 times and gimme the last thing", not in "turn this completely to a list, that may take a ton of memory, although I only need that one third element". Generators should be treatable as lazy lists in the end, and lists should have a common interface whether they are lazy or eager. Someone should figure out a way to have us write code at a higher abstraction level and have same interface for lazy vs eager data structures. ...but it's not gonna happen in a dynamic language like Python. And I can't say I like the "solution" of having the entire language be lazy like Haskell either :| We're stuck with "casting generators" for now, I guess, but it really does suck!
- Cpoll 7y agoYou don't need to cast the generator, you can do: next(itertools.islice(my_generator, n, n+1)) With that said... > In theory a "sufficiently smart language" should have a feature to understand that `thing[3]` can be translated to "call `next()` 3 times This might be a newbie trap, because next() isn't the same as indexing. What happens if I perform `thing[7]` followed by `thing[5]`? Should performing `thing[7]` put 1-6 in memory and turn the object into a generator-list hybrid?
- tgv 7y agoDjango is ok if you have a web site with content and forms that map nicely onto SQL tables. Any 1998 website, basically, with not too much of a load. Any other setup, and it gets messy. > Needing to put dict property names `{'in': 'quotes'}. Now that's a part I like.
- TylerE 7y agoThe inclusion of that made me question the entire thing. It's just so...wrong. Does the author not realize that you can use (almost) anything as a dict key? a = 123 b = 'foo' d = {a:456, b:123, 2.3:'2.3'} print(d) >>> {123: 456, 'foo': 123, 2.3: '2.3'}
- droithomme 7y agoIt seems he just doesn't want to type quotes and is OK with breaking everything else to get that. Which is fine, but no one else supports that change request.
- coldtea 7y ago>Does the author not realize that you can use (almost) anything as a dict key? You can do that in JS too, it's just coerced to string, so you can do e.g. {foo: "bar"} where foo is not a variable, but assumed to be the string foo. In Python you can't, because you couldn't tell if it's foo the string, or a reference to an existing (or non-existing) foo variable. That said, in JS, not only you're limited to using (real or coerced) strings as keys to Objects, but you also need to use the square bracket: {[foo]: "bar"} syntax, so it can tell that you need it to use the value of the variable foo as the key (else it will understand {"foo": "bar"}).
- TylerE 7y agoThat's different though. In python there is no coercion going on with the keys.
- diminoten 7y agoGraphene + React is just fine.
- tanilama 7y agoSo be it. It is useful nevertheless.
- tomp 7y ago> a big part of my frustration comes from having a JavaScript background Yeah, I thought so when I was reading the list of "problems". In fact, many of those are features (e.g. lists & tuples being different, list comprehensions, lazy evaluation, distinction between maps/dicts and objects, ...) but the author doesn't actually understand them. I hate to sound so negative, I guess I just didn't realize how bad a programmer knowing (only/mainly) JavaScript causes you to be.
- ng12 7y agoHow about how condescending of a programmer not knowing JS causes you to be :-) Either way, if the number of idiosyncracies in your language is confusing to junior developers it's absolutely something worth considering.
- throwaway1777 7y agoJavaScript is full of idiosyncrasies.
- smitty1e 7y agoWhat drives me nuts about doing JS is that the browser execution model seems vague. In python, I can have the if __name__=='__main__': main() at the end if a script, and easily import the script's functions into - pytest for testing - some other module for larger modules - into a cli.py file to slap a Click interface on it. What a great blend of flexibility while retaining coherence.
- echelon 7y agoComplaining about things you don't understand is pretty bad practice. The parent poster was pointing that out. Sure, the Javascript dig is unnecessary, but the language currently holds a position as the spot of first language many junior engineers employ.
- marcinzm 7y ago>Either way, if the number of idiosyncracies in your language is confusing to junior developers it's absolutely something worth considering. Why? Aiming for the lowest common denominators and the simplest systems tends to not create scalable long term solutions. You also seem to really undercount what a properly trained junior developer is capable of understanding.
- stevebmark 7y agoThese all just seem related to syntax, not actual program structure or capabilities. The only program structure thing I see is list comprehensions, which is one of Python's great strengths. Ironically they say Ruby is more pleasant to write, when Ruby has the deepest structural flaws of any dynamic programming language.
- opn7d7 7y agoWell in an industry where people are often “Code should be written to make sense for humans first, machines second.“ syntax concerns seem pretty valid. As a Python coder going back to 2008, I can see the point the author makes in isolation. I disagree with the title though. Even though I mostly write Rust, Go, and C anymore, I am fine with digging into Python as needed. I cringe at thoughts of using Ruby or JS
- manch23 7y agoI’ve always been super happy using Ruby. Never had any experiences that would cause me to label it in the way that you have. However, I am interested to know what those flaws are. Could you elaborate?
- kiaulen 7y agoDisclaimer: I do ruby for my day job, and python for fun Disclaimer 2: I don't hate ruby, despite all these criticisms. If I had to pick a worst dynamic language it would be PHP. Things I don't like about ruby: - two string types, symbol and string, with string being the mutable by default one. This means given a random thing back from an api, you don't know whether to do thing[:id], thing["id"], or thing.id This has been acknowledged as a pain point by Matz, which is why in ruby 3 strings will be immutable by default. - Simultaneously too many names for things and not enough. Is it .length or .size or .capacity (probably not capacity)? is_a?, kind_of?, or instance_of?? Why can I do .select or .keep_if but not .filter? - Too many function types. Do you want a method, a block, a proc, or a lambda? There are subtle differences between each, so choose wisely. I'll note that python suffers from this too (method, function, lambda, comprehension). - Too much emphasis on magic Novice rubyists get frequently bitten by all the advanced (and very hard to google) ruby concepts. How do you know what arr.map(&:id) is without already knowing that it's calling symbol.to_proc? How about $1 $? $! (if you know what all these do, you're a better rubyist than I am). Since the author of the referenced post criticizes django for being too magical, try rails. In addition to the names of files mattering a ton, there's the routes DSL, the migrations DSL (which is not well specified in the guides), and ActiveSupport, which you only realize you're using when it's gone. - Horrible error messages undefined method :[] for nil:NilClass (when you try to get something out of a hash and it's nil) cannot convert Symbol into Integer (this is on an array being returned where a hash is expected) Also, if you get a stack trace, it's completely inscrutable. Python's stack traces (at least ipython's) show you both the line number and the line in question (often with context).
- sys_64738 7y agoIt doesn't matter about its quirks. The most important thing nowadays is that it's reached critical mass. We're at the point where even non-developers can now cobble together a bit of python code to do simple things to make their jobs easier. This means it's here forever, IMO.
- FpUser 7y agoI remember our salesmen back in 90's cobbling together some Visual Basic or whatever it was called. So where it is now?
- zekrioca 7y agoHas the same happened to Python yet? No? So bookmark this thread, and come back in here when the very same happens to Python :)
- FpUser 7y agoI just made a note. I do not really give a flying hoot to what happens to Python. I only use it in places I do some consulting since they require it. I do not use it for my own products.
- sys_64738 7y agoDid Microsoft not kill VB in the 2000s? I could be wrong.
- jbdigriz 7y agoI'm not disagreeing with this, but you'd be surprised just how much VB still exists in the wild. Literally billions of dollars in revenues in financial service industry alone. Some trading desks use VB and Excel for the majority of trading. It's an abomination of epic proportions and well beyond critical mass, but it still exists precisely because of the reasons you mention - non-developers with some technical competency depending on it. Whole other debate on benefits and drawbacks if this sort if thing however..
- diminoten 7y agoYou can write your dicts as keyword args to the dict() cast if you don't like putting your keys in quotes, but it looks like shit. There are two paths to take when one encounters something new; adapt and learn, or reject and mock. This sounds like the latter.
- RootKitBeerCat 7y agoI think the adage goes “Python is the best at being the second best at... almost everything”
- folkhack 7y agoI've never heard that one, and not going to take a stance... but I WILL make the argument that if true, that's a HUGE strength!
- aeyes 7y ago> The syntax for classical inheritance. Half of each Django app is super().__init__(args, *kwargs) Care to show proof? I don't see this a lot. The code of the official Django site for example has 8 occurences: https://github.com/django/djangoproject.com/search?q=super+__init__&unscoped_q=super+__init__ https://github.com/django/djangoproject.com/search?q=super+_...
- meow_mix 7y agoThis is so surface level it's not even worth addressing
- elan3 7y agoyeah i agree, it is so weird to see that python is the only language that haven't implemented in its own language atleast to my knowledge
- progval 7y agoThat's not what the article is about. And most interpreted languages (bash, ruby, perl, JS, ...) are not implemented in themselves, because it makes no sense (who interprets the interpreter?). However, Pypy is a Python interpreter that is written in (a compiled subset of) Python 2.
- j88439h84 7y agoSure Python has many problems, but these aren't a great selection. > The syntax for classical inheritance. Half of each Django app is super().__init__(args, *kwargs). At least you don't have to pass arguments to super anymore. Yes, inheritance is hard to do well, but that's generally true. Much better to prefer composition (https://en.wikipedia.org/wiki/Composition_over_inheritance https://en.wikipedia.org/wiki/Composition_over_inheritance) > Too many magic __double-underscore__ methods and properties that you have to just memorize. Better to just start using http://attrs.org http://attrs.org or dataclasses so you don't have to do all the manual work. Classes without boilerplate. > Too many top-level built-in functions that (a) you have to just memorize, and (b) get really ugly. You end up with stuff like list(map(...)). I haven't used so many nested parentheses since my early days in PHP. Guido's explanation makes sense in theory, but is really annoying in practice. I agree, there should be a pipeline operator |> like F# has. A similar proposal has been made for JS. https://github.com/tc39/proposal-pipeline-operator https://github.com/tc39/proposal-pipeline-operator > Too many other weirdo bits of magic syntax, like [list comprehensions]. List comprehensions are good, they just take 5 minutes of getting used to. > Django specifically is so full of magic words, and its documentation is so convoluted, that I've basically given up on documentation altogether and just look at the Django source code now. Pyramid has a much more principled design IMHO. https://trypyramid.com/ https://trypyramid.com/ > Needing to put dict property names `{'in': 'quotes'}. Or use `dict(foo=5)`. Python mappings can contain non-string keys, so `{5: 1.2, 6: 3.4}` maps ints to floats. > You have to cast your data back to a list/tuple after using enumerate() and map(). Don't use map, use comprehensions. > Different syntaxes for lists and tuples. They are different objects, why would they have the same syntax? > foo['bar'] returns a KeyError, so you have to do foo.get('bar')... or in some cases getattr(foo, 'bar', None), but not in others because getattr and .get are different things. Python is a different language from Javascript. > You can't just tack on flags to /regular_expressions/ig. Yeah that's annoying. > All the goofy string literals: f' ', u' ', r' ', etc. That's a good thing, not a bad thing. > Pipfile does not work that well. Poetry works better. https://poetry.eustace.io https://poetry.eustace.io
- Animats 7y agoSure Python has many problems, but these aren't a great selection. Yes. I have my disagreements with Python, but those are not it. The article author is mostly complaining about ways Python differs from Javascript. - Agree that the mechanism for talking about parent classes wasn't very good. Multiple inheritance usually adds complication without adding much necessary functionality. That's not just a Python problem. It's a leftover from viewing objects through an "A is-a B" lens, one of the dead ends of early AI. - Python has too much gratuitous dynamism. Any thread can find and mess with any code and data in another thread. The implementation has to support that, which knocks out many valuable optimizations. The language model, and the original implementation, use "everything is a dict", which implies "slow". - One consequence of the above is Python's terrible one thread at a time thread system, with the "global interpreter lock". The "multiprocessing" hack to get around that is ugly and uses too much memory, since each subprocess has its very own Python system instance. To some extent, the "async" add on is yet another hack to get around the limits of threading. - Another consequence is a tendency to call C code where Python performance is terrible. The C code has to carefully obey the rules of the Python system. Mostly it does. - Optional typing is a marginal idea, but unchecked marginal typing is just weird. Language design seems to be converging on implicit static typing - result variables are automatically typed whenever possible. Go, Rust, and now C++ (with "auto") took that route. - And, of course, the botched Python 2 to 3 transition set Python back for a decade. On the other hand, Python exceptions work out well. A reasonably sane exception hierarchy helps. Although the one for 2.x was better than the one for 3.x; the 2.x one made a clear distinction between external problems ("Environment errors") and internal problems. The "with" clause system plays well with exceptions, and nested exception failures unwind correctly. It's far better than Go's "defer". C++ and Rust try to handle this sort of thing with RAII, which never handles trouble in a destructor well.
- juped 7y agoI wish more languages did something like the D feature where method syntax and function syntax are really just syntax - i.e., str.len() is equivalent to len(str), and you use the syntax that best improves readability at your call site.
- turbinerneiter 7y agohttps://en.m.wikipedia.org/wiki/Uniform_Function_Call_Syntax https://en.m.wikipedia.org/wiki/Uniform_Function_Call_Syntax Called uniform function call syntax, an I idea I first saw in Nim and found really cool, but then found really dumb. Can't remember the reasoning for both opinions, which is a strong indicator of "probably doesn't matter". For a while I was entertaining a thought regarding mutability and returning copy's. Like foo.bar() would mutate, bar(foo) return a modified copy. Don't know if that concept has a name or if it actually makes sense at all.
- im3w1l 7y agoMaybe it's fine, but I'd be concerned about polluting the global namespace
- etbebl 7y agoMATLAB of all languages does this! Although as usual it's quirky about performance: the foo(bar) syntax (which used to be the only syntax) is faster.
- kendallpark 7y agoSomething not mentioned in list that I had never considered until a conversation last year: meaningful whitespace is biased towards sighted programmers. According to a blind acquaintance, it is much easier to keep track of opening and closing parentheses and braces. Meaningful whitespace forces blind programmers to always check the number of tabs at the beginning of each line to make sure scope hasn't changed.
- xhgdvjky 7y agoeven if you can see, it's harder to copy paste. which could be a feature or a bug
- detaro 7y agoInteresting aspect. Kind of sad that our tooling is typically too simple to map something like this: Having cues for indentation changing would be easy, but it's a niche feature and thus probably won't be there.
- im3w1l 7y agoCouldn't whatever tool they use just apply a transformation from indentation change to brace?
- hannibalhorn 7y agoJack of all trades, master of none. The article has a silly premise - I don't know anybody who would claim it's a great programming language. For the moment, it's just the most practical in certain areas (notably data science and machine learning.)
- Stubb 7y agoPython's power comes from the fantastic array of libraries to which it provides access. Much of my Python coding involves stringing together calls to SciPy, Matplotlib, lxml, and the like. It's a super productive language so long as you don't need multithreaded performance.
- FpUser 7y agoToo bad you can not use it to write those libraries ;)
- FpUser 7y agoI know a company, they have a floor filled with developers who think that Python is the best thing since sliced bread and any other language is abomination
- santiagobasulto 7y agoTLDR: if you’re a new programmer, don’t take this seriously. This person clearly doesn’t understand programming languages so well. Sorry to make this response an “ad hominem” one, I should revoke the claims. But it’s impossible if they don’t understand basic concepts of programming languages. For example, complaining that a dictionary key must be place in quotes. It’s not that “the key needs quotes”, but that you’re using “a string” as a key. In fact in Python, you can use any immutable object as a key (tuples, for example). They clearly come from Javascript, Python works differently (and arguably better), and they’re complaining that it doesn’t work the way they’d like it to work. Then complaining about list comprehensions as a “weirdo” thing. Clearly not understanding the functional paradigm and the beauty of expressions (see Smalltalk for the ultimate example of beauty and expressiveness).
- verttii 7y agoActually nowadays it's discouraged to use list comprehensions in Haskell. Even though he didn't complain about it, Python has very poor facilities for functional programming overall.
- mplanchard 7y ago> any immutable object as a key Any hashable object, technically. Especially with custom objects, the two (immutability and hashability) don’t necessarily have to overlap, although it’s often a bad idea to have hashable, mutable objects
- abhishekjha 7y agoMutable objects can't be hashed right?
- detaro 7y agoAs the comment you responded to says: An object can be mutable and hashable. E.g. any custom class by default has mutable and hashable instances.
- danbrooks 7y agoThis reads like a list of complaints about Django. There's much, much more to python than Django!
- encoderer 7y agoThat's just like, your opinion, man
- FpUser 7y agoI would agree about "magic" parts.
- LaGrange 7y agoI actually dislike Python, but this list ain't it.
- imtringued 7y agoI personally hate virtualenv. I just install pip dependencies in a vendor directory and point PYTHONPATH to it.
- phtrivier 7y agoYes. Because python is a programming language.
- bjoli 7y agoI hate python, but it is still invaluable to me for its ability to let me get shit done. Getting meaningful data from a 100mb CSV? No problems. Everything I need can be found in the STDlib. From my main perspective (scheme programmer): I am constantly amazed by the bad code python programmers write in scheme. Take a nice recursive function, sprinkle it with set! (which leads to boxing and general slowness in many implementations) and if that wasn't slow enough for you, wrap it in a call/cc to be able to return from arbitrary places in the function. As a bonus, forget to discard the captured continuation to make your program use insane amounts of memory. Then proceed to complain on Reddit.
- jolux 7y agoThe biggest beefs I have with Python are inconsistent syntax and dynamic typing. But I've basically decided that dynamic types are a waste of time for me personally, so I'm not really the target audience anyways.
- j88439h84 7y agoThe new static type analyzers like Mypy and PyType give it more of a static feel IMHO.
- jolux 7y agoAs I understand it those are not really complete though, are they? Do they offer algebraic data types and exhaustive pattern matching?
- j88439h84 7y agoI'm not sure. There is Union[Foo, Bar] which matches instances of Foo or Bar [0] and there is @overload [1]. What would it need to be complete? [0] https://docs.python.org/3/library/typing.html#typing.Union https://docs.python.org/3/library/typing.html#typing.Union [1] https://mypy.readthedocs.io/en/latest/more_types.html#function-overloading https://mypy.readthedocs.io/en/latest/more_types.html#functi...
- beager 7y agoThere’s plenty to criticize Python about relating to performance and developer operations (pypi, virtualenvs, cumbersome version juggling), but most of these language features mentioned have a valid need to exist, or are purely stylistic, and therefore not admissible to the “not a great programming language” debate imo.
- sidlls 7y agoThere are plenty of things about Python that are not good, and only two are touched on in this list (the cumbersome double-underscore syntax and "magic methods" in general, although the author clearly has experienced python mainly through Django, which has other problems). The rest read like someone who doesn't really know the language that well and hasn't a lot of experience in general.
- akubera 7y agoPart of the problem here is clearly this person is mapping JavaScript idioms to python; in particular "Needing to put dict property names `{'in': 'quotes'}": these aren't object properties, these are keys in a map, and they can be and often are variables themselves, (also, can be any hashable type, not just strings) and I don't see how that can detract from the 'greatness' of python. Also "foo['bar'] returns a KeyError", then saying sometimes this is resolved by "getattr(foo, 'bar', None)" -- the split between attributes and items are one of the best things about python. I don't know why list comprehensions are "magic syntax", and you can't complain about having to type list(map(...)) and then complain that you don't like list comprehensions! "You have to cast your data back to a list/tuple after using enumerate() and map()." -- I don't know what that means "Different syntaxes for lists and tuples." -- Again, what? They're different types! How is r'a\nd' less "goofy" than String.raw`a\nd` in JS or any other language with prefixed strings? Python is clearly not for everyone nor for every problem, but in my opinion it is a great programming language.
- duckerude 7y ago> "Different syntaxes for lists and tuples." -- Again, what? They're different types! Lists and tuples have different syntax in a weird and surprising way. List syntax is straightforward, just square brackets and commas. Tuple syntax pretends to be list syntax with parentheses but it's actually only about commas except when it isn't. Typically you write `(a, b)`, but the parentheses are only for precedence, and can be left out if it's unambiguous: `a, b`. You can write a 1-list as `[a]`, but a 1-tuple is `(a,)` because `(a)` is just `a`. An empty tuple on the other hand is `()`, without any commas, and with parentheses doing something other than precedence. It's very ugly. I can't think of a better way to fit it into the rest of the syntax but I still count it as a flaw.
- akubera 7y agoAh, yeah I see; there's an ambiguity in parsing expressions and tuples which could lead to subtle typing bugs. There's another ambiguity that (a for a in b) is not a tuple, but a generator, while [a for a in b] is a list.
- 7y ago
- jchw 7y ago> you have to do foo.get('bar')... or in some cases getattr(foo, 'bar', None) This is a mistake based on thinking in Javascript: in JS the index operator is effectively the same as the dot operator, for example foo[“bar”] == foo.bar. In Python those are different. [] corresponds to get in dicts, and . corresponds to getattr in objects. My personal biggest gripe with Python is that there isn’t a better story for typing as I’m spoiled by TypeScript and static languages that have a better development experience and prevent certain classes of mistakes.
- snypox 7y agoHow about post 3.5 type hints?
- jchw 7y agoEvery time I mention typing in Python, people point out the existence of type hints and type checkers. However, I’ve yet to be able to meaningfully use one in practice. I have used MyPy but it didn’t offer nearly as much benefit as say, TypeScript, and brought problems of its own. There’s been some work done but for example, Django middleware is problematic here. A lot of Pythonic code would be extremely challenging to actually cover with robust typechecking. Not to mention, a lot of software treats type hints very differently. PyCharm is able to do powerful inference that MyPy can’t do.
- ACow_Adonis 7y agoIt's certainly not a perfect language (no multi-line lambdas, double underscore keywords everywhere, converting generators, significant white space means problems working in other environments, typing, isn't called lisp), but you know what... I've been pleasantly surprised how shallow the "general python rabbit-hole" is. If i can express this in words, one of the ways I like to judge a language when I program: i think of something a computer could theoretically do, then I look for ways to express it in that language. How many independent jumps I have to take down the conceptual rabbit-hole before I get to the solution is a nice little arbitrary metric. Does python do everything the way I'd do it? No. You get over yourself and just accept that's the way it is in this language. Once I've done that, so far most problems in python have been pretty shallow: do this arbitrary thing and then this arbitrary thing and you're done. Compared to some of my past languages where you have to go 4 or 5 levels deep with N compulsory but conceptually irrelevant steps, it's pretty damn good. Makes for a reasonable quick pathway to actually getting anything done... Purely my subjective opinion.
- rdiddly 7y agoAs usual, the worst things about a thing are also the best things about it, and the best things about it are the worst things about it.
- deleted 7y ago[deleted]
- hootbootscoot 7y agoOne realizes the true cost of Pythons forced indentation when using MicroPython over a serial connection, for example It's a big PITAS, tbh. I see Python as a Vala-like glue language for C (as in Cython or FFI) but this singular weakness makes you pay attention to it in a context in which it' s truly beyond ridiculous. One may as well lisp for such use-cases...
- ben509 7y agoMost of these are pretty dumb, but there are some inadvertently good points.[5] > The philosophy of "one correct way to do things." I miss those days. T_T > A huge ecosystem of good third-party libraries. Python also has a huge ecosystem of huge ecosystem managers, which is less than ideal. > Half of each Django app is super().__init__( * args, * * kwargs) Haven't used Django, but if I were providing a suite of classes people were extending, I'd provide lifecycle hooks. Using super().__init__ is not a syntax problem as much as it's a semantics problem, because it's so fragile.[1] > Too many magic __double-underscore__ methods and properties that you have to just memorize. Yup, dunders are the ugly consequence of duck-typing. Maybe Python could tuck them away in some kind of traits system. > Too many other weirdo bits of magic syntax, like [list comprehensions]. But the Python syntax is weird: [elem for outer in iterable for inner in outer] Which is essentially: for outer in iterable: for inner in outer: result.append(elem) It's backwards. The PEP[2] doesn't explain why, but looking at the JS syntax[3] it does seem less worse. Other weirdo syntax: while some_condition(): if check_a_thing(elem): break else: print("never broke from loop") The meaning sort of makes sense if you think of `while` as an extension of `if`. But I would have expected this: for x in y: do_a_thing() else: handle_empty_case() Or, really, a more descriptive keyword. > You have to cast your data back to a list/tuple after using enumerate() and map(). I thought it was the coolest thing when generators got full support in py3k, but it's horribly broken. This does not raise an exception: x = list(some_generator) y = list(some_generator) y will be empty, which is a completely silent failure. The same is true for iterators. And everyone's been bit by strings being iterable[4]. Sometimes it's useful to do this: i = iter(some_generator) x = next(i) for elem in i: ... But Python should not: 1. make iterators be iterable. 2. allow spent generators to be reused without exception. 3. make strings be iterable. (All of which could be bypassed with a method call when you really want that behavior.) > foo['bar'] returns a KeyError, so you have to do foo.get('bar') LOL, only javascript devs could not have noticed the hours they've spent tracking down the source of some mysterious undefined. Python definitely got this one right. [1]: https://fuhm.net/super-harmful/ https://fuhm.net/super-harmful/ [2]: https://www.python.org/dev/peps/pep-0202/ https://www.python.org/dev/peps/pep-0202/ [3]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Array_comprehensions https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe... [4]: https://mail.python.org/pipermail/python-3000/2006-April/000759.html https://mail.python.org/pipermail/python-3000/2006-April/000... [5]: Wait, am I talking about the OP or this comment?
- viraptor 7y agoIf you complain in the same post: about top level functions like list and map, and about list comprehension, you've lost me. To have lazy and eager types and list processing, you either have to have functions or syntax for both. If you complain about existence of both, you either need to propose a new paradigm, or you're just grumpy about everything.
- djohnston 7y agoHe has insulted list comprehensions and therefore my honor!
- nhumrich 7y agoThere are two kinds of languages. Those that people complain about, and those that nobody uses.
- HorkHunter 7y agoI mean, one could complaint about many things in Django, but the documentation....??? Really?
- nojvek 7y agoI love python. I just really wish there was a typed equivalent of python like Typescript. The python3 types are very weak compared to TS.