%%% 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}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% CS611: Please fill in these macros as appropriate:
\lecture{36}                  %% Lecture number
\title{Modules and dependent types}   %% Title of lecture
\author{Yookyung Jo and Aaron Lenfestey}       %% name of scribe
\date{28 November, 2005}     %% 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\unpack[3]{"unpack"\ #1\ "as"\ #2\ "in"\ #3}
\newcommand\pack[2]{"pack"_{#1}#2}

\newcommand{\kw}[1]{\ensuremath{\mathtt{#1}}}
\newcommand{\pr}{^{\prime}}

\begin{document}

\maketitle

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% CS611: SCRIBE NOTES GO HERE!
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\noindent Last lecture introduced existential types.
This lecture will cover


\begin{itemize} % use enumerate for numbered list
\item Typed closure conversion
\item Dependent module types
\item Strong existentials
\end{itemize}

\section{Typed closure conversion}

Existential types enable information hiding.
We can hide certain contents by replacing
their type $\tau$ with a type variable $X$.

\noindent With existential types, we have the following additional syntax
for types and terms.

\[
\begin{array}{lll}
\tau & ::= & ...  ~|~ \exists X.\tau \\
e & ::= & ... ~|~ \kw{pack}~_{\exists X.\tau}[ \tau', e ] ~|~
  \kw{unpack}~e~\kw{as}~[ Y,x ]~ \kw{in}~e_2 \\
\end{array}
\]

\noindent Note that in Pierce book, 
``$\kw{pack}~_{\exists X.\tau}[ \tau', e ]$'' is
represented as ``$\{ \tau', e \} ~\kw{as}~ \{ \exists X, \tau \}$'' and
``$\kw{unpack}~e~\kw{as}~[ Y,x ]~\kw{in}~ e_2$''
is represented as ``$\kw{let}~ \{ Y,x \} = e ~\kw{in}~ e_2$''.


\subsection{Motivating example for typed closure conversion}
Consider the following program code example in C where
a function takes generic types as input.

\[
\kw{qsort}~ ( \mbox{T}~ a[~], ~\kw{order} ~\kw{compare} 
( ~\mbox{T}~x, ~\mbox{T}~ y ) ) 
\]

\noindent qsort takes an array of values of type T,
and a compare function on values of type T,
and it returns the ordered array of input values. 
The problem is that you may want to pass on additional
information that the compare function might consult.
For example, you might want the order to be forward or reverse order.

\noindent One way to bring this additional information or environment is to declare it
as a global variable.   However, declared as a global variable,
only one instance of an environment is available 
to several occurrences of qsorts.
And it may be dangerous in concurrent programming.

\noindent The better solution is to have a new data structure which
is a closure of the compare function and the environment it uses.

\begin{eqnarray*}
\begin{array}{ll}
\multicolumn{2}{l}
{\kw{qsort}~ ( ~\mbox{T}~ a[~], ~\kw{comparer}~ *C );} \\
\kw{struct}~ \kw{comparer}~ \{& \kw{order}~ \kw{compare}~ 
      ( ~\mbox{T}~ x, ~\mbox{T}~ y, ~\kw{Env}~ *env ); \\
   & \kw{Env}~ *env; \} \\ 
\end{array}
\end{eqnarray*}

\noindent The problem with this expression is in the type Env.
The qsort routine and struct comparer are provided by the 
implementer of the library.  But, it is the client who
defines what the environment is going to be, and thus,
its type Env.
To get around this difficulty, C programming language uses
``void *'' in place of Env.

\noindent We can use existential types to encode the type Env as 
a type variable X as below.
\begin{eqnarray*}
\begin{array}{ll}
\exists X.\kw{struct}~\kw{comparer}~ \{& 
\kw{order}~ (~\mbox{T}~ x, ~\mbox{T}~ y, ~\mbox{X}~ *env); \\
      & \mbox{X}~ *env;\} \\
\end{array}
\end{eqnarray*}

\noindent Type-safe version of C language called Cyclone is a variant of
C language that handles the above case. 
% device driver

\subsection{untyped closure conversion}
\noindent The comparer example indicates that we can build closure.
Here is the untyped closure conversion.
\begin{eqnarray*}
\begin{array}{lllll}
\SB{x} &=& \multicolumn{3}{l}{x} \\
\SB{\lam{x}{e}} &=& \multicolumn{2}{l}{( \lam{x \rho}{}
\kw{let} }
 & x_1 = \#1 \rho ~\kw{in} \\
    &&&     & ...  \\
    &&&     & x_n = \#n \rho ~\kw{in} \\
    &&&     & \SB{e}, \\
&& \multicolumn{3}{l}{(x_1, ..., x_n))} \\
&&&& (\kw{where}~ 
(x_1, ..., x_n) = ~\mbox{FV}~(e) - {x}) \\
\SB{e_1 e_2} &=& \kw{let} &
\multicolumn{2}{l}{c = \SB{e_1} ~\kw{in}} \\
&&& \multicolumn{2}{l}{(\#1 c) (\SB{e_2}, \#2 c)} \\
\end{array}
\end{eqnarray*}

\noindent $\rho$ in lambda abstraction translation is the environment that
grabs all free variables in the function body.

\noindent This is essentially what we have done in the lifted closure conversion
programming assignment in HW2.

\subsection{typed closure conversion}
\noindent In addition to building a closure, we also want to treat
the type of the environment in the closure as a type variable
using existential types.
We do this by typed closure conversion on typed lambda calculus.
The translation of typed language is on the type derivation, as usual.

\begin{eqnarray*}
\begin{array}{lllll}
\multicolumn{5}{l}
{\SB{ \Gamma, x:\tau \vdash x:\tau }} \\
~~~~~ &=& \multicolumn{3}{l}{x} \\
\multicolumn{5}{l}
{\SB{\Gamma \vdash \lam{x:\tau}{e}: \tau \rightarrow \tau\pr}} \\
 &=&
\kw{pack}~_{\exists X.(\SB{\tau}*X \rightarrow \SB{\tau\pr})*X} 
[&\multicolumn{2}{l}{\SB{\tau_1}*...*\SB{\tau_n},} \\
&&&(\lam{x:\SB{\tau},\rho:\SB{\tau_1}*...*\SB{\tau_n}}{\kw{let}}
& x_1 = \#1 \rho ~\kw{in} \\
&&&& ... \\
&&&& x_n = \#n \rho ~\kw{in} \\
&&&& \SB{\Gamma, x_1:\tau_1, ..., x_n:\tau_n \vdash e:\tau\pr}, \\
&&& \multicolumn{2}{l}{(x_1, ..., x_n) ] }\\
\multicolumn{5}{l}
{\SB{ \Gamma \vdash e_0 e_1 : \tau\pr }} \\
 &=&
\multicolumn{3}{l}
{\kw{let}~ c = 
   \SB{\Gamma \vdash e_0 : \tau \rightarrow \tau\pr} ~\kw{in}} \\
&& \multicolumn{3}{l}
{~~~~~~\kw{unpack}~c~\kw{as}~[ X', c']~\kw{in}
~(\#1 c') (\SB{\Gamma \vdash e_1:\tau}, \#2 c')} \\

\end{array}
\end{eqnarray*}

\noindent Note that there is another translation in type level.
The reason that type translation is required is illustrated
in the translation of lambda term.
In closure conversion, we have converted a function type
into a type for a closure, which is a pair of
a function that takes additional input for an environment,
and an environment.
\begin{eqnarray*}
\SB{\tau \rightarrow \tau\pr} = 
\exists X.(\SB{\tau}*X \rightarrow \SB{\tau\pr}) * X
\end{eqnarray*}

\noindent In the typed closure conversion,
lambda abstraction is translated into a closure pair
that hides the type for the environment as a type variable
by packing the closure into an existential type.
In application translation, the lambda abstraction
that is once packed by the lambda abstraction translation, is 
unpacked and the application is performed in the closure application style.
By unpacking $c$ of type 
$\exists X.(\SB{\tau}*X \rightarrow \SB{\tau\pr}) * X$  as 
$[X',c']$,
$c'$ has type
$(\SB{\tau}*X' \rightarrow \SB{\tau\pr}) * X'$.

\section{Module types}

Using some of the concepts we've developed so far, we can talk about
module types, which are like record types but allow data hiding.
Extend the grammar of the simply typed $\lambda$-calculus as such:

\[
\begin{array}{lll}
\tau & ::= & ...  \bnf \kw{sig}~\{ \kw{type}~T_1, ..., T_n;~
                                   \kw{val}~x_1:\tau_1, ..., x_m:\tau_m\} \\
e & ::= & ... \bnf \kw{struct}~\{\kw{type}~T_1=\tau_1, ..., T_n=\tau_n;~ 
                                 \kw{val}~x_1=e_1, ..., \kw{val}~x_m=e_m\} \\
\end{array}
\]

We interpret a \kw{struct} to have a meaning similar to:
\[
  \exists T_1~...~\exists T_n . \{ x_1:\tau_1, ..., x_n:\tau_n\} \\
\]

This lets the fields of the module type refer to a set of hidden types
that only they know about.  Any program making use of the data type
would only be able to access the data of hidden types indirectly.  To
see why this might be useful, consider a possible structure for
representing rational numbers where the type of the internal data
representation is hidden from client code:
\[
\begin{array}{l}
 \nm{Rat} =  \kw{struct}~\{                                       \\
 \begin{array}{lll}
        \quad    \kw{type}~T        &=& \kw{int} * \kw{int};      \\
        \quad    \kw{val}~\nm{zero} &=& (0, 1): T                 \\
        \quad    \kw{val}~\nm{add}  &=& \lam{x:T}{\lam{y:T}{...}} \\
 \end{array} \\
\}
\end{array}
\]

Ideally then we would want something like this to make sense:
\[
  \nm{Rat}.\nm{add}~(\nm{Rat}.\nm{zero}, \nm{Rat}.\nm{zero})
\]
Unfortunately, with our weak existential interpretation this doesn't work
out.  The problem is that this subexpression is not actually well-typed: 
\[
\begin{array}{l}
\kw{unpack}~\nm{Rat}~\kw{as}~[T, r]~\kw{in}~r.\nm{zero} 
\end{array}
\]
as it would be typed $T$, however the typing derivation enforces $T
\notin \Delta$.  More generally, this means that for computation to
act on two different rational values (each of type $T$) they must be
present in the same unpacking context.  This is because the dummy type
$T$ in $\kw{unpack}~e_1~\kw{as}~[T,r]~\kw{in}~e_2$ can only be
referred to during the evaluation of $e_2$ and cannot escape into the
broader typing context.


\section{Strong existentials}

To address these issues we introduce strong existential types,
beginning by extending the grammar of $\lambda^\arrow$ as such:
\[
\tau ::= ... \bnf \exists x.\tau \bnf e.T
\]

$T$ is a type variable as before, however $e.T$ has the novel feature
that its type depends on $e$, which is a term.  As such, we refer to 
it as a {\it dependent type}.  The new inference rules are:
\bigskip 

\begin{tabular}{c}
  \infer{\Delta; \Gamma \vdash e.T :: "type"}
      {\Delta; \Gamma \vdash e:\exists X.\tau \quad 
        \Delta, X::"type" \vdash \tau :: "type"}
\end{tabular}
\bigskip 
\begin{tabular}{c}
  \infer{\Delta; \Gamma\vdash\kw{unpack}~e_1~\kw{as}~
    [Y,x]~\kw{in}~e_2:\tau_2\{e_1.X/Y\}  }
      {\Delta; \Gamma \vdash e_1:\exists X.\tau \quad 
        \Delta, Y::"type", \Gamma, x:\tau\{Y/X\} \vdash e_2 : \tau_2 \quad
      Y \notin \Delta}
\end{tabular}
\bigskip

The inference rule for \kw{pack} has not changed.  One should note
that since $e_2 : \tau_2 \{e_1.X/Y\}$, the quantified type $X$ is
allowed to escape in a controlled manner.

\subsection{Problems}

Introducing dependent types is fraught with peril.  This is because we
expect that type checking can be performed statically, but this
generally cannot be the case with dependent types.  Specifically, we
expect that:
\bigskip 

\begin{tabular}{c}
  \infer{e_1.T \cong e_2.T}
        {\vdash e_1 = e_2}
\end{tabular}
\bigskip\\ However, for most languages of interest recognizing $e_1 =
e_2$ is undecidable. Instead language designers restrict the
expressions $e$ that can appear in $e.T$ to a strongly normalizing
subset of the language.  In ML for example we say that modules are
second class because $e$ is required to be a value.


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\end{document}
