The Working Programmer's Guide To Variables - Scope, Lifetime And More
Written by Mike James   
Thursday, 22 August 2019
Article Index
The Working Programmer's Guide To Variables - Scope, Lifetime And More
Scope
Objects And Lifetimes
Visibility

Visibility

The final twist to the story is visibility.

Suppose a variable is in scope but you then declare another variable of the same name in an inner block. Presumably you would like to work with the newly declared variable and not the one defined in the outer block.

The outer block's version of the variable is said to be in scope but inaccessible or not visible and the new definition replaces it.

You can invent additional rules to make variables that are in scope but redefined visible. For example, you could insist that every block was named and then you could refer to a variable as blockname.variablename. If you leave off the blockname then it defaults to the current block.

If this sounds familiar then I am not surprised because it is exactly the mechanism that object oriented languages used for making clear which object method is to be used in an object hierarchy.

However, this said, many language designers have decided that such a name collision is not a good idea and will flag any attempt to declare a variable within an inner block that is already in scope as an error. For example, in C# the following is an error:

{
 int i = 1;
 {

  int i = 2;

 }
}

Python does things the other way round to most languages and you have to declare a variable to be global otherwise it is assumed to be local.

Banner

Existence

Existence is an aspect of variables that most programmers rarely consider because it is an obvious consequence of the type of language that they most use.

For example, in Fortran and Basic variables are usually static, in block structured languages such as Java,  C and C#  they are usually dynamic or automatic as the term "dynamic" is used for so many things.

  • A static variable is one that exists for the duration of the program.
  • An automatic variable is created each time a function is run and then destroyed when it ends.

In languages such as Fortran and Basic static variables are the norm.

In block structured languages automatic variables are the norm.

Static variables can be used to store state information such as the number of times a function has been called. As a static variable retains its value between calls you can simply add one each time the function is called. Automatic variables make it impossible to set up a use counter in this way because they are destroyed when the function terminates. In this case you have no choice but to use a global variable or at least one that lives long enough to retain the count. 

Automatic variables minimise storage requirements by assuming that if a procedure isn't running then its local variables cannot be in use by any other procedure.

Of course in a block structured language automatic variables exist when the block they are declared in is executing and they are destroyed when the block is completed. 

This existence rule is just an extension of the nested scope rule - if a variable is in scope then it exists if it isn't then it doesn't.

Even block structured languages normally allow the programmer to create static variables on demand. Usually by declaring them using a a STATIC modifier. Languages that don't have a STATIC modifier and so don't appear to recognise the existence of static variables allow you to create static variables as global variables. A variable that has global scope will exist for the whole program and so can be described as a global static variable.

This is of course the trick used in both C++, JavaScript and Object oriented Pascal to ensure that objects exist for the duration of the program - they are all declared at the highest level in the program!variablescope

The Stack 

You might be wondering what the advantage of static variables is that many early languages adopted them as the only type they provided?

Well the answer is that a static variable can be assigned to an area of storage by the compiler at compile time and it stays there at the same location throughout the run of the program. This makes static variables simpler and faster than automatic variables.

Automatic variables on the other hand cannot be allocated at compile time they have to allocated to storage at run time. Fortunately this isn't as difficult as it sounds because most block structured languages use some sort of execution stack.

When a new procedure is started the old variables are pushed on the stack and the new procedures are allocated. When the procedure is finished the original procedure's variables are pulled off the stack. Using the stack makes automatic variables very easy to implement. 

Variables as Names

It is generally assumed that variables form some sort of immutable name system. If you have a variable called Total then it stores a quantity that you can forever think of as "the total". It is natural to think that variable names, name things. Unfortunately this starts to break down when the language becomes more advanced. A variable can be a mutable reference to an object and this means that the object isn't necessarily uniquely associated with the variable and its name.

In JavaScript you can write:

var myPoint=new Point(x,y);

where Point is a constructor for a Point object. It is tempting to think that the new object is called myPoint but this isn't the case. The object is annoymous and myPoint is a variable that just happens to reference it. Consider:

