Live data from Hacker News

Understanding Python through its builtins

sadh.life

41–50 of 180 posts

Re: Understanding Python through its builtins

#41
post #40

You know what helped me with python? Breakpoints inside vscode's module. It all just kinda clicked.

python actually has a build-in `breakpoint()` function. I think it brings up a repl at the line.

I've been using that instead of print debug, it's been great.

Re: Understanding Python through its builtins

#42

Earlier quoted context omitted.

> things like `.append` changing the object, returning `None` instead of creating a copy and returning that The obvious question is why it can't return a reference to the list instead of returning None. I feel like if I've been using the language on an almost daily basis for ten years now and I still get burned by that all the time, then it's just a poorly designed feature.

The advantage of mutating operations always returning None is that you can easily tell whether a mutation is happening by looking at the code. If you see y = f(x) that means x is unchanged, whereas if you see just f(x) on a line that means something stateful is happening.

There are counter-examples: functions that return values while also having side effects, cases where the developer simply made a mistake.

Coming from a language with baked-in immutability, Python’s behavior in this regard was very difficult to get used to.

Re: Understanding Python through its builtins

#43
I am a pretty average Python programmer(5 years teaching, 15 years writing).

I still wonder what was the reasoning for allowing creation of local objects with the same name as builtins.

Okay it can be nice to redefine pprint as print I suppose.

Still how many sum, list, min, max, dict(!) have been erroneously redefined in beginner tutorials and beginner code.

From my experience sum and list suffer the most.

Sure there are linters that will warn you but there should be a setting for the interpreter (as in -Werror in GCC) to disallow this silliness.

Re: Understanding Python through its builtins

#44
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…

> things like `.append` changing the object, returning `None` instead of creating a copy and returning that The obvious question is why it can't return a reference to the list instead of returning None. I feel like if I've been using the language on an almost daily basis for ten years now and I still get burned by that all the time, then it's just a poorly designed feature.

random.shuffle() has bitten me that way a few times too:

    array = random.shuffle(array)
because I expected it to return a copy or reference, instead making my array None.

It would also enable chaining operations:

    array = array.append(A).append(B).sort()
In-place vs immutable copy is a language design choice with tradeoffs on both sides, but there's no reason that I can see to not return a reference to the list.

Perhaps recognizing this is really the job of an external linter. Sometimes I wonder if the future of enforcing canonical formatting on save like "gofmt" or "black" will extend to auto-correcting certain goofy errors on each save.

mypy would yell at you about this, but afaik type-checked python still isn't the norm.

Re: Understanding Python through its builtins

#45
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…

> Used to see many flaws in the language (things like `.append` changing the object, returning `None` instead of creating a copy and returning that)

I think it's pretty off-base to call this a "flaw". Immutable structures have their place and can be very helpful where appropriate, but making its core primitives work this way is far outside the scope or the philosophy of Python. If you want otherwise, you're really wanting an entirely different language. And there's nothing wrong with that! But I think it would be a "flaw" for Python to make these operations immutable, even though I love immutability personally.

Re: Understanding Python through its builtins

#46

Earlier quoted context omitted.

> things like `.append` changing the object, returning `None` instead of creating a copy and returning that The obvious question is why it can't return a reference to the list instead of returning None. I feel like if I've been using the language on an almost daily basis for ten years now and I still get burned by that all the time, then it's just a poorly designed feature.

The advantage of mutating operations always returning None is that you can easily tell whether a mutation is happening by looking at the code. If you see y = f(x) that means x is unchanged, whereas if you see just f(x) on a line that means something stateful is happening.

Agreed. JavaScript's Array.sort is an example of this. Most of JavaScript's other array methods return a new array and people get used to chaining them, but sort mutates the array and also returns a reference to it. You can actually get pretty far before being bitten by this so long as you're sorting already-copied arrays. But then one day you hit a bizarre bug caused by behavior that's been sneaking past your radar the whole time.

Re: Understanding Python through its builtins

#47
post #43

I am a pretty average Python programmer(5 years teaching, 15 years writing). I still wonder what was the reasoning for allowing creation of local objects with the same name as builtins. Okay it can be nice to redefine pprint as print I suppose. Still how many sum, list, min, max, dict(!) have been erroneously redefined in beginner tutorials and beginner code. From my experience sum and list suffer the most. Sure ther…

I think linters are really effective to figure out such issues in professional code.

For students for example, I'll have to agree. Maybe having a flag or environment variable that teachers can set up for it would be a nice idea. You should start a thread on the python-ideas mailing list about this, and it might get somewhere :)

Re: Understanding Python through its builtins

#48
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!

> I highly recommend just reading the codebase

Me too. When I used to write Ruby I read a lot of CRuby source code. I achieved a much deeper understanding of the language that way. Even answered some really fun stackoverflow questions.

Now the first thing I do when I see a new language is read its source code.

Re: Understanding Python through its builtins

#49
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.
Post reply on HN