Programming Languages – Differences Between Block Scoped and Function Scoped Languages

cprogramming practicesprogramming-languagesscopevba

I've noticed that some languages like C, C++, Java, Perl, and .NET Visual Basic have "block" scoping which means that a variable will only be defined within the specific code block it was declared in.

For example (C++):

if (true) {
    int x = 1;
}
std::cout << x << std::endl;

This code will fail to compile since x is only visible within the block scope created by the if statement.

error: 'x' was not declared in this scope


But languages like VBA, Python, and Javascript have "function based" scoping which means that the only time a new scope is created is when a new function is defined.

For example (VBA):

If True Then
    Dim x As Integer
    x = 1
End If
MsgBox(x)

This code runs successfully and the value of x is visible outside of the if statement.

This type of scoping seems rather confusing to me because visually it looks like x should "belong" to the if statement.


So this raises the question: Are there any advantages other than just look and feel… like performance advantages/compile speed advantages/etc… for a language to be "function" scoped rather than "block" scoped?

Best Answer

In theory, function scope should actually be faster - variables are typically created in a stack frame, and function scope would only create that stack frame once, while block scope would need to repeadedly open up a new stack frame in every block.

In practice, there are several facts that invalidate that initial assumption:

  1. No compiler is forced to create a stack frame for a block only if a specific block is actually reached - And most compilers do exactly that - A stack frame is being created that holds room for the superset of all variables that are part of the function. Languages like C only define compile-time accessibility of a variable. So, the compiler must only make sure that access to a variable that is not currently in scope is forbidden - Not that this variable is not present at all. That is a rule that can be enforced at compile time. Note that good compilers can even re-use space in the stack frame that is used by variables with non-overlapping scope and will sort and consolidate all variables in a stack frame to ensure maximum memory re-use.
  2. Block scope can allow better usage of register variables if the compiler is clever enough and enough registers are available - Because variables in a block only need to have the lifetime of the block, they can be re-used earlier.

So, from a performance viewpoint, I don't actually see advantages for both approaches - As pointed out above, you can technically implement function scope even if the language asks for block scope. That might waste some memory, though.

From a programmer's standpoint, I do see, however, clear advantages for block scope (that might, however, just be because I grew up with languages like C and C++)