Live data from Hacker News

Understanding Python through its builtins

sadh.life

71–80 of 180 posts

Re: Understanding Python through its builtins

#71

Earlier quoted context omitted.

Yes, lots of them are available. But I also would like to be able to call .sum() on my iterable at the end of a chain, instead of having to mentally unwrap sum(map(filter(filter(map(...))))

I strongly dislike python, I often wonder if it would have been as popular if Guido didn't work at Google early on.

Guido joined Google in 2005, and it was already plenty popular by then.

Re: Understanding Python through its builtins

#72
post #16

Earlier quoted context omitted.

But that's good. Because a string just needs to know aboit interable to perform that operation whereas every iterable would need to implement it's own join if you had it the other way around.

Yet Ruby and JS manage to do it somehow. To me it seems natural that join should be a method on the iterable, and I always have to pause to remember Python is different.

[deleted]

Re: Understanding Python through its builtins

#73

Earlier quoted context omitted.

Yes, lots of them are available. But I also would like to be able to call .sum() on my iterable at the end of a chain, instead of having to mentally unwrap sum(map(filter(filter(map(...))))

I strongly dislike python, I often wonder if it would have been as popular if Guido didn't work at Google early on.

FWIW Python was fourteen years old when GVR joined the Borg. That doesn't address how popular it was but I think it's reasonable to say it was well established.

Re: Understanding Python through its builtins

#74
post #68

Earlier quoted context omitted.

Anything remotely interesting like that is dumped in itertools. Python's creator, Guido van Rossum, doesn't like functional/functional-ish programming a lot. That's well-known. Guido: "I value readability and usefulness for real code. There are some places where map() and filter() make sense, and for other places Python has list comprehensions. I ended up hating reduce() because it was almost exclusively used (a) to…

> "I value readability and usefulness for real code" Amen. There are plenty of languages where your code ends up looking like an entry in an obfuscation competition without even trying. If you're using Python, and working for me, I expect the code to be readable by anyone. And, no, I don't give a toss whether the code is three times the length it might have been if it was dangerously, and expensively, obscure.

if you come from a imperative background and everyone is used to working in imperative languages... I guess thats anyone.

Someone coming from, say ruby, or javascript would find list comprehension jarring. You can't compose them and you basically have to rewrite them when its time to extend them.

readable by anyone is pretty subjective.

Re: Understanding Python through its builtins

#75
post #56
post #28

In addition to this, I highly recommend just reading the codebase. I haven't written C since college and it's remarkably readable. I once tried to catalogue all the stdlib operations which release the GIL, meaning if you use only those (well, only those "heavy" bits, you can still use other small blocking glue bits), you can do "real" multithreading. It was a fun exercise!

There's a really nice (although old now) walk through of the cpython code base on YouTube. I watched it on a long 24 hour flight between Canada and Sweden a couple of years back. Edit: Found it! You're in for about 9 hours of quality watching. https://youtube.com/playlist?list=PLwyG5wA5gIzgTFj5KgJJ15lxq...

Excellent, thanks for sharing!

Re: Understanding Python through its builtins

#76

Cute fact about __debug__: it is one of the only ways to get compile-time conditionals in Python. Performing a comparison with `if __debug__:` will output byte code for the ensuing statement if and only if the interpreter is in debug mode - notably, in `-O` mode, it will not even generate a load of __debug__ and a conditional jump, and acts as if the statement didn’t exist at all.

I knew that `assert` behaved in a similar way. Turns out it's actually equivalent to an `if __debug__:` https://docs.python.org/3/reference/simple_stmts.html#gramma...

Re: Understanding Python through its builtins

#77

Cute fact about __debug__: it is one of the only ways to get compile-time conditionals in Python. Performing a comparison with `if __debug__:` will output byte code for the ensuing statement if and only if the interpreter is in debug mode - notably, in `-O` mode, it will not even generate a load of __debug__ and a conditional jump, and acts as if the statement didn’t exist at all.

Not going to lie, if I could enable stricter compile time conditions without debug mode that would be a very welcome RFC

Re: Understanding Python through its builtins

#78
post #2

Nicely written article! - Slightly off topic: I love seeing and reading Python code. Used to see many flaws in the language (things like `.append` changing the object, returning `None` instead of creating a copy and returning that), but after ten years of working with Python I really appreciate its versatility, it‘s ubiquitous availability, the large number of libraries and the community. There‘s nothing I can‘t solv…

Thank you! Things like `list.append` modifying in-place might feel like a flaw to some, but I think Python is really consistent when it comes to its behaviour. If you ask a person who comes from an object-oriented world, they'll say it only makes sense for a method on an object to modify that object's data directly. There's always ways to do things the other way, for example you can use x = [*x, item] to append and c…

One related area where Python is not consistent is operators like +=.

In pretty much all other languages that have them, the expected behavior of A+=B is exactly the same as A=A+B, except that A is only evaluated once. Now lets look at lists in Python:

   xs = [1, 2]
   ys = xs
   ys = ys + [3]
   print(xs, ys)
This prints [1, 2] [1, 2, 3], because the third line created a new list, and made ys reference that. On the other hand, this:

   xs = [1, 2]
   ys = xs
   ys += [3]
   print(xs, ys)
prints [1, 2, 3] [1, 2, 3], because += changes the list itself, and both xs and ys refer to that same list.

(Note that this is not the same as C++, because in the latter, the variables store values directly, while in Python, all variables are references to values.)

The worst part of it is that Python isn't even self-consistent here. If you only define __add__ in your custom class, you can use both + and += with its instances, with the latter behaving normally. But if you define __iadd__, as list does, then you can do whatever you want - and the idiomatic behavior is to modify the instance!

For comparison, C# lets you overload + but not +=, and automatically synthesizes the latter from the former to enforce the correct behavior.

Re: Understanding Python through its builtins

#79

Very well written. Fun little tidbit, Django abuses the fact that bools are ints in it's partition util: https://github.com/django/django/blob/01bf679e59850bb7b3e639...

It does make for some amusing code golf techniques, e.g.:

   print([
      f"{(not x % 3) * 'Fizz'}{(not x % 5) * 'Buzz'}" or x for x in range(1, 20)
   ])

Re: Understanding Python through its builtins

#80
post #16

Earlier quoted context omitted.

But that's good. Because a string just needs to know aboit interable to perform that operation whereas every iterable would need to implement it's own join if you had it the other way around.

Yet Ruby and JS manage to do it somehow. To me it seems natural that join should be a method on the iterable, and I always have to pause to remember Python is different.

I don't think it should be a method at all. It's just a function: join(iterable, separator). It can also be implemented with reduce naturally: `reduce(lambda x, y: x + separator + y, iterable)`.
Post reply on HN