What are the benefits and drawbacks of variable hoisting in programming languages?

Viewed 657

The following Python program A outputs 1, as expected, while the following Python program B raises an unbound local variable x error, counterintuitively.

  • Program A:
def f(): print(x)
x = 1
f()
  • Program B:
def f(): print(x); x = 2
x = 1
f()

Javascript has the exact same behaviour.

  • Program A:
function f() { console.log(x); }
let x = 1;
f();
  • Program B:
function f() { console.log(x); let x = 2; }
let x = 1;
f();

However, C++ outputs 1 in both cases, as expected.

  • Program A:
#include <iostream>
int x;
void f() { std::cout << x; }
int main() { x = 1; f(); return 0; }
  • Program B:
#include <iostream>
int x;
void f() { std::cout << x; int x = 2; }
int main() { x = 1; f(); return 0; }

So all programs A output 1. The differences in programs B between Python and Javascript on the one hand, and C++ on the other hand, result from their different scoping rules: in C++, the scope of a variable starts at its declaration, while in Python and Javascript, it starts at the beginning of the block where the variable is declared. Consequently, in C++ printing variable x in function f resolves to the value 1 of global variable x since it is the only variable in context at this point of execution. In Python and Javascript printing variable x in function f resolves to nothing and raises an unbound local variable x error since local variable x is already in context at this point of execution and therefore it masks global variable x without being bound yet to the value 2. This counterintuitive behaviour of Python and Javascript is also known as variable hoisting since it ‘hoists’ variable declarations (but not definitions) at the beginning of their blocks.

What are the benefits and drawbacks of variable hoisting in programming languages?

1 Answers

This is more a artifact of the language, rather than a programmer oriented feature.

For python and javascript, the new variable means allocate an entry in the name dictionary, until you actually create an object and assign it. In C++ there is no name dictionary in the run-time, the definition needs to actually allocate memory for the object (and it could be a 10MB array for all we know).

This does allow C++ to fit into smaller memory footprint if you really need that. Otherwise there's no much reason to think about it.

From the developer's perspective you have a bug. Your x has 2 meanings. Programming is hard enough as it is without having variables change meaning on you, so I would avoid as much as possible. I think C++ would give you a warning in some such a cases.

In practice you would get used to either setup.

Related