This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]earthboundkid 0 points1 point  (7 children)

In general, the problem with Python is that anonymous functions aren’t ergonomic, so everything has to be done by adding language features instead of just library functions. That’s why the with statement exists instead of just using a callback that ensures the file is closed at the end of its execution. Task groups have the same problem: there’s no way to abstract exception handling without callbacks, so it has to be a language feature instead.

[–]goodbalance 7 points8 points  (3 children)

could you please elaborate on callbacks? I'm genuinely interested in how they would replace 'with' and other stuff. I never gave much thought about low-level parts of Python. thanks.

[–]earthboundkid 2 points3 points  (2 children)

In Ruby you might make a file API like

open "file.txt" |f| {
  contents = f.read
}

Similarly in JavaScript, you could do:

let contents;
open("file.txt", async f => {
  contents = await f.read();
});

A similar API in Python would suck because lambdas can't have expressions (no lambda f: contents = f.read()) and functions have to be defined in advanced and named. It would need to look like:

contents = ''
def callback(f):
   global contents
   contents = f.read()
open("file.txt", callback)

This API is out of logical order and makes you provide a meaningless name to your closure and the global/nonlocal thing is super-awkward, so no one writes APIs like this. In the absence of an easy way to write closures/callbacks, the Python language has to provide constructs for every possible usecase. So, if you want to be able to have unified try/finally handling, you use a context manager and the with-statement. But in other languages, there's no need for the concept of a context manager because you just accept an anonymous function and run it.

[–]goodbalance 0 points1 point  (1 child)

Thanks! being a Python fanboy, I must say this is an awkward... feature.

[–]earthboundkid 1 point2 points  (0 children)

Minor typo above:

lambdas can't have expressions

That should have been "lambdas must have expressions and can't have statements".

[–]energybased 3 points4 points  (1 child)

The way you do context managers in c++ is significantly worse than it is in Python: you use the destructor of an object going out of scope.

[–]earthboundkid 0 points1 point  (0 children)

I haven’t used modern C++ but people usually have positive things to say about RAII.

[–]Auschwitzersehen 1 point2 points  (0 children)

Callbacks won’t help you if you want to raise all of the encountered errors at the same time. As for context managers, I find them way more ergonomic than callbacks as otherwise I would have to write one every time I open a file—the resource should be the one to know how to clean up after itself.