That scope logic is normal in many interpreted languages. I love it in Python.
Python does support block scoping- so no- it doesn't work there. Also, if you need to use variables in outer scopes, it's ok to declare them there. There is literally, and I mean this, literally- no possible justification for using inner-scoped variables in an outer scope that they weren't declared in.
if predicate:
A = 3
else:
A = 5
B = A / 2
...
Why forward declare A = None?
Because it announces that you intend to use the name 'A' in the current scope after some assignment happens in a nested one. It's intentional.
It /can/ be useful, but it should be opt-in. JavaScript had to figure this out with their 'var' declaration scoping too.
Also, try:
A = (predicate) ? 3 : 5
Or, in a language that embraces expressions instead of statements:
val A = if (predicate) { 3 } else { 5 }
These are all more intentional, concise, and readable than allowing variables to outlive their scope by default.
Java has also alternative approach:
final a;
if (predicate) {
a = 3;
} else {
a = 5;
}
`final` makes it possible for variable to be assigned exactly once. Verbose but useful when "?:" is not a good fit.
if (true) { $a=1; }
echo($a); // outputs 1