Hacker News new | past | comments | ask | show | jobs | submit login

Python has evolved into quite a complex language considering the amount of features that come built-in. The documentation, while complete, does not facilitate discovery of many of those features.



The quality of documentation is a known, highlighted concern in the community. There is particular interest in adopting Diataxis principles to improve documentation, both for Python itself and for packaging (see e.g. the user guide at https://packaging.python.org/en/latest/ , or the PyPA main site https://www.pypa.io/en/latest/ ).

If you want to help, there's a section on the Python forum (https://discuss.python.org/c/documentation/26) and a Discord server, and issues with documentation can also be reported on the main Python GitHub issue tracker (https://github.com/python/cpython/labels/docs).


Just like Microsoft maintains the Typescript handbook, I think the Python Foundation needs a "Idiomatic Modern Python Handbook" which always shows the most modern and idiomatic way to use Python features.


Python has always been quite complex, people get deceived by how simple Hello World looks in Python.

Using it since version 1.6.


It's more complex that decade ago, but still a relatively simple language. I can understand the article without much effort, while I scratch my head really hard when read about advance feature of Typescript or Scala.


> still a relatively simple language

If only. I suspect very few Python programmers can even fully explain what `a + b` does.

If `a` and `b` are instances of classes, many would say it's equivalent to `a.__add__(b)` or `type(a).__add__(a, b)`, but in fact it's much more complex.


I once broke some Python by changing a = a + b to a += b.

If a and b are lists, the latter modifies the existing list (which may be referenced elsewhere) instead of creating a new one.

I think Python is the only language I've encountered that uses the + operator with mutable reference semantics like this. It seems like a poor design choice.


This is one of the absolute worst design mistakes in Python. The example you give (that `a = a + b` and `a += b` aren't equivalent) is bad enough:

    >>> a = b = [1, 2, 3]                >>> a = b = [1, 2, 3]
    >>> a = a + [4]                      >>> a += [4]
    >>> a, b                             >>> a, b
    ([1, 2, 3, 4], [1, 2, 3])            ([1, 2, 3, 4], [1, 2, 3, 4])
What's worse is that sometimes, they are equivalent:

    >>> a = b = (1, 2, 3)                >>> a = b = (1, 2, 3)
    >>> a = a + (4,)                     >>> a += (4,)
    >>> a, b                             >>> a, b
    ((1, 2, 3, 4), (1, 2, 3))            ((1, 2, 3, 4), (1, 2, 3))
And even worse, in order to support a version of `a += b` that sometimes modifies `a` (e.g. with lists), and sometimes doesn't (with tuples), the implementation of the `+=` operator is convoluted, which can lead to:

    >>> t = ([1, 2, 3], ['a'])
    >>> t[0] += [4]
    TypeError: 'tuple' object does not support item assignment
    >>> t
    ([1, 2, 3, 4], ['a'])
The operation raises a TypeError, despite having succeeded!


Care to elaborate? Where is the complexity hidden?


1. operators use special lookup for dunder methods--on class, not on instance:

    >>> a+1 # lookup on class 
    1+1
    2 
    >>> a.__add__(1) # instance method 
    0
2. There is __radd__ that is called if __add__ doesn't support given types (for different types).


the full story is in the language reference, but the short answer is: __radd__ (unless it's more complicated than I realize)


Yes, the next level of complexity is that `a + b` will sometimes fall back to `b.__radd__(a)` if `a.__add__(b)` returns `NotImplemented`. But also:

- There are situations where `__radd__` takes priority over `__add__`. The rules for determining that priority are complex (and IIRC subtly different from the rules that determine whether `a < b` prioritises `a.__lt__(b)` or `b.__gt__(a)`).

- The lookup of `__add__` etc uses a special form of attribute lookup that's neither equivalent to `a.__add__` nor `type(a).__add__`. This special lookup only searches `type(a)` whereas the first would find an `__add__` function on `a`, and the second on `type(type(a))`.

I've also heard of further complications caused by implementation details leaking into the language semantics - for example, see Armin Ronacher's blog post: https://lucumr.pocoo.org/2014/8/16/the-python-i-would-like-t...


I doubt many 4gl language developers could explain what a + b does in their respective language. That rabbit hole goes all the way down to the physical instruction execution on silicon.


Meanwhile some 3GL language developers, think they can explain.




Consider applying for YC's Summer 2025 batch! Applications are open till May 13

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

Search: