Sunday, 9 February 2014

Week 5: Remembering Python's Memory Model

        The goal of this week is to appreciate how Python’s memory model brings two interesting advantages to programmers.  A memory model in the context of programming languages is the structure of how a programming language stores information about its objects during program execution.  In Python, when a name is defined, it refers to an id, which stores an object.  The link between the name and the id is stored in a dictionary-like data structure called a namespace.  What makes Python’s memory model interesting is that a separate namespace is created for every module and function call during program execution; when a module or function exits, its namespace is deleted.  We can then introduce two basic rules in Python's memory model:

(1) If there exists two same names in two separate namespaces, then the names do not interfere with each other during program execution.

(2) If a function needs to work with a name that is defined in the global namespace of a module, then the function will a create an identical name with the same id in its local namespace.

The creation of separate namespaces is the first interesting advantage of Python's memory model.  We can illustrate why this is an advantage with a thought experiment:  assume that the negation of rules (1) and (2) are true for Python's memory model.  The result is that programming in Python becomes very difficult because we can never use the same name twice in a program.  Additionally, if we run multiple programs at a time, then we have to ensure that there are no overlapping names between the programs.  Therefore, the inability to alter the ids of names in a separate namespace is one advantage of Python’s memory model.

        Another advantage of Python’s memory model is its flexibility.  To illustrate this advantage, assume that in the animated solver of the Towers of Anne Hoy game, function min_moves(n) has to find an integer i between zero and the number of cheeses n, such that the solver can solve the game in the minimum moves.  The problem is that the function returns the minimum moves for the chosen i but it does not return i itself.  So how can we access the chosen i?  A possible solution is to define i in the global namespace of the module.  Then use the global assignment in function min_moves to assign global i another id:

def min_moves(n: int) -> int:
        …
        for something in something:
        …min_moves(n - i)
            if something:
                global i
        …
                i = something
        …
        return fewest_moves

Every name i after ‘global i’ in the function refers to the i in the global namespace of the module.  Since we can access global i from anywhere in the module, then the global assignment is a solution to the inability of function min_moves(n) to return i.  Therefore, the existence of a global assignment that can change the id of a name in the global namespace is another advantage of Python’s memory model; it demonstrates its flexibility under special conditions.  Combined with a function's inability to alter the ids of names in a separate namespace under normal conditions, these are two interesting advantages of Python's memory model.


3 comments:

  1. I really like your way of finding i using a global variable. That was much more convenient than creating a class. BTW thanks for your hardworking doing Assignment 2.

    ReplyDelete
  2. i think that memory storage as global and local variables are quite inconvenient in OOP especially in the case of python. i think that it would be much more convenient to have every variable defined globally, and to be called by ever instance seen in other parts of the code.

    ReplyDelete
  3. Thank YOU Lucas for coming up with the final solution!

    And Jack, I can see where you are coming from... every name being defined globally... yet about recursive function calls? If a function modifies a global name and it is called recursively, then the name receives and new id in every call. That can lead to a programming mess! Therefore, I still support the current structure of Python's memory model, despite its greater complexity. Yet still, thank you for your interesting idea Jack. It was a great thought experiment...

    ReplyDelete