_____
 ---'   __\_______
            ______)         Beyond the field - Declarations in Poke
            __)               structs
           __)
 ---._______)

                                                      Jose E. Marchesi
                                                      October 23, 2019

The main purpose of Poke structs  and unions is to define fields that,
eventually, will be mapped and accessed to inspect and manipulate some
underlying  IO space  like a  file.   However, they  can also  contain
declarations of other entities; namely variables, types and functions.
This is a nice abstraction that allows to implement useful idioms like
setters and  getters, pretty printers,  and much more.   Let's explore
this in some detail.
    

Lexical Binding and Scoping

Before dealing with struct types, let's first have a super quick look at how Poke deals with variables. Basically, Poke implements what is known as "lexical binding". Many programming languages use lexical binding. Notable examples are Scheme, Pascal and Javascript. In lexical binding, entities that can be referred by name are organized in a hierarchical <i>lexical environment</i>. When an entity is referenced from within a given level in the hierarchy, it is traversed bottom-up until an entity with the given name is found. If no entity is found, then an error is produced. Each level in the lexical environment is introduced by some construct in the programming language, which always defines a sort of block, either implicitly of explicitly. For example, compound statements introduce a new lexical level. Let's see an example:
{
  /* Outer block.  */
  var a = 10;
  var b = "foo";

  {
    /* Inner block.  */
    var c = 30;
    var a = 2;

    printf "a is %i32d\n", a;
  }

  printf "a is now %i32d\n", a;
In the excerpt above the outer compound statement delimits a block that introduces it's own lexical level. This block has two "bindings", associating the name 'a' with an integer variable, and the name 'b' with a string variable. Similarly, the inner compound statement introduces another lexical level, with two bindings for 'c' and 'a'. When the reference to the name 'a' is found in the inner 'printf', a search process is performed starting in the current lexical level. In this case, a binding associating 'a' with an integer variable that contains the number 2 is found. Therefore, the inner 'printf' prints 2. We say that the inner binding for 'a' "ghosts" the binding of the same name in the outer block. When the execution reaches the end of the inner compound statement, it's associated lexical level is exited: it's bindings are no longer accessible. Therefore, the searching process triggered by the reference to 'a' in the outer block results in the variable containing 10, not 2. Functions also introduce lexical levels, and they can be nested.