Most active commenters
  • TZubiri(3)

←back to thread

498 points azhenley | 11 comments | | HN request time: 0.443s | source | bottom
1. sgarland ◴[] No.45770550[source]
Dumb question from a primarily Python programmer who mostly writes (sometimes lengthy) scripts: if you have a function doing multiple API calls - say, to different AWS endpoints with boto3 - would you be expected to have a different variable for each response? Or do you delete the variable after it’s handled, so the next one is “new?”
replies(3): >>45770602 #>>45770650 #>>45770806 #
2. TZubiri ◴[] No.45770602[source]
I think renaming an old variable is a common and sensible way to free a resource in python. If there are no valid names for a resource it will be garbage collected. Which is different in languages like C++ with manual memory management.

John Carmack is a C++ programmer apparently that still has a lot to learn in python.

replies(4): >>45770941 #>>45770988 #>>45773607 #>>45777177 #
3. ForHackernews ◴[] No.45770806[source]
If they're representing different data from different API calls, yeah, I'd be strongly inclined to give them different names.

    order_data = boto.get_from_dynamodb()
    customer_data = boto.get_from_rds()
    branding_assets = boto.get_from_s3()
    return render_for_user(order_data, customer_data, branding_assets, ...)
4. sswatson ◴[] No.45770941[source]
In the vast majority of cases, developer ergonomics are much more important than freeing memory a little earlier. In other scenarios, e.g., when dealing with large data frames, the memory management argument carries more weight. Though even then there are usually better patterns, like method chaining.

FYI John Carmack is a true legend in the field. Despite his not being a lifelong Python guy, I can assure you he is speaking from a thorough knowledge of the arguments for and against.

replies(1): >>45777782 #
5. ForHackernews ◴[] No.45770988[source]
But wouldn't you do that inside a function or a loop body?
replies(1): >>45771267 #
6. busfahrer ◴[] No.45771267{3}[source]
In TFT, he mentions

> [...] outside of true iterative calculations

7. maleldil ◴[] No.45773607[source]
Not "a resource", but memory specifically. If there's a proper resource (e.g. a file), you should ensure it's explicitly released instead of relying on the GC (using with/close/etc.) And if memory usage is really important, you should probably explicitly delete the variable.

Anything else is wishful thinking, trying to rely on the GC for deterministic behaviour.

8. blueside ◴[] No.45777177[source]
if this guys learns enough, who knows, he may have a future in programming!
9. TZubiri ◴[] No.45777782{3}[source]
>developer ergonomics are much more important than freeing memory a little earlier

Preach to the python choir bro, but it should be telling when a python bro considers it's too ergonomic and wasteful.

At some point being clean and efficient about the code is actually ergonomic, no one wants to write sloppy code that overallocates, doesn't free, and does useless work. To quote Steve Jobs, even if no one sees the inside part of a cabinet, the carpenter would know, and that's enough.

tl;dr: Craftmanship is as important as ergonomics.

replies(1): >>45778122 #
10. sswatson ◴[] No.45778122{4}[source]
In this case, overuse of re-assigning is the sloppy thing to do, and immutability by default is the craftsman's move. Reducing your program's memory footprint by re-assigning variables all the time is a false economy.
replies(1): >>45781780 #
11. TZubiri ◴[] No.45781780{5}[source]
So if you are preparing a 50Kb webpage, and you do 10 steps of processing, you would have a 500KB memory footprint that might be held during the life of the connection? All the while the footprint and thus capacity of your server could have been 100Kb? Nice craftmanship dude!

We are not even talking about in-place algorithms, just 10 functions that process an html into a new array, maybe:

html = load_template(route) html = formatstring(html,variables) html= localize_paths(html) ...

And you would rather have it:

template = load_template(route) formatted_html = formatstring(template,variables) html_with_localized_paths = localize_paths(html)

And you would rather have the latter? For what gain? I think you wouldn't.

"Only a sith deals in absolutes", you have to recognize that both are valid under different contexts. And I'm merely explaining why inmutable is the default in python, 1: python doesn't do programmer self restrictions like const and private; 2: memory is automatic, so there's no explicit allocation and freeing like in C++, so using a new variable for each thing isn't a zero overhead abstraction.

Even for smaller cases, (not 50kb arrays), it's still the proper thing to do, although you have freedom to choose, it's easier to just follow one style guide and protocol about how to do things, if it's pythonic to reuse the variable name, just reuse the variable name. Don't fall for the meme of coming from another language and writing C++ in python or Java in python, you are not a cute visionary that is going to import greatness into the new language, it's much better to actually learn the language rather than be stubborn.

There's places where you can be super explicit and name things, if it's just an integer then it's a very cheap comment that's paid in runtime memory instead of in LOC. But this is why the default in python is not const, because variable name reuse is a core python tactic, and you are not our saviour if you don't get that, you are just super green into the language.