packages feed

Agda-2.3.2.2: notes/talks/Modules/talk.tex

\documentclass{beamer}

\usetheme{JuanLesPins}

\usepackage{beamerthemesplit}
\usepackage{pxfonts}
\usepackage{proof}
\usepackage{graphicx}

\newenvironment{agda}{
\begin{block}{}\small
}{
\end{block}
}

\setlength\parskip{2mm}

\begin{document}

\title{A Module System for Agda}
\author{Ulf Norell}
\institute{Chalmers University of Technology}
\date{\today}

\frame{\titlepage}

\section{Introduction}


%- Purpose ----------------------------------------------------------------

\frame{
\frametitle{Purpose of this talk}

\begin{itemize}
    \item I (boldly) claim: ``You don't need a fancy module system''
    \item<2> ..and you tell me why I'm wrong.
\end{itemize}
}

%- Design -----------------------------------------------------------------

\frame{
\frametitle{Design of the module system}

\begin{itemize}
    \item Purpose
    \begin{itemize}
        \item handle the scope of names
    \end{itemize}
    \item Goals
    \begin{itemize}
        \item (reasonably) simple
        \item clear separation between scope checking and type checking
    \end{itemize}
    \item Consequences
    \begin{itemize}
        \item Modules don't have types,
        \item they're not higher order
        \item<2> and they don't have a categorical semantics.
    \end{itemize}
\end{itemize}
}

\begin{frame}
  \frametitle{Justification}

  Distinguish between modules and records.
  \begin{itemize}
    \item Modules structure names
    \item Records structure data
    \item Records are first class
    \item and should be used for things that the module system can't do.
    \item<2> ..unfortunately we don't have records yet.
  \end{itemize}
\end{frame}

\section{The Module System}

%- Simple example ---------------------------------------------------------

\begin{frame}[fragile]
\frametitle{A simple example}

A module contains a bunch of declarations

\begin{agda}
\begin{verbatim}
module A where
  id : (A : Set) -> A -> A
  id A x = x
\end{verbatim}
\end{agda}

Outside the module the contents can be accessed using qualified names

\begin{agda}
\begin{verbatim}
zero' = A.id Nat zero
\end{verbatim}
\end{agda}

Or we can {\em open} the module to bring the contents into scope

\begin{agda}
\begin{verbatim}
open A
zero' = id Nat zero
\end{verbatim}
\end{agda}

\end{frame}

%- Controlling imported names ---------------------------------------------

\begin{frame}[fragile]
\frametitle{Controlling what is imported}

When opening a module we can choose to only bring certain names into scope.

\begin{agda}
\begin{verbatim}
open Nat, using (Nat) -- only Nat
plus : Nat -> Nat -> Nat
plus = Nat.plus
\end{verbatim}
\end{agda}
\begin{agda}
\begin{verbatim}
open Nat, hiding (plus) -- everything but plus
\end{verbatim}
\end{agda}
\begin{agda}
\begin{verbatim}
-- everything, but rename zero and suc
open Nat, renaming (zero to z, suc to s)
_+_ : Nat -> Nat -> Nat
z   + m = m
s n + m = s (n + m)
\end{verbatim}
\end{agda}

\end{frame}

%- Controlling exports ----------------------------------------------------

\begin{frame}[fragile]
\frametitle{Controlling what is exported}
You can declare things {\em private}, meaning that they will not be
accessible outside the module (but they can still be computed with).

\begin{agda}
\begin{verbatim}
module Proof where
  private boringLemma : (A : Set) -> A
          boringLemma = ..
  mainTheorem : P == NP
  mainTheorem = boringLemma (P == NP)
\end{verbatim}
\end{agda}

\end{frame}

%- Abstract definitions ---------------------------------------------------

\begin{frame}[fragile]
  \frametitle{Abstract definitions}

  An {\em abstract} definition does not reduce outside the module.
\begin{agda}
\begin{verbatim}
module A where
  abstract z : Nat
           z = zero
  -- here z reduces to zero
  zIsZero : z == zero
  zIsZero = refl

