Hacker News new | ask | show | jobs
by fennecfoxen 1679 days ago
Your expectation does not match the best practices that language designers have converged on in this day and age. No one can keep up with all the variables outside a given function, and it’s way to easy to cause confusing, untraceable side effects. In almost every language, variables introduced in methods like this will be lexically scoped when the contrary is not otherwise indicated.

(Some of the older languages do differ, and usually best practices in those languages include running linters that yell at you to use explicit scopes.)

1 comments

Then the function should not use the global variable at all without explicitly indicating it. Printing 2 different variables when referring to a singular one is not great behavior, and passes the smell test for "confusing, untraceable" side effect to me. There should also be a different syntax for initializing a variable and changing a variable value, so that your intention is obvious.

I can see the point a bit of added safety of basically defaulting to a constant when declaring global variables, although since I use older languages (but not python), I have not run into that. I do find it humorous that the global variable is semi-protected in python, while the variable type is not.

> Then the function should not use the global variable at all without explicitly indicating it

Generally you use `global` to handle this.

> I do find it humorous that the global variable is semi-protected in python, while the variable type is not.

It's not, there are no differences between them. Bindings (names) are captured like most other languages, and you're free to overwrite them if you wish.

In your example you bind a new string to an existing name. I think it's pretty expected that this wouldn't suddenly change the global object to a local one, that would be madness.

But you're free to update the object _referenced_ if it's mutable:

  def f():
     thing.append(1)
  thing = []
  f()
  print(thing)
Assigning is different than appending, and is the case with a syntax ambiguity. But I'm also not a big fan of the implicit `global` in your example if it's not always implicit.

Fine, we want a test by using `global` to make sure we are doing what we intend when we assign, especially since I see python does not even have true constants so there is a basic lack of safety there. There should also be similar tests before passing every variable with the same name through our function and treating a single name as a list of references without a keyword `all` or similar. Or changing the type of a variable without explicit casting.

To me that lack of continuity just makes a language feel idiomatic and buggy.