%%% This is the scribe notes template for CS611
%%% There are several comments preceded by CS611: and boxed in %%%%'s
%%% which indicate where macros should be altered to set up the header
%%% for the paper.  Your Notes should go at the comment SCRIBE NOTES GO HERE!.

%%% In the various .sty files that accompany this .tex file you will
%%% find LaTeX macros that make it easier to typeset inference rules
%%% and programming language constructs.  You must make sure that the
%%% file proof.sty is in a path searched by LaTeX when you try to
%%% use this file.  Take a look to see what macros are available--it
%%% will save you time and make the notes look better.  Feel free to
%%% extend the set of macros--post them to the newsgroup and contact
%%% the course staff if you come up with some good ones so they can be
%%% added to the template.

%%% This template includes examples of how to use some of the macros
%%% to give you an idea of how they work.  (Delete the examples when
%%% you do your scribing.)

\documentclass{article}
\usepackage{611-lecture,amsmath,amssymb}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% CS611: Please fill in these macros as appropriate:
\lecture{12}                  %% Lecture number
\title{Modules and State}   %% Title of lecture
%\author{Krishnaprasad Vikram, David Crandall}       %% name of scribe
\date{25 September 2006}     %% Date of lecture, e.g., 1 January 2001
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% See 611.sty for a variety of macros that will be helpful in
% typesetting the lecture. Here are a few of particular interest:
%
% "x"       x in keyword font (e.g., "if", "#t")
% _x_       x in italics
% \nm{n}    n in slanted font (used for abbreviations)
% <e>       e in angle brackets
% \lt       less-than sign
% \gt       greater-than sign
% \SB{x}    x in semantic brackets
% \Tr x{y}  x[[y]] with x in calligraphic font
%           (if x is more than a single character, use \Tr{x}{y})

\newcommand\LOOKUP[2]{\mathrm{LOOKUP}~{#1}~{#2}}
\newcommand\UPDATE[3]{\mathrm{UPDATE}~{#1}~{#2}~{#3}}
\newcommand\MALLOC[2]{\mathrm{MALLOC}~{#1}~{#2}}
\newcommand\EMPTY{\mathrm{EMPTY\mbox{-}STORE}}
\renewcommand\dom[1]{\mathrm{dom}\,{#1}}
\newcommand\p[2]{\langle{#1},\,{#2}\rangle}
\newcommand\bigcdot{\mathrel{\raisebox{1pt}{$\scriptscriptstyle\bullet$}}}
\newcommand\holed[1]{[\,#1\,]}
\newcommand\hole{\holed\bigcdot}
\newcommand\context[1]{E\kern1pt\holed{#1}}
\newcommand\contextHole{\context\bigcdot}
\newcommand\goesto[2]{\underset{#2}{\overset{#1}\longrightarrow}}
\newcommand\ifthenelse[3]{\mathsf{if\ }#1\mathsf{\ then\ }#2\mathsf{\ else\ }#3}
\newcommand\letin[3]{\mathsf{let\ }#1 = #2\mathsf{\ in\ }#3}
\newcommand\letrec[5]{\mathsf{letrec\ }#1 = #2\mathsf{\ and\ \ldots\ and\ }#3 = #4\mathsf{\ in\ }#5}
\newcommand\letrecone[3]{\mathsf{letrec\ }#1 = #2\mathsf{\ in\ }#3}
\newcommand\true{\ensuremath{\mathsf{true}}}
\newcommand\false{\ensuremath{\mathsf{false}}}
\newcommand\error{\ensuremath{\mathsf{error}}}

\begin{document}

\maketitle

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% CS611: SCRIBE NOTES GO HERE!
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\section{Introduction}

In the last two lectures, we studied the static and dynamic approaches to
variable scoping.  These scoping disciplines are mechanisms for binding
names to values so that the values can later be retrieved by their assigned name.

Both static and dynamic naming strategies are _hierarchical_ in the
sense that variables enter and leave scope according to the program's abstract
syntax tree (in the case of static scoping) or the tree of function
calls (in dynamic scoping). This dependence on hierarchy might prove restrictive 
or inflexible for writing certain kinds of programs. In such cases we might want
a more liberal naming discipline that is independent of any hierarchy induced
by the syntactic structure or call structure.

Such a non-hierarchical scoping structure is provided by _modules_.
A _module_ is like a software black box with its own local namespace.
It can export resources as a set of names without revealing its internal
composition. Thus the names that can be used at a certain point in
a program need not ``come down from above'' but can also be
names exported by modules.

Good programming practices encourage _modularity_, especially in the construction
of large systems.  Programs should be composed of discrete components
that communicate with one another along small, well-defined
interfaces and are reusable.  Modules are consistent with this
idea.  Each module can treat the others as black boxes; that is, they know
nothing about what is inside the other module except as revealed by the interface.

Early programming languages had one global namespace in which names of all functions in source files and libraries
were visible to all parts of the program.  This was the approach for example of FORTRAN and C.
There are certain problems with this:
\begin{itemize}
\item
The various parts of the program can become tightly coupled. 
In other words, the global namespace does not enforce the modularity
of the program. Replacing any particular part of the program with an enhanced
equivalent can require a lot of effort.
\item
Undesired name collisions occur frequently, since names inevitably tend to coincide.
\item
In very large programs, it is difficult to come up with unique names, thus
names tend to become non-mnemonic and hard to remember.
\end{itemize}

A solution to this problem is for the language to provide 
a _module mechanism_ that allows related functions, values, and types
to be grouped together into a common context.
This allows programmers to create a local namespace, thus
minimizing naming conflicts.  Examples of modules are classes in Java and C++,
packages in Java, or structures in ML.
Given a module, we can access the variables in it by qualifying
the variable names with the name of the module, or we can \emph{import}
the whole namespace of the module into our code, so we can use the module's
names as if they had been declared locally.

\section{Modules}

A _module_ is a collection of named things (such as values, functions,
types etc.) that are somehow related to one another. The programmer
can choose which names are _public_ (exported to other parts of the
program) and which are _private_ (inaccessible outside the module).

There are usually two ways to access the contents of a module. The
first is with the use of a _selector expression_, where the name of the module is prefixed 
to the variable in a certain way.  For instance, we write "m.x" in Java 
and "m::x" in C++ to refer to the entity with name "x" in the module "m". 

The second method of accessing the contents of a module is to use an expression that
brings names from a module into scope for a section of code. 
For example, we can write something like "with m do e", which means that
"x" can be used in the block of code "e" without prefixing it with "m". 
In ML, for instance, the command ``"Open List"'' brings names from
the module "List" into scope. In C++ we write ``"using namespace 
module\_name;"'' and in Java we write ``"import module\_name;"'' 
for the similar purposes.

%In ML, for example, one can write $"with"~m~"do"~e$ to bring all
%public symbols of $m$ into scope during evaluation of $e$.
%The using $"namespace"$ and $"import"$
%commands are examples of this construct in C++ and Java, respectively.

Another issue is whether to have modules as _first class_ or _second
class_ objects.  First class objects are entities that can be passed to a 
function as an argument, bound to a variable or returned from a function. 
In ML, modules are not first class objects, whereas in Java, modules can 
be treated as first class objects using the _reflection mechanism_.
While first-class treatment of modules increases the flexibility of a language, 
it usually requires some extra overhead at run-time.

\section{Module Syntax and Translation to uML}

We now extend uML, our simple ML-like language, to support
modules. We call the new language uML+M to denote that
it supports modules. There must be some values that we can
use as names with an equality test.  The syntax of the new language is:

\medskip

\[\begin{array}{rcll}
e &::=& \ldots\\
& \bnf & "module"~(x_1=e_1, \ldots , x_n=e_n) & \textrm{(module definition)} \\
& \bnf & e_m . e & \textrm{(selector expression)} \\
& \bnf & "with"~e_m~e & \textrm{(bringing into scope)} \\
& \bnf & "lookup-error" & \textrm{(error)}
\end{array}\]

\medskip

We now want to define a translation from uML+M to
uML.\footnote{Actually our translation is to the target language
uML+S+"lookup-error", a simple extension to
uML that contains equality operators for strings and an extra
token called "lookup-error", which is returned when a variable name is not found
in a module.}
To do this, we notice that a module is really
just an environment, since it is a mapping from names
to values. Here is a translation of the module definition:

\medskip

\begin{tabbing}
\hspace{1.6in}\=\hspace{.4in}\=\kill
\> $\SB{"module"~(x_1=e_1, x_2=e_2, \ldots , x_n=e_n)}~\rho~\definedas$  \\[1em]
\> \> $\lambda x.~$\=$\ifthenelse{x=x_1}{\SB{e_1}~\rho}{}$ \\
\> \> \> $\ifthenelse{x=x_2}{\SB{e_2}~\rho}{}$\\
\> \> \> \ldots \\
\> \> \> $\ifthenelse{x=x_n}{\SB{e_n}~\rho}{}$\\
\> \> \> "lookup-error"
\end{tabbing}

\medskip

The above is one possible translation. Note that $\rho$ is passed       
as the environment to the translation of $e_1,\ldots,e_n$. This has an     
important consequence: variables defined within the module are _not_    
visible within the initialization expression of other variables in      
the module. For instance, in the above translation, we cannot refer      
to any of the $x_i$'s within any of the $e_i$'s.  Nor does it seem      
possible to use the resulting environment within itself for the purpose 
of accessing the module variables, since this leads to circularity problems.                                                               

However, we could translate "module" using techniques from the translation of "letrec". The environment that results after the translation should be the same that is used within the module. This can be found by taking the fixpoint of the function

\medskip

\begin{tabbing}
\hspace{1.8in}
$\lambda \rho '.~\lambda x.~$\=$\ifthenelse{x=x_1}{\SB{e_1}~\rho'}{}$\\
\> $\ifthenelse{x=x_2}{\SB{e_2}~\rho'}{}$\\
\> \ldots\\
\> $\ifthenelse{x=x_n}{\SB{e_n}~\rho'}{}$\\
\> "lookup-error"
\end{tabbing}

\medskip

\noindent
This works fine if the $e_i$'s are functions.
%, because a fixed point can be taken.
However, it is not clear how to handle variables whose initialization
expressions reference one another. For instance, consider
\[
"module"~(x_1=x_2,~x_2=x_1)
\]
Java and C++ avoid this problem by allowing functions within a
class to call any other function within the class, but
initialization expressions of variables are only allowed to refer
to variables declared earlier in the class.
For our purposes, we stay with the translation above.

The remainder of the translation is as follows:

\medskip

\begin{eqnarray*}
\SB{e_m.e}~\rho &\definedas& (\SB{e_m}~\rho)~(\SB e~\rho)\\
\SB{"with"~e_m~e}~\rho &\definedas& \SB e~("MERGE"~\rho~(\SB{e_m}~\rho))\\
"MERGE"~\rho~\rho' &\definedas& \lam x{\letin y{\rho'~x}{\ifthenelse{y="lookup\mbox{-}error"}{\rho~x}y}}\\
\end{eqnarray*}

\medskip\noindent
In the translation of $\SB{e_m.e}$, presumably $\SB e~\rho$ would evaluate to a name.

Note that these translations are really functions of environments.
That is, the translation above for $\SB{e_m.e}$ can be written:

\begin{eqnarray*}
\SB{e_m.e} &=& \lam\rho{(\SB{e_m}~\rho)~(\SB e~\rho)}.
\end{eqnarray*}

\section{State}

_Program state_ refers to the ability to change the values of program variables over time.
The $\lambda$-calculus and the uML language do not have state in the sense that once a variable
is bound to a value, it is impossible to change that value as long as the variable is in scope. 
Although state is not a necessary feature of a programming language---for example,
the $\lambda$-calculus is Turing complete but does not have a notion of state---it is
a common feature of most languages, and most programmers are accustomed to it.

\subsection{Reference Cells}

We extend uML to include the ability to change the values of
variables, and we call the new language uML!. We use a construct
called a _reference cell_ (aka _mutable variable_, aka _pointer variable_) that allows
the variable to be rebound to different values over time.
The syntax of uML! is as follows:

\medskip

\[
\begin{array}{rcll}
e &::=& \ldots\\
& \bnf & "ref"~e & \textrm{(create a reference cell with initial value $e$)} \\
& \bnf & !e & \textrm{(evaluation or dereference)} \\
& \bnf & e_1~:=~e_2 & \textrm{(assignment or mutation)} \\
& \bnf & "unit" & \textrm{(no value)}
\end{array}
\]

\medskip

Informally, the meaning of these new expressions is as follows.
Evaluating the expression $"ref"~e$ creates a new reference cell
having the initial value $e$.  The expression $!e$ evaluates to
the current value of the reference cell $e$.  The assignment
$e_1 := e_2$ assigns the value of $e_2$ to the reference cell
$e_1$, and in our semantics returns the value "unit".

Other design choices could have been made.
For example, the assignment operator could have
returned the value of $e_2$ so that expressions like
$e_0~:=~(e_1~:=~e_2)$ would make sense and could be used
to assign the same value to multiple variables.

In this treatment, reference cells are first-class objects. This is more powerful
than simple mutable variables as in C. It is also more dangerous, because
it introduces _aliasing_, as the following example demonstrates:

\medskip

\begin{tabbing}
\hspace{2in}\=\hspace{1em}\=\hspace{1em}\=\hspace{1em}\=\kill
\> $\letin x{"ref"~1}{}$\\
\> \> $\letin yx{}$\\
\> \> \> $\letin z{(x:=2)}{}$\\
\> \> \> \> $!y$
\end{tabbing}

\medskip

\noindent

Here $y$ is an alias for $x$.  Dereferencing $y$ gives us the value of $x$,
which in this case has changed from 1 to 2. The expression therefore 
evaluates to 2.  In other words, if you kick $x$, $y$ jumps!

\subsection{Operational Semantics}

We now give an operational semantics for reference cell
expressions in uML!. To do this, we define a _configuration_
as a pair $\p e\sigma$, where $e$ is an expression and $\sigma$ is
a function mapping reference cells to values.  Reference cells
are denoted generically by $\ell$.

\medskip

\[\begin{array}c
\displaystyle\frac{e~\goesto{}{\mathrm{uML}}~e'}{\p e\sigma~\goesto{}{\mathrm{uML!}}~\p{e'}\sigma}\\[3em]
\p{"ref"~v}\sigma~\rightarrow~\p\ell{\sigma[v/\ell\kern1pt]},\quad\ell\notin\dom\sigma\\[1em]
\p{!\ell}\sigma~\rightarrow~\p{\sigma(\ell)}\sigma,\quad\ell\in\dom\sigma\\[1em]
\p{\ell:=v}\sigma~\rightarrow~\p{"unit"}{\sigma[v/\ell\kern1pt]},\quad\ell\in\dom\sigma
\end{array}\]

\noindent
where $\sigma[v/\ell\kern1pt]$ is the same function as $\sigma$, except that
the value on input $\ell$ is changed to $v$.  These are eager evaluation rules, evaluating values
from left to right, so the evaluation contexts are given by the grammar:
\begin{eqnarray*}
E &::=& \hole \bnf "ref"~E \bnf !\,E \bnf E := e \bnf \ell := E.
\end{eqnarray*}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\end{document}