-- but not here
zIsZero : A.z == zero
zIsZero = A.zIsZero {- we can't use refl -}
\end{verbatim}
\end{agda}

  Care has to be taken so that the definition of \verb!z! doesn't escape.

\end{frame}

%- Parameterised modules --------------------------------------------------

\begin{frame}[fragile]
  \frametitle{Parameterised modules}

  Modules can be parameterised (similar to sections in Coq)

\begin{agda}
\begin{verbatim}
module Sort (A : Set)(_<_ : A -> A -> Bool) where
  sort : List A -> List A
  sort xs = ..
\end{verbatim}
\end{agda}

  A parameterised module can be applied to create a new module

\begin{agda}
\begin{verbatim}
module SortNat = Sort Nat natLess
\end{verbatim}
\end{agda}

  Design decision: Is the following valid?

\begin{agda}
\begin{verbatim}
Sort.sort : (A : Set) -> (A -> A -> Bool) ->
            List A -> List A
\end{verbatim}
\end{agda}

\end{frame}

%- Separate compilation ---------------------------------------------------

\begin{frame}[fragile]
  \frametitle{Separate type checking}

  A program can be split over multiple files.
  \begin{itemize}
    \item Principle: keep the file system out of the source code
    \item Each file contains a single top level module whose name corresponds to
    the file name.
    \item Type checking a file produces an interface file, containing
    essentially a dump of the proof state.
    \item Saves a lot of re-type checking.
  \end{itemize}
\end{frame}

%- Overview ---------------------------------------------------------------

\begin{frame}[fragile]
  \frametitle{Overview of the syntax}

\begin{agda}
\begin{verbatim}
Decl ::= module M Tel where Decls
      |  module M Tel = M' Exprs [Modifiers]
      |  import M [ as M' ]      [Modifiers]
      |  open   M [, public ]    [Modifiers]
      |  private Decls
      |  abstract Decls
      |  ...
Modifier ::= , using    (x, ..)
          |  , hiding   (x, ..)
          |  , renaming (x to y, ..)
\end{verbatim}
\end{agda}
\end{frame}

\section{Implementation}

%- The goals --------------------------------------------------------------

\frame{
\frametitle{Revisiting the goals}

Our goals:

\begin{itemize}
  \item Simple
  \begin{itemize}
    \item We like to think it is.
  \end{itemize}
  \item<2> Clear separation between scope checking and type checking.
  \begin{itemize}
    \item No type checking during scope checking
    \item No scope checking during type checking
  \end{itemize}
\end{itemize}
}

%- No type checking during scope checking ---------------------------------

\begin{frame}[fragile]
  \frametitle{No type checking during scope checking}

  \begin{itemize}
    \item Modules cannot be passed around..
    \item ..and they don't have types..
    \item ..so we don't need type checking to figure out what names a particular
    module contains.
  \end{itemize}
\end{frame}

%- No scope checking during type checking ---------------------------------

\begin{frame}[fragile]
  \frametitle{No scope checking during type checking}

\begin{itemize}
  \item Remove the module system during scope checking.
  \begin{itemize}
    \item Modules are about managing names, so this should be possible.
    \item Except.. performing module instantiations at scope checking might
          generate a lot of extra work for the type checker.
  \end{itemize}
\end{itemize}
\end{frame}

%- Result of scope checking -----------------------------------------------

\begin{frame}[fragile]
  \frametitle{Result of scope checking}

The type checking will see:

\begin{agda}
\begin{verbatim}
Decl ::= section M Tel Decls
      |  apply M = M Exprs
      |  import M
      |  ..
\end{verbatim}
\end{agda}

\begin{itemize}
  \item Names are fully qualified
  \item Scope control has disappeared
\end{itemize}

\end{frame}

%- Scope checking ---------------------------------------------------------

\begin{frame}[fragile]
  \frametitle{Implementing the scope checker}
\begin{agda}
\begin{verbatim}
data Scope = Scope { name         :: Name
                   , publicNames  :: Names
                   , privateNames :: Names
                   }
type Names = Map ConcreteName QualifiedName
type State = Stack Scope
\end{verbatim}
\end{agda}
\begin{itemize}
  \item Entering a module:
  \begin{itemize}
    \item push an empty scope on the stack
    \item if parameterised, output a section
  \end{itemize}
  \item Exiting a module: pop a scope from the stack
  \begin{itemize}
    \item discard private names
    \item put public names in the current scope (but qualified)
  \end{itemize}
\end{itemize}

\end{frame}

\begin{frame}[fragile]
  \frametitle{Example}
\begin{agda}
\begin{verbatim}
module A where          Current stack
  f : T  <-- 
  module B0 where
    g : T
  module B where     
    private g : T       A - public : f -> A.f
    module C where                   
      h : T

\end{verbatim}
\end{agda}
\end{frame}

\begin{frame}[fragile]
  \frametitle{Example}
\begin{agda}
\begin{verbatim}
module A where          Current stack
  f : T
  module B0 where
    g : T  <--
  module B where        B0 - public: g  -> A.B0.g
    private g : T       A  - public: f  -> A.f
    module C where                   
      h : T

\end{verbatim}
\end{agda}
\end{frame}

\begin{frame}[fragile]
  \frametitle{Example}
\begin{agda}
\begin{verbatim}
module A where          Current stack
  f : T
  module B0 where
    g : T
  module B where        B - private: g    -> A.B.g
    private g : T <--   A - public : f    -> A.f
    module C where                   B0   -> A.B0
      h : T                          B0.g -> A.B0.g

\end{verbatim}
\end{agda}
\end{frame}

\begin{frame}[fragile]
  \frametitle{Example}
\begin{agda}
\begin{verbatim}
module A where          Current stack
  f : T
  module B0 where
    g : T               C - public : h    -> A.B.C.h
  module B where        B - private: g    -> A.B.g
    private g : T       A - public : f    -> A.f
    module C where                   B0   -> A.B0
      h : T <--                      B0.g -> A.B0.g

\end{verbatim}
\end{agda}
\end{frame}

\begin{frame}[fragile]
  \frametitle{Example}
\begin{agda}
\begin{verbatim}
module A where          Current stack
  f : T
  module B0 where
    g : T               B - public : C.h  -> A.B.C.h
  module B where            private: g    -> A.B.g
    private g : T       A - public : f    -> A.f
    module C where                   B0   -> A.B0
      h : T                          B0.g -> A.B0.g
    <--
\end{verbatim}
\end{agda}
\end{frame}

\begin{frame}[fragile]
  \frametitle{Example}
\begin{agda}
\begin{verbatim}
module A where          Current stack
  f : T
  module B0 where
    g : T
  module B where        A - public : f     -> A.f  
    private g : T                    B0    -> A.B0
    module C where                   B0.g  -> A.B0.g
      h : T                          B.C.h -> A.B.C.h
  <--
\end{verbatim}
\end{agda}
\end{frame}

\begin{frame}[fragile]
  \frametitle{Example}
Output from scope checking
\begin{agda}
\begin{verbatim}
A.f     : T
A.B0.g  : T
A.B.g   : T
A.B.C.h : T
\end{verbatim}
\end{agda}
\end{frame}

\begin{frame}[fragile]
  \frametitle{Other operations}

  \begin{itemize}
    \item {\tt open A}
    \begin{itemize}
      \item for each A.B.x $\to$ y add B.x $\to$ y to the top scope
      \item no output
    \end{itemize}
    \item {\tt module A $\Delta$ = B es}
    \begin{itemize}
      \item push a module A
      \item {\tt open B, public}
      \item pop A
      \item if $\Delta$ is non-empty, output \\
            {\tt section \_ $\Delta$ where apply A = B es}
    \end{itemize}
    \item {\tt using, hiding, renaming} just affects what is added to the scope
    \item name resolution - look up the concrete name (in any part of the stack)
  \end{itemize}
\end{frame}

%- Type checking ----------------------------------------------------------

\begin{frame}[fragile]
  \frametitle{Implementing the type checker}

  After type checking:
  \begin{itemize}
    \item All definitions are lambda lifted.
  \end{itemize}

  What does the type checker have to do?
  \begin{itemize}
    \item Collect paramers
    \item Lambda lift definitions (after type checking)
    \item Apply sections ({\tt apply A = B es})
    \begin{itemize}
      \item check that the arguments es match the parameters of B
      \item for each definition {\tt B.C.f} create a new definition \\
            {\tt A.C.f = B.C.f es}
    \end{itemize}
  \end{itemize}

\end{frame}

%- Design choices ---------------------------------------------------------

\section{Conclusions}

\begin{frame}[fragile]
  \frametitle{Conclusions and Future work}

  Future work
  \begin{itemize}
    \item Mutual recursion between modules
    \begin{itemize}
      \item same file: easy
      \item different files: requires more machinery (including syntax!)
    \end{itemize}
    \item Unifiying modules and local definitions
    \item Add records and {\bf try some real examples}
  \end{itemize}

  Conclusions
  \begin{itemize}
    \item Simple - yes!
    \item Sufficiently powerful
    \begin{itemize}
      \item<2> exercise for the audience
    \end{itemize}
  \end{itemize}
\end{frame}

\end{document}

% vim: et tw=80 sts=2 sw=2