var myOtherPoint=myPoint;

now both myOtherPoint and myPoint reference the same object - so what is its "name"? Clearly it doesn't have a fixed name.

This doesn't seem so strange when its a general object like Point but in JavaScript functions are objects and they are, by the same reasoning annoymous. For example:

var myFunc=function(){code};

or equivalently

function myFunc(){code};

In both cases the "name" of the function is myFunc and many programmers regard this as fixed in some way. It isn't. For example:

var myOtherFunc=myFunc;

Now you can call the function using myFunc or myOtherFunc and again what is the name of the function?

In languages that use variables to reference object the objects are annoymous and do not have fixed names - unless of course the language introduces a rule to make them fixed.

In many languages it is better to always think of a variable as a muatable named reference to an object and not the immutable name of an entity.

Conclusion 

At this point you can now see that variables can be classified  in two ways Scope - local, nested, global; and Existence - static and automatic.

No doubt there are other subtle ways of managing variables their scope, visibility, lifetime and so on - but this more or less corresponds to what most programmers have to deal with today.  

in general when learning a new language you have to ask what the rules are for the binding of a name to an entity i.e. its scope and you have to ask about the question of the lifetime of that binding. There are many variations of possible answers. 

Related Articles

Binary - Negative Numbers

Binary Arithmetic

Inside the Computer - Addressing

The Heart Of A Compiler

The Fundamentals of Pointers

Computer Memory and Pigeonholes

 

To be informed about new articles on I Programmer, install the I Programmer Toolbar, subscribe to the RSS feed, follow us on, Twitter, FacebookGoogle+ or Linkedin,  or sign up for our weekly newsletter.

  • Mike James is the author of Programmer's Python: Everything is an Object published by I/O Press as part of the  I Programmer Library. With the subtitle "Something Completely Different" this is for those who want to understand the deeper logic in the approach that Python 3 takes to classes and objects.

 

 

 

What Programmers Know

knowcover

Contents

  1. The Computer - What's The Big Idea?*
  2. The Memory Principle - Computer Memory and Pigeonholes*
  3. Principles of Execution - The CPU
  4. The Essence Of Programming
  5. Variables - Scope, Lifetime And More*
  6. Binary Arithmetic
  7. Hexadecimal*
  8. Binary - Negative Numbers*
  9. Floating Point Numbers*
  10. Inside the Computer - Addressing
  11. The Mod Function
  12. Recursion
  13. The Lost Art Of The Storage Mapping Function *
  14. Hashing - The Greatest Idea In Programming
  15. Advanced Hashing
  16. XOR - The Magic Swap*
  17. Programmer's Introduction to XML
  18. From Data To Objects*
  19. What Exactly Is A First Class Function - And Why You Should Care*
  20. Stacks And Trees*
  21. The LIFO Stack - A Gentle Guide*
  22. Data Structures - Trees
  23. Inside Random Numbers
  24. The Monte Carlo Method
  25. Cache Memory And The Caching Principle
  26. Data Compression The Dictionary Way
  27. Dates Are Difficult*
  28. Sequential Storage*
  29. Magic of Merging*
  30. Power of Operators
  31. The Heart Of A Compiler*
  32. The Fundamentals of Pointers
  33. Functional And Dysfunctional Programming*

* Recently revised

espbook

 

Comments




or email your comment to: comments@i-programmer.info

To be informed about new articles on I Programmer, sign up for our weekly newsletter, subscribe to the RSS feed and follow us on Twitter, Facebook or Linkedin.

Banner


Compilers, Interpreters, VMs and JIT

The distinction between a compiler and an interpreter is one that can cause controversy. One programmer's compiler is another's interpreter and the whole subject gets very murky when you throw in the  [ ... ]



Coded Easter Eggs

A software Easter Egg is an intentionally hidden novelty or message concealed for personal reasons within a computer program or application.  We take a look at its history and original motivation [ ... ]


Other Articles

<ASIN:1871962587>

<ASIN:B07S1K8KLW>

 

 



Last Updated ( Thursday, 22 August 2019 )