[HN Gopher] What the Fuck Python
___________________________________________________________________
What the Fuck Python
Author : sundarurfriend
Score : 74 points
Date : 2025-07-19 19:01 UTC (3 hours ago)
(HTM) web link (colab.research.google.com)
(TXT) w3m dump (colab.research.google.com)
| alabhyajindal wrote:
| Preach. We need more Python slander. It annoys me to no end when
| people trash JavaScript as if it was some exception in bad
| language design. Most languages have something bad that can be
| picked up and trashed on - some more than others.
| heavenlyblue wrote:
| Given that it starts with a thing called "id" which is an
| implementation detail and probably should not be used for
| equality, it seems like this is a geniuinely well designed
| language :)
| mirashii wrote:
| id is not an implementation detail, it's a core built-in
| function of the language. The value that it returns is an
| implementation detail, but the properties of the value it
| returns are not and perfectly valid to rely on.
| zahlman wrote:
| `id()` is documented and mandated to exist, and the result
| provides guarantees that make it suitable for identity (not
| equality) checks[1] (although of course you should normally
| use the `is` operator). Pitfalls involving it are generally
| really pitfalls with understanding object lifetimes[2].
|
| [1]: https://docs.python.org/3/library/functions.html#id
|
| [2]: see e.g. https://stackoverflow.com/questions/52096582
| bnchrch wrote:
| Thank you! For years Ive been saying the sheer volume and fury
| by which Javascript is criticized is much more applicable to
| Python.
|
| Both aren't perfect languages, and both are far from "the best"
| but it is maddening that Python get often picked as a darling
| when its implementation, ecosystem and tooling are
| fundamentally at odds with correctness and productivity.
| verbify wrote:
| I think people pick on js more because it's the only option
| for scripting frontend for the web, while if you don't like
| python there's probably another language that can be used
| instead.
| dreamcompiler wrote:
| Unless you're doing AI, in which case you're royally
| screwed.
| moffkalast wrote:
| Yeah python deserves a good bashing as well, it's about as bad
| as JS in this regard. I mean for bool("false") resolves to True
| ffs.
| bnchrch wrote:
| Don't forget its transitive dependencies creating non-
| deterministic builds
| 3eb7988a1663 wrote:
| That is entirely consistent with how truthiness works in
| Python. The function does not claim to parse strings, that is
| how you get YAML Norway.
|
| Do you think there should be different results for
| bool("no"), bool("false"), bool("heckno!"), bool("heckyes!")?
|
| Edit: should have included internationalization:
| bool("nein!")
| moffkalast wrote:
| Honestly once you really think about it just about nothing
| about these decisions ever makes any real sense which is
| why JS is made fun of constantly. It's nonsense functions
| running on nonsense data. "if some_non_bool_value:" should
| not be valid syntax and truthy and falsy is a concept that
| would get you locked up in an asylum if you decided to
| explain it to a doctor.
| crazygringo wrote:
| > _The function does not claim to parse strings_
|
| But it's entirely reasonable to think it would. I honestly
| don't understand why it wouldn't, because:
| >>> int("35") 35 >>> float("3.5") 3.5
| >>> bool("False") True
|
| If casting from a string to a type works with ints and
| floats, why not with bools? What possible justification is
| there?
|
| And of course it doesn't need to work for "no" or
| "heckno!", that's silly. But it sure seems like it ought to
| work on whatever the official string representation is. And
| not produce: >>> bool(str(False))
| True
|
| I'd honestly much prefer bool() threw an exception on
| receiving a string, rather than act the way it does now.
| 3eb7988a1663 wrote:
| prefer bool() threw an exception on receiving a string,
| rather than act the way it does now.
|
| That breaks the truthiness cornerstone of the language.
| You can write a = 1 # or [], (), "yo",
| "false", 3.2, MyFooClass(), (1,), False if a:
| fire_ze_missles() else: declare_peace()
|
| Upon encountering `a`, Python is evaluating bool(a). If
| that no longer works for strings, you now need a separate
| code path for determining a non-empty string.
|
| It can short-circuit the brain upon reading a word that
| you know means false, but the Python rules are
| consistent. "Empty" is False, everything else is True.
| moffkalast wrote:
| You can write that yes, but I'm calling the police.
| librasteve wrote:
| yeah
|
| in raku, i checked say False.so; #False
| Jtsummers wrote:
| If I understand raku correctly, the Python example would be
| more like this: say "False".Bool
|
| Which displays True. Note that the Python example is
| converting (via `bool`) a string with the text "false"
| (which would make more sense as "False" which is the actual
| name of `False` in Python) into a boolean value. It's
| consistent with how Python behaves, in that the empty
| string (like in Raku from what I can tell) is false-y and
| non-empty strings are truth-y. It would be weird to have
| this use the else branch: if bool("False"):
| ... else: ...
|
| But not this: if "False": ...
| else: ...
| motorest wrote:
| > We need more Python slander. It annoys me to no end when
| people trash JavaScript as if it was some exception in bad
| language design.
|
| Python's file system support across platforms is notoriously
| problematic or even outright broken. Wasn't this enough reason
| to put it lower in the quality bar than JavaScript?
| fragmede wrote:
| wat
|
| https://www.destroyallsoftware.com/talks/wat
| throwaway314155 wrote:
| JavaScript is far more jarring than Python depending on your
| background. They do both have issues of course, but that's the
| reason JavaScript gets "picked on" more.
| ltbarcly3 wrote:
| Haha these aren't even wtfs! the id changes or not? oh noooo,
| people use the id() function so much, I've literally seen it 0
| times ever in production code. This is nothing like the JS wtfs
| where there is no way to predict what it will do, and it violates
| it's own patterns.
|
| edit: to be more clear, I have run into a lot of JS wtf's trying
| to write code for work. you just run into bugs all the time where
| JS doesn't do anything like what would be the obvious thing to
| do, or the thing that works 99.99% of the time fails depending on
| the value of the string being 'magic'. with Python I rarely if
| ever learn some bizarre arcane thing accidentally because it
| almost always behaves as expected. If you think there's an
| equivalence here you are just a JS fanboy, JS was a language that
| evolved largely because of hacks vendors put in and those insane
| hacks got standardized because it was too late, despite being
| insane. Python was specifically and carefully designed to
| minimize unexpected behavior.
| andy_ppp wrote:
| I think they are pretty bad tbh apart from the ID one. Everyone
| knows about the JS quirks so I think it's good to know
| sometimes equality in Python strings can behave extremely
| strangely and the other issues mentioned. Why does it have to
| be defended "my language is better than your language"? However
| I'd like to say Elixir is near perfect, thanks :-)
| ltbarcly3 wrote:
| No you misread it, equality for python strings works exactly
| the way you expect. the id() value (which is basically the
| memory address) might not change if you concatenate strings,
| but literally nobody ever uses id for anything ever. You
| would use hash() which does change appropriately.
|
| edit: 'wtf!' is always equal to itself. Maybe you are
| thinking of `is`, which just compares the value of id(). `is`
| can't be used for comparisons, saying it's a WTF is just
| being unfamiliar with basics. `is` is not used for equality
| comparisons. This is how more or less every language works,
| comparing pointers is not the same as comparing strings in
| C/rust/etc. Comparing object identity is not the same as
| testing equality in Java.
| andy_ppp wrote:
| I think honestly it is you who misread my comment... I was
| saying the id() issue isn't a real problem, the weirdness
| around "wtf!" not being equal to itself under some
| circumstances is very confusing. Seems Google Colab isn't
| loading here.
| ziml77 wrote:
| But "is" doesn't check equality. It checks reference
| equality. Maybe the real wtf here is they made that check
| a temptingly short infix operator rather than a function
| named reference_equals().
| zahlman wrote:
| "wtf!" _is_ consistently equal to itself in Python.
|
| The fact that you could have separate string objects both
| representing that text, is entirely orthogonal to that.
| Jtsummers wrote:
| `is` is more like doing this in C: char*
| s1 = "wtf!"; char* s2 = "wtf!"; if (s1 == s2)
| { ... }
|
| They may or may not be stored in the same place depending
| on your compiler (clang and gcc yes, msvc no, at least
| with just a quick default build). If you actually want to
| do an _equality_ check, you need to use `==` (in Python)
| which would be like using `strcmp` in C.
|
| > "wtf!" not being equal to itself
|
| It _is_ equal to itself, but multiple variables
| referencing that string may not hold references to the
| _same_ (literal, in memory) string.
| mvanbaak wrote:
| I totally agree with you. I have seen a lot of code, but the
| id() function has never been used in production code
| w4yai wrote:
| And now you're using pretty much the same rhetoric than JS guys
| when facing to wtfjs.
| ltbarcly3 wrote:
| No, I don't think so. The JS wtf's actually make you gasp.
| These are so obscure and boring.
|
| F'ing JS equality isn't transitive for builtin types.
| BobbyTables2 wrote:
| Even normal JS is WTF-worthy...
|
| Allowing out of bound array indexing and operations using
| "undefined" seems pretty crazy to me.
| jacquesm wrote:
| For the former: technically they are about as undefined as
| they could be on read. On write, it's a different matter
| (you could decide to resize the array under the hood). Even
| so, I think arrays with a particular size always were
| simply an illustration that there is a point where you have
| to allocate a physical resource to something entirely
| imaginary and that's where infinite bounds are no longer
| acceptable. In the 80's that was '256', in the 90's
| '65535', nowadays it is more like '4G' but no matter how
| far we advance there are still hard limits. And on the wire
| it gets even more constrained.
| craftkiller wrote:
| I think this one is good: False == False in
| [False] # Outputs True
|
| It doesn't make sense no matter which way you evaluate it.
| Equality first: False == False # True
| True in [False] # False
|
| or `in` first: False in [False] # True
| False == True # False
| ltbarcly3 wrote:
| Ok I'll admit this is a real WTF
| Upvoter33 wrote:
| chained comparisons are weird and counter-intuitive,
| sometimes
| quuxplusone wrote:
| Python is my second language (after C++) and for me the
| surprising thing here is not "chained comparisons are
| weird" but rather "`in` is a comparison operator."
|
| So for example `1 in [1,2] in [[1,2],[3,4]]` is True...
| but off the top of my head I don't see any legitimate
| use-case for that facility. Intuitively, I'd think a
| "comparison operator" should be homogeneous -- should
| take the same type on LHS and RHS. So, like, "is-subset-
| of" could sanely be a comparison operator, but `in` can't
| be.
| zahlman wrote:
| >and for me the surprising thing here is not "chained
| comparisons are weird" but rather "`in` is a comparison
| operator."
|
| Python documentation calls it a "comparison operator" (ht
| tps://docs.python.org/3/reference/expressions.html#compar
| i...) but a broader, better term is "relational
| operator". It expresses a possible relationship between
| two arguments, and evaluates whether those arguments have
| that relationship. In this case, "containment" (which
| intuitively encompasses set membership and substrings).
|
| A finer distinction could have been made, arguably, but
| it's far too late to change now. (And everyone is
| traumatized by the 2->3 transition.)
| None4U wrote:
| Yeah, having the expansion rule operate on operators that are
| clearly not transitive serves no purpose (1 < 2 < 3 is at
| least a math notation)
| daedrdev wrote:
| Its apparently trying to allow x < y < z be a legal
| statement, meaning that we get:
|
| False == False and False in [False] is a expansion of that
| statement, just like x < y and y < z is the expansion of x <
| y < z
| jnpnj wrote:
| Oh yeah, that's a great one, there must be a compounded
| boolean expression logic escaping us
|
| I'll add: >>> False == False in [True]
| False >>> True == True in [True] True
|
| ps: some ast poking >>>
| ast.show(ast.parse("False == False in [False]"))
| Module( body=[ Expr( value=Compare(
| left=Constant(value=False), ops=[ Eq(),
| In()], comparators=[
| Constant(value=False), List( elts=[
| Constant(value=False)], ctx=Load())]))])
| >>> ast.show(ast.parse("(False == False) in [False]"))
| Module( body=[ Expr( value=Compare(
| left=Compare( left=Constant(value=False),
| ops=[ Eq()], comparators=[
| Constant(value=False)]), ops=[ In()],
| comparators=[ List( elts=[
| Constant(value=False)], ctx=Load())]))])
|
| note the first tree as one Comparator node with multiple ops,
| time to read the spec to know how these are evaluated
| Jtsummers wrote:
| The document explains it. When dealing with these
| comparators, when chained they get separated and you have
| the equivalent of this: False == False in
| [True] => (False == False) and (False in
| [True])
|
| If you put it into a function like this:
| def foo(): return False == False in [True]
|
| And then disassemble it you'll get this byte code (3.13,
| may vary by version): RESUME
| 0 LOAD_CONST 1 (False)
| LOAD_CONST 1 (False) SWAP
| 2 COPY 2 COMPARE_OP
| 72 (==) COPY 1
| TO_BOOL POP_JUMP_IF_FALSE 5 (to L1)
| POP_TOP LOAD_CONST 2 ((True,))
| CONTAINS_OP 0 RETURN_VALUE L1:
| SWAP 2 POP_TOP
| RETURN_VALUE
|
| There is no literal `and` operation occurring here, instead
| it first does the `False == False`, then jumps if false or
| continues to the second comparison.
|
| For the literals we've given it, it'll go on to the second
| comparison which will result in false since `False` is not
| in `(True,)`.
|
| EDIT: And here's the non-chained version disassembled:
| def bar(): return (False == False) in [True]
| RESUME 0 LOAD_CONST
| 1 (False) LOAD_CONST 1 (False)
| COMPARE_OP 72 (==) LOAD_CONST
| 2 ((False,)) CONTAINS_OP 0
| RETURN_VALUE
| its-summertime wrote:
| return False == False in [False]
|
| is roughly a = False b = False
| c = [False] (a == b) and (b in c)
|
| is less roughly a = False b = False
| if not (a == b): # short circuits
| https://news.ycombinator.com/item?id=44619401
| return False c = [False] if not (b in
| c): return False return True
| zahlman wrote:
| > It doesn't make sense no matter which way you evaluate it
|
| It makes sense when you evaluate it the way it's intended to
| be understood (https://stackoverflow.com/questions/6074018).
| There _are_ other languages that do this, and it was
| consciously designed to work this way. The idea that you
| should have to evaluate one of the operators "first" may
| make sense to someone trying to implement a parser with
| techniques from the 70s, but for languages like Python, the
| design is clearly more about what makes sense for the code
| author.
|
| Arguably it's surprising that `in` is treated as on par with
| `==`. But on the other hand, even someone trying to implement
| a parser with techniques from the 70s would have to admit
| that both are "relational operators".
| kgm wrote:
| I have used id() in production code, but the circumstances were
| extremely specific: It was in some monitoring-related code that
| was trying to dig down into the guts of the interpreter for the
| purposes of tracking memory usage on the level of individual
| pages. It was a whole thing.
|
| Which is to say: Users of Python almost certainly don't want to
| call id(), unless they are mucking around with something
| related to the functioning of the interpreter itself. The only
| other circumstance in which I've used it in anything like real
| code was in a quick hack where what I really wanted was to put
| a bunch of dicts in a set, but you can't do that, so I made a
| set of their IDs instead (but this wasn't in what I would call
| "production code").
|
| In general, most of the "wtfs" listed here are pretty banal. If
| you're using `is` on immutable objects, you're basically just
| asking for trouble. The functioning of string and integer
| interning and constant folding are implementation curiosities,
| and if you ever write code in which such differences matter,
| then you have made an error.
| jtolmar wrote:
| I don't think either reach the real wtfs of their language.
| id() does some weird things with string interring, javascript
| coerces cross-type arithmetic into weird nonsense instead of
| throwing a type error. Whatever, neither of these come up in
| the real world.
|
| Builds so messy that you need to resort to venv, every second
| DOM API being someFunc(thirdMostImportantArgument, {
| mostImportantArgument: val }), these are the real wtfs.
| zahlman wrote:
| Yes, but those are definitionally library and ecosystem wtfs,
| rather than language ones.
| zahlman wrote:
| Like I've been saying in other recent submissions, since there
| seems to be a trend for similar discussion: in Python you find
| WTFs by trying to probe how Python works, pushing deliberately
| over-flexibly customization hooks to their limits, etc. In JS
| you find them by merely trying to call builtins with dodgy
| inputs.
| Shacklz wrote:
| > I have run into a lot of JS wtf's trying to write code for
| work
|
| JS certainly does have _plenty_ of wtfs but honestly, when
| sticking to somewhat modern JS, it 's not so bad anymore these
| days. Function-scoping-shenanigans can mostly be circumvented
| by simply sticking to const/let, use a 3rd-party-library like
| date-fns instead of the dumpsterfire that is native Date and
| you're almost there - throw typescript into the mix and I have
| a very hard time imagining running into the meme-worthy JS-
| warts on a daily basis.
| JohnKemeny wrote:
| If you use a floating point number as a key in a `dict` the wtf
| should not be pointing at Python.
|
| These are not wtfs, please.
|
| These examples read like someone who is learning to program and
| who is confused. x is not y x is (not
| y)
|
| How can you confuse these two?!
| mvanbaak wrote:
| AI
| woooooo wrote:
| Fp32 or fp64 in a strongly typed language would be no problem
| as hash keys. Yes, they're imprecise for math but the 64 bits
| of data should work just like a long as a hash key.
| marcosdumay wrote:
| No, they are not suitable for use as hash keys unless you are
| treating them as opaque binary data. And if you are there,
| you are better putting your values in some type that means
| opaque binary data for the start.
| spacechild1 wrote:
| They are perfectly suitable as long as you know what you
| are doing. Here's a real use case: when compiling a
| scripting language, map float constants to slots in a
| "constant table" so that all constants with the same value
| share the same slot.
| woooooo wrote:
| They ARE fixed-width binary data, and they're effectively
| opaque unless you have IEEE 754 open on your desk, it's all
| handled in hardware otherwise.
| LPisGood wrote:
| Some of these just seem to be using Python out of spec and being
| surprised that implementation details exist, and misunderstanding
| boolean expressions.
| otabdeveloper4 wrote:
| Python doesn't have a spec. It barely even has documentation
| nowadays. (Sad. Twenty five years ago it was the gold standard
| of documenting software.)
| troupo wrote:
| > Twenty five years ago it was the gold standard of
| documenting software.
|
| That was PHP. Though Python was a close second
| LPisGood wrote:
| I don't understand what you mean by "doesn't have a spec"
|
| The existence of Pypy and CPython and separate but compatible
| entities shows that there is
| motorest wrote:
| CPython is the de-facto reference implementation of Python.
|
| Pypy was developed by reverse engineering CPython and their
| automated tests feature explicit comparisons with CPyton.
|
| You made the opposite point you thought you were making.
| librasteve wrote:
| in raku, the test suite (ROAST) is the spec
|
| any compiler that can pass ROAST is valid
| simonw wrote:
| https://docs.python.org/3/reference/grammar.html and
| https://docs.python.org/3/reference/index.html look pretty
| comprehensive to me, and they're backed up by a thorough
| collection of PEPs: https://peps.python.org/pep-0000/
|
| As a relatively recent example, here's the language reference
| documentation for the match statement https://docs.python.org
| /3/reference/compound_stmts.html#the-...
| NeutralForest wrote:
| That seems uncalled for, the docs are great and the various
| guides are usually a good starting point to understand and
| then use the stdlib.
| zahlman wrote:
| Python's documentation today[1] is clearly more expansive,
| better formatted and more readily comprehensible than its
| documentation from 2001[2] (or even 2008[3]). There are
| multiple entire sections of documentation now that didn't
| exist before. Standards were just lower back then, partly
| because a larger percentage of "programmers" were accustomed
| to wrestling with beasts like C, and partly because systems
| were much smaller.
|
| https://docs.python.org/3/
|
| https://docs.python.org/2.0/
|
| https://docs.python.org/2.5/
| motorest wrote:
| > Python's documentation today[1] is clearly more
| expansive, better formatted and more readily comprehensible
| than its documentation from 2001[2] (or even 2008[3]).
|
| Documentation is not a specification. Specifications cover
| all behavior that should be expected, and specify which
| behavior is implementation-defined or undefined. If
| something isn't defined them this is a failure in the
| specification that requires fixing. The point of a
| specification is to allow independent parties to do clean
| room implementations that can be used interchangeably.
| zahlman wrote:
| The majority of the comment I was replying to was about
| documentation, and I was responding to that.
| otabdeveloper4 wrote:
| Good documentation cannot be "expansive". Good
| documentation must be a) thorough and b) minimal.
|
| Modern Python documentation is absolutely horrible -
| there's a shitload of irrelevant rambling while absolutely
| crucial details are omitted.
| omoikane wrote:
| See also: https://github.com/satwikkansal/wtfpython
|
| The "interactive notebook" link goes to the colab page.
|
| There are many earlier threads associated with the markdown
| version, for example:
|
| https://news.ycombinator.com/item?id=21862073 (2019-12-23, 185
| comments)
|
| https://news.ycombinator.com/item?id=26097732 (2021-02-11, 163
| comments)
|
| https://news.ycombinator.com/item?id=31566031 (2022-05-31, 143
| comments)
|
| https://news.ycombinator.com/item?id=37281692 (2023-08-27, 82
| comments)
| rr808 wrote:
| While we're at it. Notebooks aren't a real programming
| environment.
| incognito124 wrote:
| I don't think anyone is disputing that
| klysm wrote:
| Huh we must be hallucinating then?
| rexpop wrote:
| Yeah, this simply doesn't work for me; ie the expressions did
| not evaluate, and output was not made visible.
|
| I have _never_ had a successful experience writing or running
| programs in notebooks like this--although I have not, arguably,
| tried with high stakes.
|
| As soon as the stakes rise that far, however, I reach for a
| whole-ass Unix environment with a shell, a filesystem, and a
| stateful process model.
|
| Is this a crutch? Is it too much overhead? It's arguably absurd
| that I even ask. (Edit: It's actually _killing me_ how
| ambiguous I 'm being, right now. There's no winning.)
| zahlman wrote:
| > As soon as the stakes rise that far, however, I reach for a
| whole-ass Unix environment with a shell, a filesystem, and a
| stateful process model.
|
| I don't understand what you mean by "reach for". Don't, for
| example, Linux desktop users have all these things at hand
| all the time? For me it would take much more effort to set up
| a "notebook" than a virtual environment.
| fragmede wrote:
| For you, sure, but for someone that lives and breathes
| notebooks, running _jupyter notebook_ and going to
| localhost:8888 already happened, so it 's opening a
| terminal that's the extra step.
| zahlman wrote:
| ... How do you do those things without a terminal?
| hollerith wrote:
| You would start the Jupyter application, then use a
| browser to go to localhost:8888 :)
|
| To start the application, you would typically use the
| start menu on Windows or the Dock on MacOS. Alternatively
| on MacOS you could point the Finder at the /Applications
| folder, then start the application from the Finder
| window.
|
| (This is not meant as an endorsement of notebooks.)
| fragmede wrote:
| install https://github.com/jupyterlab/jupyterlab-desktop
| and double click
| jacquesm wrote:
| Agreed. Even so, you'd be surprised to find that some companies
| run them in production. I never got the idea behind that, maybe
| someone that engages in such a practice could enlighten me. I
| have yet to hear a good rationale.
| mr_toad wrote:
| Programming encompasses things other than production
| environments and software engineering. Notebooks are fine
| programming environments for prototyping, exploration and
| training.
| extraduder_ire wrote:
| Real in what way? I'm not too familiar with them, but they seem
| about on par with the environment for JavaScript that is html
| files or "web pages".
|
| Making a html document so someone can easily run some
| JavaScript, seems like the closest parallel to making a jupiter
| notebook so someone can easily run some python.
| moffkalast wrote:
| Jupyter is like if someone decided they don't like neither REPL
| nor running complete scripts and did something that makes a
| mockery of both.
| pseufaux wrote:
| Define "real programming environment"
|
| Seems like an odd way to say, "Notebooks don't fit my
| workflow/usecase."
| Danjoe4 wrote:
| Who writes python this way? Good Python code, being such a
| flexible language, relies on conventions. Never seen the id()
| function in production code. "Is" is canonically used for "if var
| is None", not string comparisons. Python has a rich library of
| string methods, maybe use them?
|
| You're finding bugs because you're using the language like a QA
| tester instead of the way its intended. If I saw string_var is
| "some_string" in a PR, I would reject it. Even the triple boolean
| comparison example should just be separated with an "and".
|
| Read PEP20 and PEP8. A goal of Python is to be as readable as
| possible, not to conform to some spec. You may not agree with
| that design decision, but all these examples have an obviously
| more readable alternative which would work.
|
| Jeez. It's like me complaining that Rust looks ugly (it does).
| The language was designed with a different set of priorities.
| motorest wrote:
| > You're finding bugs because you're using the language like a
| QA tester instead of the way its intended.
|
| What do you think this means? Are the bugs there or not?
| fragmede wrote:
| Not all bugs are equal though, and if I'm only going to run
| across the bug when I'm standing on my head the third
| Wednesday of the month while singing Poker Face, it's a bit
| less concerning than one that happens only on days that end
| in "Y".
| happytoexplain wrote:
| So we shouldn't learn about them? They're offensive to
| enumerate? No, they're useful to understand.
| fragmede wrote:
| So we should put them into the bug tracking system and
| prioritize them accordingly. They're very useful to
| understand, but if one costs $100 every time it happens
| but it only happens once a year, vs a different bug that
| costs $1 every time it gets hit, but it happens every
| day, which one should get fixed first?
| motorest wrote:
| I think you're showing some despair in trying to avoid
| addressing the fact that there are indeed bugs. There is
| nothing suggesting bugs are obscure or random. You have a
| list of examples. Is it hard to acknowledge the problems
| are there? What exactly makes you feel threatened or
| personally attacked by a bug tracker?
| fragmede wrote:
| I think you're reading a lot more emotion than exists
| into my comment. Despair? lol I'm just pointing out that
| QA testers (and good ones are worth their weight in gold)
| find bugs by doing things must users wouldn't even
| consider doing.
|
| https://news.ycombinator.com/item?id=25851770
| FreakLegion wrote:
| Which ones are bugs? I read the first few sections and
| glanced through the rest, but it's a long notebook. There
| were runtime-specific implementation details, operator
| precedence, genuine language footguns (like scoping rules),
| but no bugs that I saw.
| duncanfwalker wrote:
| I mainly see this wtf pages as a hook to talk about the
| internals of a language/interpretor/etc. As you say, there's no
| point reading them as a criticism of the language because
| that's just not what production python looks like. I read the
| line of code and think 'can I imagine why it does that?' if I
| can I skip the explanation but sometimes I have absolutely no
| idea what's going on and they're the ones I like to read the
| detail on
| evertedsphere wrote:
| > While some of the examples you see below may not be WTFs in
| the truest sense, but they'll reveal some of the interesting
| parts of Python that you might be unaware of. I find it a nice
| way to learn the internals of a programming language, and I
| believe that you'll find it interesting too!
|
| the spirit in which that page is presented is different from
| what you seem to have taken it to mean
| crazygringo wrote:
| > _A goal of Python is to be as readable as possible, not to
| conform to some spec._
|
| The goal of _every_ programming language should be to conform
| to a spec that is as logical and consistent as possible. This
| prevents bugs by saving tons of mental effort having to worry
| about and look up edge cases, and not always catching them all.
|
| I don't mind so much if end-user applications have bugs when
| they're used differently from intended, because their use cases
| are narrow. If Word crashes when I put 10,000 images on a
| single page, well obviously it's not built for that.
|
| But I mind _very much_ when programming languages have bugs,
| because they are the layer on top of which we build so many
| other things! The use cases for a programming language are
| almost infinitely wide.
|
| For a language as widely used as Python, we _should_ be testing
| it out like QA testers. All these inconsistencies add up to
| tons of bugs when you expect something to follow a consistent
| pattern and it doesn 't.
| happytoexplain wrote:
| Why are you being so defensive? Every language has bad or
| surprising (which IMHO is a synonym for bad) design choices.
| These are just a few of Python's. "You're using it wrong" seems
| like an unrelated criticism. Languages have the luxury of
| dictating how you use them.
| hansvm wrote:
| The first third of this seems to just be complaining that it's
| not obvious when two objects are actually the same object, and
| that if you mistake identity-related operators for other
| operators then you'll have a bad day.
|
| That's a fair critique. It's a little weird that `is` and friends
| have dedicated, short, nice syntax.
|
| On the other hand, most compiled languages are compatible with an
| implementation which admits the following optimization:
| const a: u32 = 42; const b: u32 = 42; assert(&a ==
| &b);
|
| The language usually doesn't guarantee that different immutable
| variables have dedicated memory on the stack, or that they even
| live on the stack in the first place.
|
| That's the same class of error we're seeing here, and even among
| popular interpreted languages Python is by no means unique. I
| might get to the bottom 2/3 of the doc later, but the rest was
| off-putting enough that I don't know I'll bother.
| hmry wrote:
| Yeah, it would be much clearer if instead of an `a is b`
| operator, there was a `same_object(a, b)` built-in method.
| procaryote wrote:
| I'm happy to complain about python but I got like a third into it
| and didn't find any actual wtfs.
|
| Java as contrast has interning wtfs because == between java
| objects does essentioally what python's `is` does. Python
| actually made a good choice here and made == do what you'd
| expect.
|
| Is anyone surprised by `(1 > 0) < 1`? There are languages where
| it will be rejected because of types, but what else would you
| expect it do than compare a boolean true to 1?
|
| Is there anything of value later on?
| happytoexplain wrote:
| I'm a little flabbergasted at how many comments here boil down to
| "These aren't WTFs if you understand the language."
| pseufaux wrote:
| It's a bit like when non-JS programmers complain about
| JavaScript. It's mostly nonsense. That's not to say that
| JavaScript doesn't have flaws and footguns, but the opinion of
| novices in the language is not who I am interested in learning
| from. Python is the same. It has flaws and idiosyncrasies,
| especially in the standard library (cough cough
| xml.ElementTree), but the core language is fairly consistent
| and predictable. Expecting casting functions like bool() to
| parse strings like JavaScript does makes little sense.
___________________________________________________________________
(page generated 2025-07-19 23:00 UTC)