% SETUP
%
% # font size (open large term)
% paste ~/work/talks/cppcon/2019/setup
%
% cat test-1.cxx
%
% time b
% b clean
% time b
%
% b clean
% b configure config.cxx.translatable_headers='<iostream>'
% time b
% b clean
% time b
%

\documentclass{beamer}
\usepackage{slides}
\usepackage{setspace}
\usepackage{placeins}  % \FloatBarrier

\usepackage{booktabs}
%\usepackage{tabularx}  % \extrarowheight

\usepackage{array}
%\usepackage{bigstrut}

\usepackage[thinlines]{easytable}

\usepackage{ulem}
\renewcommand<>{\sout}[1]{
  \renewcommand{\ULthickness}{.7pt}%
  \alt#2{\beameroriginal{\sout}{#1}}{#1}
}

% Title.
%
\title{Practical C++ Modules}
\author{Boris Kolpackov}
%\institute{https://build2.org}
\institute{\large \colorhref{build2.org}{https://build2.org}}
\date{v1.3, September 2019}

% Logo.
%
\pgfdeclareimage[height=0.7cm]{logo}{cs-logo}
\titlegraphic{
\begin{beamercolorbox}[sep=20pt,center]{black}
\pgfuseimage{logo}
\end{beamercolorbox}}

% Document.
%
\begin{document}

%
%
\begin{frame}
\titlepage
\end{frame}

%
%
\begin{frame}[fragile]
\begin{center}\alert{\Huge What \& Why}\end{center}
\end{frame}

%
%
\begin{frame}[fragile]
\frametitle{Headers and Textual Inclusion}
\begin{center}
\begin{tikzpicture}[
  node distance=8mm,
  code/.style={draw=green!50!black,
               solid,
               fill=green!50!black!20,
               minimum width=2cm,
               minimum height=.8cm},
  incl/.style={draw=green!50!black,
               dashed,
               fill=green!50!black!20,
               minimum width=2cm,
               minimum height=.8cm},
  arrow/.style={->,shorten >=1pt,>=stealth',thick},
  ]

  % SETUP
  %
  \fontsize{8pt}{9pt}\selectfont

  \tikzstyle{every node}=
  [
    inner sep=3pt,
    thick,
    anchor=north west
  ]

  \coordinate (DUMMY1) at (0,0);
  \coordinate (DUMMY2) at (9,6);
  \path (DUMMY1) (DUMMY2);

%  \filldraw (0, 0) circle (1pt);
%  \filldraw (9, 6) circle (4pt);

  % PICTURE
  %
  \node (HPP)  at (0.5, 5) [code,minimum width=2cm] {\texttt{hello.hpp}};
  \node (CPP)  at (0.5, 3) [code,minimum width=2cm] {\texttt{hello.cpp}};

\uncover<1-2>{
  \node (MAIN) at (5.5, 5) [code,minimum width=2cm] {\texttt{main.cpp}};
}

\uncover<2>{
  \path (MAIN.west) edge[arrow] node[above] {\begin{minipage}{2cm}\center{\texttt{\#include}}\end{minipage}} (HPP.east);
}

\uncover<3->{
  \node (IHPP) at (5.5, 5) [incl,minimum width=2cm] {\texttt{hello.hpp}};
  \node (MAIN) at (5.5, 4.2) [code,minimum width=2cm] {\texttt{main.cpp}};
  \path (IHPP.west) edge[arrow] node[above] {\begin{minipage}{2cm}\center{\texttt{\#include}}\end{minipage}} (HPP.east);
}

\end{tikzpicture}
\end{center}
\end{frame}


%
%
\begin{frame}[fragile]
\frametitle{Header Disadvantages}
\noindent
\begin{minipage}{.6\textwidth}
\vspace{1em}
\begin{itemize}
  \itemsep0.7em
  \item Compilation speed
  \item Header/Source split
  \item Lack of isolation
    \begin{itemize}
    \itemsep0.4em
    \item Our code can change headers
    \item Headers can change our code
    \item Headers can change each other
    \item Dependency on implementation
    \end{itemize}
  \item ODR violations
    \begin{itemize}
    \itemsep0.4em
    \item \emph{single definition}: non-inline
    \item \emph{identical definitions}: inline, types
    \end{itemize}
  \item Order dependency and cycles
  \item Interfacing with C++
  \end{itemize}
\end{minipage}%
\begin{minipage}{.4\textwidth}
  \begin{tikzpicture}[
  node distance=8mm,
  code/.style={draw=green!50!black,
               solid,
               fill=green!50!black!20,
               minimum width=2cm,
               minimum height=.8cm},
  incl/.style={draw=green!50!black,
               dashed,
               fill=green!50!black!20,
               minimum width=2cm,
               minimum height=.8cm},
  arrow/.style={->,shorten >=1pt,>=stealth',thick},
  ]

  % SETUP
  %
  \fontsize{8pt}{9pt}\selectfont

  \tikzstyle{every node}=
  [
    inner sep=3pt,
    thick,
    anchor=north west
  ]

  \coordinate (DUMMY1) at (0,0);
  \coordinate (DUMMY2) at (4,6);
  \path (DUMMY1) (DUMMY2);

  %\filldraw (0, 0) circle (1pt);
  %\filldraw (4, 6) circle (4pt);

  % PICTURE
  %
  \node (CPP1) at (0.5, 4.8) [code,minimum width=2cm, minimum height=0.5cm] {};
  \node (HHPP) at (0.5, 4.4) [incl,minimum width=2cm] {\texttt{hello.hpp}};
  \node (SHPP) at (0.5, 3.6) [incl,minimum width=2cm] {\texttt{spell.hpp}};
  \node (PHPP) at (0.5, 2.8) [incl,minimum width=2cm] {\texttt{print.hpp}};
  \node (CPP2) at (0.5, 2)   [code,minimum width=2cm] {\texttt{main.cpp}};

\uncover<2>{
  \path (CPP1.east) edge[arrow,bend left=60,out looseness=2.2,in looseness=2] (HHPP.east);
}

\uncover<3>{
  \path (PHPP.east) edge[arrow,bend left=60,out looseness=1.4,in looseness=1.3] (CPP2.east);
}

\uncover<4>{
  \path (HHPP.west) edge[arrow,bend right=60,out looseness=1.1,in looseness=1] (PHPP.west);
}

\uncover<5->{
  \path (CPP1.east) edge[arrow,bend left=60,out looseness=2.2,in looseness=2]   node[right] {\begin{minipage}{2cm}\texttt{NDEBUG}\end{minipage}} (HHPP.east);
  \path (PHPP.east) edge[arrow,bend left=60,out looseness=1.4,in looseness=1.3] node[right] {\begin{minipage}{2cm}\texttt{assert}\end{minipage}} (CPP2.east);
}
\end{tikzpicture}
\end{minipage}
\end{frame}

\begin{frame}[fragile]
\frametitle{Header Advantages}
\begin{itemize}
  \itemsep0.7em
  \item Embarrassingly Parallel
  \item Familiar
  \item Flexible \& Hackable
  \item Toolable (to a degree)
  \end{itemize}
\end{frame}

%
%
\begin{frame}[fragile]
\frametitle{From Headers to Modules}
\begin{center}
\begin{tikzpicture}[
  node distance=8mm,
  code/.style={draw=green!50!black,
               solid,
               fill=green!50!black!20,
               minimum width=2cm,
               minimum height=.8cm},
  incl/.style={draw=green!50!black,
               dashed,
               fill=green!50!black!20,
               minimum width=2cm,
               minimum height=.8cm},
  kill/.style={draw=red!90!black},
  arrow/.style={->,shorten >=1pt,>=stealth',thick},
  ]

  % SETUP
  %
  \fontsize{8pt}{9pt}\selectfont

  \tikzstyle{every node}=
  [
    inner sep=3pt,
    thick,
    anchor=north west
  ]

  \coordinate (DUMMY1) at (0,0);
  \coordinate (DUMMY2) at (9,3.7);
  \path (DUMMY1) (DUMMY2);

%  \filldraw (0, 0) circle (1pt);
%  \filldraw (9, 3.7) circle (4pt);

  % PICTURE
  %
  \node (MAIN) at (5.5, 3.2) [code,minimum width=2cm] {\texttt{main.cpp}};
\uncover<1-2>{
  \node (CPP)  at (0.5, 2) [code,minimum width=2cm] {\texttt{hello.cpp}};
}

\uncover<1>{
  \node (HPP)  at (0.5, 4) [code,kill,minimum width=2cm] {\texttt{hello.hpp}};
  \node (IHPP) at (5.5, 4) [incl,kill,minimum width=2cm] {\texttt{hello.hpp}};
  \path (IHPP.west) edge[arrow,kill] node[above] {\begin{minipage}{2cm}\center{\texttt{\#include}}\end{minipage}} (HPP.east);
}

\uncover<2>{
  \path (MAIN.west) edge[arrow] (CPP.east);
}

\uncover<3->{
  \node (CPP)  at (0.5, 2) [code,minimum width=2cm] {\texttt{hello\textbf{.mpp}}};
  \path (MAIN.west) edge[arrow] node[above] {\begin{minipage}{1.4cm}\texttt{import}\end{minipage}} (CPP.east);
}
\end{tikzpicture}
\end{center}
\uncover<2->{
  \begin{center}\alert{\Large Module Importation}\end{center}
}
\end{frame}


%
%
\begin{frame}[fragile]
\frametitle{From Header Include to Import}
\begin{center}
\begin{tikzpicture}[
  node distance=8mm,
  code/.style={draw=green!50!black,
               solid,
               fill=green!50!black!20,
               minimum width=2cm,
               minimum height=.8cm},
  incl/.style={draw=green!50!black,
               dashed,
               fill=green!50!black!20,
               minimum width=2cm,
               minimum height=.8cm},
  kill/.style={draw=red!90!black},
  arrow/.style={->,shorten >=1pt,>=stealth',thick},
  ]

  % SETUP
  %
  \fontsize{8pt}{9pt}\selectfont

  \tikzstyle{every node}=
  [
    inner sep=3pt,
    thick,
    anchor=north west
  ]

  \coordinate (DUMMY1) at (0,0);
  \coordinate (DUMMY2) at (9,3.7);
  \path (DUMMY1) (DUMMY2);

%  \filldraw (0, 0) circle (1pt);
%  \filldraw (9, 3.7) circle (4pt);

  % PICTURE
  %
  \node (MAIN) at (5.5, 3.2) [code,minimum width=2cm] {\texttt{main.cpp}};
  \node (HPP)  at (0.5, 4) [code,minimum width=2cm] {\texttt{hello.hpp}};
  \node (CPP)  at (0.5, 2) [code,minimum width=2cm] {\texttt{hello.cpp}};

\uncover<1>{
  \node (IHPP) at (5.5, 4) [incl,kill,minimum width=2cm] {\texttt{hello.hpp}};
  \path (IHPP.west) edge[arrow,kill] node[above] {\begin{minipage}{2cm}\center{\texttt{\#include}}\end{minipage}} (HPP.east);
}

\uncover<2->{
  \path (MAIN.west) edge[arrow] node[above] {\begin{minipage}{2cm}\center{\texttt{import}}\end{minipage}} (HPP.east);
}

\end{tikzpicture}
\end{center}
\uncover<3->{
  \begin{center}\alert{\Large Header Importation}\end{center}
}
\end{frame}


%
%
\begin{frame}[fragile]
\frametitle{From Header Include to Auto-Import}
\begin{center}
\begin{tikzpicture}[
  node distance=8mm,
  code/.style={draw=green!50!black,
               solid,
               fill=green!50!black!20,
               minimum width=2cm,
               minimum height=.8cm},
  incl/.style={draw=green!50!black,
               dashed,
               fill=green!50!black!20,
               minimum width=2cm,
               minimum height=.8cm},
  kill/.style={draw=red!90!black},
  arrow/.style={->,shorten >=1pt,>=stealth',thick},
  ]

  % SETUP
  %
  \fontsize{8pt}{9pt}\selectfont

  \tikzstyle{every node}=
  [
    inner sep=3pt,
    thick,
    anchor=north west
  ]

  \coordinate (DUMMY1) at (0,0);
  \coordinate (DUMMY2) at (9,3.7);
  \path (DUMMY1) (DUMMY2);

%  \filldraw (0, 0) circle (1pt);
%  \filldraw (9, 3.7) circle (4pt);

  % PICTURE
  %
  \node (MAIN) at (5.5, 3.2) [code,minimum width=2cm] {\texttt{main.cpp}};
  \node (HPP)  at (0.5, 4) [code,minimum width=2cm] {\texttt{hello.hpp}};
  \node (CPP)  at (0.5, 2) [code,minimum width=2cm] {\texttt{hello.cpp}};

\uncover<1>{
  \node (IHPP) at (5.5, 4) [incl,kill,minimum width=2cm] {\texttt{hello.hpp}};
  \path (IHPP.west) edge[arrow,kill] node[above] {\begin{minipage}{2cm}\center{\texttt{\#include}}\end{minipage}} (HPP.east);
}

\uncover<2->{
  \path (MAIN.west) edge[arrow]
  node[above] {\begin{minipage}{.7cm}\texttt{\#include}\end{minipage}}
  node[below] {\begin{minipage}{1.7cm}\texttt{(import)}\end{minipage}}
  (HPP.east);
}

\end{tikzpicture}
\end{center}
\uncover<2->{
  \begin{center}\alert{\Large Include Translation}\end{center}
}
\end{frame}


%
%
\begin{frame}[fragile]
\frametitle{Modularization Options}
{\large
\begin{itemize}
  \itemsep0.7em
  \item Module importation
  \item Header importation
  \item Include translation (to Header importation)
  \end{itemize}}
\end{frame}


%
%
\begin{frame}[fragile]
\frametitle{Modules Build Mechanics}
\begin{center}
\begin{tikzpicture}[
  node distance=8mm,
  code/.style={draw=green!50!black,
               solid,
               fill=green!50!black!20,
               minimum width=2cm,
               minimum height=.8cm},
  bmi/.style={draw=blue!50!black,
              fill=blue!50!black!20,
              minimum width=2cm,
              minimum height=.8cm},
  arrow/.style={->,shorten >=1pt,>=stealth',thick},
  ]

  % SETUP
  %
  \fontsize{8pt}{9pt}\selectfont

  \tikzstyle{every node}=
  [
    inner sep=3pt,
    thick,
    anchor=north west
  ]

  \coordinate (DUMMY1) at (0,0);
  \coordinate (DUMMY2) at (9,3.7);
  \path (DUMMY1) (DUMMY2);

%  \filldraw (0, 0) circle (1pt);
%  \filldraw (9, 3.7) circle (4pt);

  % PICTURE
  %
  \node (MAIN) at (5.5, 4) [code,minimum width=2cm] {\texttt{main.cpp}};
  \node (MPP)  at (0.5, 4) [code,minimum width=2cm] {\texttt{hello.mpp}};

\uncover<1>{
  \path (MAIN.west) edge[arrow] node[above] {\begin{minipage}{2cm}\center{\texttt{import}}\end{minipage}} (MPP.east);
}

\uncover<2->{
  \node (BMI)  at (0.5, 2.5) [bmi,minimum width=2cm] {\texttt{hello\textbf{.bmi}}};
  \path (MPP.south) edge[arrow] node[left] {\begin{minipage}{1.2cm}\texttt{compile}\end{minipage}} (BMI.north);
  \path (MAIN.west) edge[arrow,dashed] node[above] {\begin{minipage}{2cm}\texttt{import}\end{minipage}} (BMI.east);
}

\uncover<2->{
  \node (UTIL) at (5.5, 1) [code,minimum width=2cm] {\texttt{util.cpp}};
  \path (UTIL.west) edge[arrow,dashed] node[below] {\begin{minipage}{2cm}\texttt{import}\end{minipage}} (BMI.east);
}

\end{tikzpicture}
\end{center}
\smallskip
\uncover<2->{
  \begin{center}\alert{\Large Binary Module Interface (BMI)}\end{center}
}
\end{frame}

%
%
\begin{frame}[fragile]
\frametitle{Modularization Options}
{\large
\begin{itemize}
  \itemsep0.7em
  \item Include translation (to Header importation)
  \item Header importation
  \item Module importation
  \end{itemize}}
\end{frame}

%
%
\begin{frame}[fragile]
\frametitle{Include Translation}
{\large
\begin{itemize}
  \itemsep0.7em
  \item No modification required on either side
  \item But header should be \emph{importable}
  \item All C++20 \texttt{std} headers are importable...
  \item ... (except for \texttt{<c*>} C wrapper headers)
  \end{itemize}}
\end{frame}

%
%
\begin{frame}[fragile]
\frametitle{Include Translation}
\begin{center}{\LARGE How does it actually work?}\end{center}
\end{frame}

%
%
\begin{frame}[fragile]
\frametitle{Importable Headers}
\begin{itemize}
  \itemsep0.7em
  \item Modular in the broader sense:
  \smallskip
  \begin{itemize}
    \itemsep0.5em
    \item Does not rely on pre-definitions (macros, declarations)
    \item Or post-undefinitions (macros)
  \end{itemize}
  \item Example: header that requires pre-inclusion of another header
  \item Example: header that implements X-macro technique
  \item Internal linkage is Ok as long as not used outside header
  \item Example: Schwartz counter
  \end{itemize}
\end{frame}

%
%
\begin{frame}[fragile]
\frametitle{Include Translation: Problems Solved}
\vspace{.7em}
\begin{itemize}
  \itemsep0.7em
  \item \sout<2->{Compilation speed}
  \item Header/Source split
  \item Lack of isolation
    \begin{itemize}
    \itemsep0.4em
    \item \sout<3->{Our code can change headers} \only<3->{(if translated)}
    \item Headers can change our code
    \item \sout<3->{Headers can change each other} \only<3->{(if translated)}
    \item Dependency on implementation
    \end{itemize}
  \item \sout<4->{ODR violations} \only<4->{(if translated)}
    \begin{itemize}
    \itemsep0.4em
    \item \emph{single definition}: non-inline
    \item \sout<4->{\emph{identical definitions}: inline, types}
    \end{itemize}
  \item \sout<5->{Order dependency}\only<5->{ (if translated)} and cycles
  \item \sout<6->{Interfacing with C++ \only<6->{and C!}}
  \end{itemize}
\end{frame}


%
%
\begin{frame}[fragile]
\frametitle{Header Importation}
\begin{minipage}{.47\textwidth}
\begin{codebox}[main.cpp]
\begin{smallhlcode}{c++}
{
  \hcline<2->{1}
}
{}
#include "hello.hpp"

int main ()
{
  // ...
}
\end{smallhlcode}
\end{codebox}
\end{minipage}%
\hspace{.06\textwidth}%
\begin{minipage}{.47\textwidth}
\begin{codebox}[main.cpp]
\begin{smallhlcode}{c++}
{
  \hcline<2->{1}
}
{}
import "hello.hpp";

int main ()
{
  // ...
}
\end{smallhlcode}
\end{codebox}
\end{minipage}
\end{frame}

%
%
\begin{frame}[fragile]
\frametitle{Header Importation}
{\large
\begin{itemize}
  \itemsep0.7em
  \item Only consumer modifications required
  \item Header should be importable
  \item Remaining \texttt{\#include}s are Ok...
  \item ...But not automatically translated
  \end{itemize}}
\end{frame}

%
%
\begin{frame}[fragile]
\frametitle{Header Importation: Problems Solved}
\vspace{.7em}
\begin{itemize}
  \itemsep0.7em
  \item \sout<2->{Compilation speed}
  \item Header/Source split
  \item Lack of isolation
    \begin{itemize}
    \itemsep0.4em
    \item \sout<2->{Our code can change headers(if translated)}
    \item Headers can change our code
    \item \sout<2->{Headers can change each other (if translated)}
    \item Dependency on implementation
    \end{itemize}
  \item \sout<2->{ODR violations}
    \begin{itemize}
    \itemsep0.4em
    \item \emph{single definition}: non-inline
    \item \sout<2->{\emph{identical definitions}: inline, types}
    \end{itemize}
  \item \sout<2->{Order dependency (if translated)} and cycles
  \item \sout<2->{Interfacing with C++ and C!}
  \end{itemize}
\end{frame}


%
%
\begin{frame}[fragile]
\frametitle{Module Importation}
\begin{minipage}{.42\textwidth}
\vspace{.3em}
\begin{tightcodebox}[hello.hpp]
\begin{smallhlcode}{c++}
{
  \hcline<2>{1,...,5}
  \hcline<4>{2}
  \hcline<5>{1}
}
{}
#pragma once
#include <string>
namespace hello {
  void say (std::string);
}
\end{smallhlcode}
\end{tightcodebox}
\vspace{.5em}
\begin{tightcodebox}[hello.cpp]
\begin{smallhlcode}{c++}
{
  \hcline<2>{1,...,6}
  \hcline<4>{2}
  \hcline<5>{1}
  \hcline<6>{4}
}
{}
#include "hello.hpp"
#include <iostream>
namespace hello {
  void say (std::string) {
    ... }
}
\end{smallhlcode}
\end{tightcodebox}
\begin{tightcodebox}[main.cpp]
\begin{smallhlcode}{c++}
{
  \hcline<7>{1}
}
{}
#include "hello.hpp"
int main () {
  hello::say ("World");
}
\end{smallhlcode}
\end{tightcodebox}
\end{minipage}%
\hspace{.06\textwidth}%
\begin{minipage}{.52\textwidth}
\vspace{.3em}
\begin{tightcodebox}[hello.mpp]
\begin{smallhlcode}{c++}
{
  \hcline<2>{1,...,14}
  \hcline<3>{1}
  \hcline<4>{2, 10}
  \hcline<6>{12}
}
{}
export module hello;
import <string>;







import <iostream>;
namespace hello {
  export void say (std::string) {
    ... }
}
\end{smallhlcode}
\end{tightcodebox}
\begin{tightcodebox}[main.cpp]
\begin{smallhlcode}{c++}
{
  \hcline<7>{1}
  \hcline<8>{3}
}
{}
import hello;
int main () {
  hello::say ("World");
}
\end{smallhlcode}
\end{tightcodebox}
\end{minipage}
\end{frame}

%
%
\begin{frame}[fragile]
\frametitle{Module Importation: Problems Solved}
\vspace{.7em}
\begin{itemize}
  \itemsep0.7em
  \item \sout<2->{Compilation speed}
  \item \sout<3->{Header/Source split}
  \item \sout<4->{Lack of isolation}
    \begin{itemize}
    \itemsep0.4em
    \item \sout<4->{Our code can change modules}
    \item \sout<4->{Modules can change our code}
    \item \sout<4->{Modules can change each other}
    \item \sout<4->{Dependency on implementation}
    \end{itemize}
  \item \sout<5->{ODR violations}
    \begin{itemize}
    \itemsep0.4em
    \item \sout<5->{\emph{single definition}: non-inline}
    \item \sout<5->{\emph{identical definitions}: inline, types}
    \end{itemize}
  \item \sout<6->{Order dependency and cycles}
  \item \sout<7->{Interfacing with C++}
  \end{itemize}
\end{frame}

%
%
\begin{frame}[fragile]
\begin{center}\alert{\Huge How}\end{center}
\end{frame}

%
%
\begin{frame}[fragile]
\frametitle{Module Structure}
\begin{minipage}{.42\textwidth}
\vspace{1.5em}
\begin{codebox}[hello.mpp]
\begin{smallhlcode}{c++}
{
  \hcline<3>{1}
  \hcline<4>{2,3,4,5}
  \hcline<5>{7,8,9,10}
  \hcline<6>{11,...,15}
}
{
  \lcline<1>{1,3}
}
module;

#include <cassert>


export module hello;

import <string>;
import <iostream>;

export namespace hello {
  void say (std::string) {
    ...
  }
}
\end{smallhlcode}
\end{codebox}
\end{minipage}%
\hspace{.06\textwidth}%
\begin{minipage}{.52\textwidth}
\begin{onlyenv}<1-2>
\vspace{19.7em}
\end{onlyenv}
\begin{onlyenv}<3->
\begin{tikzpicture}[
  node distance=8mm,
  code/.style={draw=green!50!black,
               solid,
               fill=green!50!black!20,
               minimum width=2cm,
               minimum height=.8cm},
  dash/.style={draw=green!50!black,
               dashed,
               fill=green!40!black!15,
               minimum width=2cm,
               minimum height=.8cm},
  arrow/.style={->,shorten >=1pt,>=stealth',thick},
  ]

  % SETUP
  %
  \fontsize{8pt}{9pt}\selectfont

  \tikzstyle{every node}=
  [
    inner sep=3pt,
    thick,
    anchor=north west
  ]

  \coordinate (DUMMY1) at (0,0);
  \coordinate (DUMMY2) at (6,5.975);
  \path (DUMMY1) (DUMMY2);

  %\filldraw (0, 0) circle (1pt);
  %\filldraw (6, 4.5) circle (4pt);

  % PICTURE
  %
  \node (MOD) at (1.0,  4.5) [code,minimum width=3.9cm,minimum height=5.7cm] {};

  \node       at (1.05, 4.4) {\footnotesize\texttt{\textbf{module};}};

  \node (GLB) at (1.0,  3.95)  [dash,minimum width=3.9cm,minimum height=1.3cm] {};
  \node       at (1.0,  3.7)  [minimum width=3.9cm] {global module fragment};
  \node       at (1.0,  3.3)  [minimum width=3.9cm] {\tiny (preprocessor directives only)};

  \node       at (1.05, 2.625) {\footnotesize\texttt{\textbf{export module} \textit{name};}};

  \node (PRM) at (1.0, 2.15)   [dash,minimum width=3.9cm,minimum height=1.35cm] {};
  \node       at (1.0, 1.9)    [minimum width=3.9cm] {module preamble};
  \node       at (1.0, 1.5)    [minimum width=3.9cm] {\tiny (import declarations only)};

  \node       at (1.0, 0.4)   [minimum width=3.9cm] {module purview};
  \node       at (1.0, 0.0)   [minimum width=3.9cm] {\tiny (exported declarations, etc)};

  % Redraw frame.
  %
  \node at (1.0,  4.5) [draw=green!50!black,minimum width=3.9cm,minimum height=5.7cm] {};

\end{tikzpicture}
\end{onlyenv}
\end{minipage}
\end{frame}


%
%
\begin{frame}[fragile]
\frametitle{Module Structure}
\smallskip
\begin{center}{\Large What's wrong with this?}\end{center}
\smallskip
\begin{codebox}[hello.mpp]
\begin{smallhlcode}{c++}
{}{}

export module hello;

#include <string>

...
\end{smallhlcode}
\end{codebox}
\bigskip
\pause
\begin{center}\alert{\Large Including headers in module purview is a bad idea}\end{center}
\smallskip
\begin{center}{\large (Unless modularizing that header)}\end{center}
\end{frame}


%
%
\begin{frame}[fragile]
\frametitle{Module Interface and Implementation}
\begin{minipage}{.47\textwidth}
\vspace{.3em}
\begin{codebox}[hello.mpp]
\begin{smallhlcode}{c++}
{
  \hcline<2>{3,8,12}
}
{}
module;

#include <cassert>

export module hello;

import <string>;
import <iostream>;

export namespace hello {
  void say (std::string) {
    ... }
}
\end{smallhlcode}
\end{codebox}
\vspace{5.72em}
\end{minipage}%
\hspace{.06\textwidth}%
\begin{minipage}{.47\textwidth}
\vspace{.3em}
\begin{onlyenv}<3->
\begin{codebox}[hello.mpp]
\begin{smallhlcode}{c++}
{
  \hcline<4>{1,...,6}
  \hcline<5>{1}
}
{
  \lcline<1,2>{1,...,6}
}
export module hello;
import <string>;

export namespace hello {
  void say (std::string);
}
\end{smallhlcode}
\end{codebox}
\begin{codebox}[hello.cpp]
\begin{smallhlcode}{c++}
{
  \hcline<5>{4}
}
{
  \lcline<1,2>{1,...,10}
}
module;
#include <cassert>

module hello;
import <iostream>;

namespace hello {
  void say (std::string) {
    ... }
}
\end{smallhlcode}
\end{codebox}
\end{onlyenv}
\end{minipage}
\end{frame}

%
%
\begin{frame}[fragile]
\frametitle{Module Interface and Implementation}
\begin{itemize}
  \itemsep0.7em
  \item Interface can (still) define non-inline functions/variables
  \item We can have multiple implementation units...
  \item ...But only one (primary) interface unit
  \item Interface partitions: split interface
  \item Implementation partitions: ``module-private interface''
\end{itemize}
\end{frame}

%
%
%\begin{frame}[fragile]
%\frametitle{To Split or Not to Split}
%\begin{itemize}
%  \itemsep0.7em
%  \item \emph{Module interface-only} libraries?
%  \item What happens to \texttt{include/} and \texttt{src/} split?
%  \item ???
%\end{itemize}
%\end{frame}

%
%
\begin{frame}[fragile]
\frametitle{To Split or Not to Split}
\smallskip
\alert{\large Pros:}
\smallskip
\begin{itemize}
  \itemsep0.5em
  \item DRY
  \item \emph{Module interface-only} libraries
\end{itemize}
\bigskip
\alert{\large Cons:}
\smallskip
\begin{itemize}
  \itemsep0.5em
  \item Unnecessary recompilation
  \item Reduced interface readability
  \item Extra dependencies (implementation imports)
  \item Reduced interface compilation speed
\end{itemize}
\bigskip
\begin{center}\alert{\Large Judgment Call}\end{center}
\end{frame}

%
%
\begin{frame}[fragile]
\frametitle{Physical Design Mechanisms}
\begin{center}
\begin{tikzpicture}[
  node distance=8mm,
  code/.style={draw=green!50!black,
               solid,
               fill=green!50!black!20,
               minimum width=2cm,
               minimum height=.8cm},
  arrow/.style={->,shorten >=1pt,>=stealth',thick},
  ]

  % SETUP
  %
  \fontsize{8pt}{9pt}\selectfont

  \tikzstyle{every node}=
  [
    inner sep=3pt,
    thick,
    anchor=north west
  ]

  \coordinate (DUMMY1) at (0,0);
  \coordinate (DUMMY2) at (9,6.5);
  \path (DUMMY1) (DUMMY2);

%  \filldraw (0, 0) circle (1pt);
%  \filldraw (9, 6) circle (4pt);

  % PICTURE
  %
  \node (PKG) at (3.5,  6.0) [code,minimum width=2cm,minimum height=0.75cm] {\texttt{package}};

  \node (LIB) at (3.5,  4.5) [code,minimum width=2cm,minimum height=0.75cm] {\texttt{library}};
  %\path (PKG.south) edge[arrow] (LIB.north);


  \node (MOD) at (2.4,  3.0) [code,minimum width=2cm,minimum height=0.75cm] {\texttt{module}};
  \node (HDR) at (4.6,  3.0) [code,minimum width=2cm,minimum height=0.75cm] {\texttt{header}};

  \node (NSP) at (3.5,  1.5) [code,minimum width=2cm,minimum height=0.75cm] {\texttt{namespace}};

  \node (NAM) at (3.5,  0.0) [code,minimum width=2cm,minimum height=0.75cm] {};
  \node (NAM) at (3.5,  -0.1) [minimum width=2cm] {\texttt{name}};
  \node       at (3.5,  -0.35) [minimum width=2cm] {\tiny (function, class)};

\end{tikzpicture}
\end{center}
\end{frame}

%
%
\begin{frame}[fragile]
\frametitle{Module Granularity}
\begin{center}
\begin{tikzpicture}[
  node distance=8mm,
  code/.style={draw=green!50!black,
               solid,
               fill=green!50!black!20,
               minimum width=2cm,
               minimum height=.8cm},
  arrow/.style={->,shorten >=1pt,>=stealth',thick},
  ]

  % SETUP
  %
  \fontsize{8pt}{9pt}\selectfont

  \tikzstyle{every node}=
  [
    inner sep=3pt,
    thick,
    anchor=north west
  ]

  \coordinate (DUMMY1) at (0,0);
  \coordinate (DUMMY2) at (9,5);
  \path (DUMMY1) (DUMMY2);

%  \filldraw (0, 0) circle (1pt);
%  \filldraw (9, 6) circle (4pt);

  % PICTURE
  %

  \node (LIB) at (3.5,  4.5) [code,minimum width=2cm,minimum height=0.75cm] {\texttt{library}};

  \node (HDR) at (3.5,  3.0) [code,minimum width=2cm,minimum height=0.75cm] {\texttt{header}};

  \node (NAM) at (3.5,  1.5) [code,minimum width=2cm,minimum height=0.75cm] {};
  \node (NAM) at (3.5,  1.4) [minimum width=2cm] {\texttt{name}};
  \node       at (3.5,  1.15) [minimum width=2cm] {\tiny (function, class)};

  \path (1.5, 3.0) edge[arrow] (1.5, 0.75);

  \path (1.5, 1.5) edge[arrow] (1.5, 4.5);

\end{tikzpicture}
\end{center}
\begin{center}{\Large Cost of importing modules is negligible}\end{center}
\end{frame}

%
%
\begin{frame}[fragile]
\frametitle{Module Granularity}
\alert{\large Too big:}
\smallskip
\begin{itemize}
  \itemsep0.7em
  \item Unnecessary recompilations
  \item Hard to navigate
\end{itemize}
\bigskip
\alert{\large Too small:}
\smallskip
\begin{itemize}
  \itemsep0.7em
  \item Tedious to import
  \item Also hard to navigate
\end{itemize}
\end{frame}

%
%
\begin{frame}[fragile]
\frametitle{Module Granularity}
\begin{center}\alert{\Large Combine related and commonly-used entities}\end{center}
\begin{center}{\Large (generally good design)}\end{center}
\smallskip
\pause
\begin{center}\alert{\Large Use re-export to create ``aggregate modules''}\end{center}
\bigskip
\begin{codebox}[hello.mpp]
\begin{smallhlcode}{c++}
{}{}
export module hello;

export import hello.format;
export import hello.print;
\end{smallhlcode}
\end{codebox}
\end{frame}

%
%
\begin{frame}[fragile]
\frametitle{Module Name}
\begin{codebox}[]
\begin{smallhlcode}{c++}
{} {}
export module hello;

export module hello.format;
export module hello.print;

export module hello.print.iostream;
\end{smallhlcode}
\end{codebox}
\bigskip
\begin{itemize}
  \itemsep0.7em
  \item Sequence of dot-separated identifiers
  \item On a separate ``name plane''
  \item Do not collide with namespace/type/function names
  \item No specified hierarchical semantics (yet)
\end{itemize}
\end{frame}

%
%
\begin{frame}[fragile]
\frametitle{Naming Modules}
\begin{center}
\begin{tikzpicture}[
  node distance=8mm,
  code/.style={draw=green!50!black,
               solid,
               fill=green!50!black!20,
               minimum width=2cm,
               minimum height=.8cm},
  arrow/.style={->,shorten >=1pt,>=stealth',thick},
  ]

  % SETUP
  %
  \fontsize{8pt}{9pt}\selectfont

  \tikzstyle{every node}=
  [
    inner sep=3pt,
    thick,
    anchor=north west
  ]

  \coordinate (DUMMY1) at (0,0);
  \coordinate (DUMMY2) at (9,6.5);
  \path (DUMMY1) (DUMMY2);

%  \filldraw (0, 0) circle (1pt);
%  \filldraw (9, 6) circle (4pt);

  % PICTURE
  %
  \node (PKG) at (3.5,  6.0) [code,minimum width=2cm,minimum height=0.75cm] {\texttt{package}};

  \node       at (0.55, 6.0) [minimum height=0.75cm] {\footnotesize\texttt{libhello}};
  \node       at (6.85, 6.0) [minimum height=0.75cm] {\footnotesize\texttt{hello}};

  \node (LIB) at (2.4,  4.5) [code,minimum width=2cm,minimum height=0.75cm] {\texttt{library}};
  \node (EXE) at (4.6,  4.5) [code,minimum width=2cm,minimum height=0.75cm] {\texttt{executable}};

  \node       at (0.55, 4.5) [minimum height=0.75cm] {\footnotesize\texttt{libhello}};
  \node       at (6.85, 4.5) [minimum height=0.75cm] {\footnotesize\texttt{hello}};

  \node (MOD) at (3.5,  3.0) [code,minimum width=2cm,minimum height=0.75cm] {\texttt{module}};

  \node       at (0.55, 3.0) [minimum height=0.75cm] {\footnotesize\textbf{\texttt{hello.print}}};
  \node       at (6.85, 3.0) [minimum height=0.75cm] {\footnotesize\textbf{\texttt{print}}};

  \node (NSP) at (3.5,  1.5) [code,minimum width=2cm,minimum height=0.75cm] {\texttt{namespace}};

  \node       at (0.55, 1.5) [minimum height=0.75cm] {\footnotesize\texttt{hello}};
  \node       at (6.85, 1.5) [minimum height=0.75cm] {\footnotesize\texttt{<none>}};

  \path (0.25, 0.75) edge[arrow] (0.25, 6);
  \path (8.45, 0.75) edge[arrow] (8.45, 6);

\end{tikzpicture}
\end{center}
\end{frame}

%
%
\begin{frame}[fragile]
\frametitle{Naming Modules}
{\large
\begin{itemize}
  \itemsep0.7em
  \item Start with the library/project top namespace (if any)
  \item Finish with a name describing the module's functionality
  \item If for a single/primary entity (class, etc), use its name
  \item Provide ``aggregate modules'' for hierarchy
\end{itemize}}
\end{frame}

%
%
\begin{frame}[fragile]
\frametitle{Module Naming Examples}
\begin{itemize}
  \itemsep0.4em
  \item Library name: \verb|libbutl|
  \item Library namespace: \verb|butl|
  \item Library modules:
\end{itemize}
\begin{code}{c++}
    butl.base64                butl.path
    butl.char_scanner          butl.path_io
    butl.const_ptr             butl.path_map
    butl.diagnostics           butl.process
    butl.fdstream              butl.sha256
    butl.filesystem            butl.small_vector
    butl.manifest_parser       butl.string_parser
    butl.manifest_serializer   butl.string_table
    butl.multi_index           butl.target_triplet
    butl.openssl               butl.timestamp
    butl.pager                 butl.vector_view
\end{code}
\end{frame}

%
%
\begin{frame}[fragile]
\frametitle{Naming Module Files}
{\large
\begin{itemize}
  \itemsep0.7em
  \item No mapping between module names and file names
  \item But clearly makes sense for them to be related
\end{itemize}}
\end{frame}

%
%
\begin{frame}[fragile]
\frametitle{Naming Module Files: Extensions}
\begin{center}
{
\setlength{\aboverulesep}{.3em}
\setlength{\belowrulesep}{1em}
\begin{tabular}{p{3.5cm}p{3.5cm}p{3.5cm}}
\footnotesize Source/Header            & \footnotesize Module Interface & \footnotesize Module Implementation \\
\midrule
\texttt{.cpp/.hpp/.h}           & \texttt{.mpp}    & \texttt{.cpp}    \\ \addlinespace[.8em]
\texttt{.cxx/.hxx/.h}           & \texttt{.mxx}    & \texttt{.cxx}    \\ \addlinespace[.8em]
\texttt{.c++/.h++/.h}           & \texttt{.m++}    & \texttt{.c++}    \\ \addlinespace[.8em]
\texttt{.cc/.hh/.h}             & switch           & switch           \\ \addlinespace[.8em]
\texttt{.C/.H/.h}               & switch           & switch           \\
\end{tabular}}
\end{center}
\smallskip
\begin{center}\alert{\Large Have a separate extension for interfaces}\end{center}
\end{frame}

%
%
\begin{frame}[fragile]
\frametitle{Naming Module Files: Base}
\begin{codebox}[]
\begin{smallhlcode}{c++}
{}
{}
export module hello;

export module hello.format;
export module hello.print;

export module hello.print.iostream;
\end{smallhlcode}
\end{codebox}
\bigskip

\begin{minipage}{.6\textwidth}
\begin{verbatim}
libhello/
├── hello.mpp
├── hello-format.mpp
├── hello-print.mpp
└── hello-print-iostream.mpp
\end{verbatim}
\end{minipage}%
\begin{minipage}{.4\textwidth}
\begin{verbatim}
libhello/
├── hello.mpp
├── format.mpp
├── print.mpp
└── print-iostream.mpp
\end{verbatim}
\end{minipage}
\end{frame}

%
%
\begin{frame}[fragile]
\frametitle{Naming Module Files}
\begin{center}{\large Embed sufficient amount of module name ``tail''}\end{center}
\begin{center}{\large into file names to unambiguously distinguish modules}\end{center}
\begin{center}{\large within a library/project}\end{center}
\end{frame}

%
%
\begin{frame}[fragile]
\frametitle{Distributing Modules}
\begin{center}\alert{\Large What's in a BMI?}\end{center}
\bigskip
{\large
\begin{itemize}
  \itemsep0.7em
  \item Compiler specific, can be anything between
  \item ...stream of preprocessed tokens
  \item ...dump of an AST
  \item ...something close to object code
  \item Sensitive to most compiler options (even warning)
\end{itemize}}
\end{frame}

%
%
\begin{frame}[fragile]
\frametitle{What to Install/Distribute?}
\begin{center}\alert{\Large BMIs are not a \emph{distribution mechanism}}\end{center}
\bigskip
\begin{itemize}
  \itemsep0.7em
  \item BMIs should not be installed/distributed (maybe cached)
  \item Install/distribute module interfaces instead
  \item BTW, another reason to split interface/implementation
\end{itemize}
\end{frame}

%
%
\begin{frame}[fragile]
\begin{center}\alert{\Huge When}\end{center}
\end{frame}

%
%
\begin{frame}[fragile]
\frametitle{Modularization Options}
\begin{center}\alert{\Large How far do you want to go?}\end{center}
\bigskip
{\large
\begin{itemize}
  \itemsep0.7em
  \item Include translation
  \item Header importation
  \item Module importation
  \end{itemize}}
\end{frame}

%
%
\begin{frame}[fragile]
\frametitle{Types of C++ Projects}
\begin{center}
{\large
\renewcommand{\arraystretch}{3}
\setlength{\tabcolsep}{2.4em}
\setlength{\arrayrulewidth}{0.75pt}
\begin{tabular}{m{3.1cm} | m{3.1cm}}
Single-platform End-product & Single-platform Reusable \\
\\[-3.2em]
\hline
Cross-platform End-product  & Cross-platform Reusable \\
\end{tabular}}
\end{center}
\end{frame}

%
%
\begin{frame}[fragile]
\frametitle{Single-platform End-product}
\begin{center}
{\large
\renewcommand{\arraystretch}{1.5}
%\setlength{\tabcolsep}{2.4em}
\setlength{\arrayrulewidth}{0.75pt}
\begin{tabular}{p{6.6cm} | m{1.6cm}}
Single-platform End-product:
\smallskip
\smallskip
\begin{itemize}
  \itemsep0.5em
  \item \textcolor{orange!90!black}{Include translation} {\footnotesize(can do better)}
  \item \textcolor{green!50!black}{Header importation}
  \item \textcolor{green!50!black}{Module importation}
\end{itemize}
& \tiny Single-platform \newline Reusable \\
\\[-2.2em]
\hline
\tiny Cross-platform \newline End-product  & \tiny Cross-platform \newline Reusable \\
\end{tabular}}
\end{center}
\end{frame}

%
%
\begin{frame}[fragile]
\frametitle{Single-platform Reusable}
\begin{center}
{\large
\renewcommand{\arraystretch}{1.5}
%\setlength{\tabcolsep}{2.4em}
\setlength{\arrayrulewidth}{0.75pt}
\begin{tabular}{m{1.6cm} | p{6.6cm}}
\tiny Single-platform \newline End-product &
Single-platform Reusable:
\smallskip
\smallskip
\begin{itemize}
  \itemsep0.5em
  \item \textcolor{red!80!black}{Include translation} {\footnotesize(can do better)}
  \item \textcolor{green!50!black}{Header importation}
  \item \textcolor{green!50!black}{Module importation}
\end{itemize}
\\
\\[-2.2em]
\hline
\tiny \vspace{.7em} Cross-platform \newline End-product  & \tiny Cross-platform \newline Reusable \\
\end{tabular}}
\end{center}
\end{frame}

%
%
\begin{frame}[fragile]
\frametitle{Cross-platform End-product}
\begin{center}
{\large
\renewcommand{\arraystretch}{1.5}
%\setlength{\tabcolsep}{2.4em}
\setlength{\arrayrulewidth}{0.75pt}
\begin{tabular}{p{6.6cm} | m{1.6cm}}
\tiny Single-platform \newline End-product & \tiny \vspace{0.8em} Single-platform \newline Reusable \\
\\[-1.4em]
\hline
Cross-platform End-product:
\smallskip
\smallskip
\begin{itemize}
  \itemsep0.5em
  \item \textcolor{green!50!black}{Include translation}
  \item \textcolor{orange!90!black}{Header importation} {\footnotesize(complexity)}
  \item \textcolor{red!80!black}{Module importation} {\footnotesize(portability)}
\end{itemize}
& \tiny Cross-platform \newline Reusable \\
\end{tabular}}
\end{center}
\end{frame}

%
%
\begin{frame}[fragile]
\frametitle{Cross-platform Reusable}
\begin{center}
{\large
\renewcommand{\arraystretch}{1.5}
%\setlength{\tabcolsep}{2.4em}
\setlength{\arrayrulewidth}{0.75pt}
\begin{tabular}{m{1.6cm} | p{6.6cm}}
\tiny \vspace{0.8em} Single-platform \newline End-product & \tiny Single-platform \newline Reusable \\
\\[-1.4em]
\hline
\tiny Cross-platform \newline End-product  &
Cross-platform Reusable:
\smallskip
\smallskip
\begin{itemize}
  \itemsep0.5em
  \item \textcolor{green!50!black}{Include translation}
  \item \textcolor{red!80!black}{Header importation} {\footnotesize(portability)}
  \item \textcolor{red!80!black}{Module importation} {\footnotesize(portability)}
\end{itemize}
\\
\end{tabular}}
\end{center}
\end{frame}

%
%
\begin{frame}[fragile]
\frametitle{Cross-platform Reusable}
\begin{center}\alert{\Large Dual header/module interface?}\end{center}
\smallskip
\begin{center}\alert{\Large Just say No!}\end{center}
\smallskip
\begin{center}{\large See CppCon 2017 ``Building C++ Modules'' for details}\end{center}
\end{frame}

%
%
\begin{frame}[fragile]
\frametitle{When: the Standard}
{\large
\begin{itemize}
  \itemsep0.7em
  \item Modules in C++20
  \item Importable standard library headers in C++20
  \item Modular standard library in C++23
  \item What about system headers?
  \end{itemize}}
\end{frame}

%
%
\begin{frame}[fragile]
\frametitle{When: the Compilers}
{\large
\begin{itemize}
  \itemsep0.7em
  \item Still incomplete but improving rapidly
  \item There are bugs, especially in header importation
  \item Support for build systems is still lacking
  \end{itemize}}
\end{frame}

%
%
\begin{frame}[fragile]
\frametitle{When: the Build Systems}
\begin{center}
{
\setlength{\aboverulesep}{.3em}
\setlength{\belowrulesep}{1em}
\begin{tabular}{p{2.5cm}p{2.5cm}p{2.5cm}p{2.5cm}}
& \small Modules & \small Headers &  \small Include \newline Translation \\
\midrule
build2    & Yes           & Yes (GCC)    & Yes (GCC)    \\ \addlinespace[.8em]
CMake     & WIP           &              &              \\ \addlinespace[.8em]
Meson     & \multicolumn{3}{c}{``wait and see''}        \\ \addlinespace[.8em]
autotools & \multicolumn{3}{c}{``unlikely?''}           \\ \addlinespace[.8em]
Bazel     & \multicolumn{3}{c}{?}                   \\ \addlinespace[.8em]
Buck      & \multicolumn{3}{c}{?}                   \\ \addlinespace[.8em]
IDEs      & \multicolumn{3}{c}{?}                   \\
\end{tabular}}
\end{center}
\end{frame}

%
%
\begin{frame}[fragile]
\frametitle{Questions?}
\smallskip
{\Large Areas Not Covered:}
\bigskip
\begin{itemize}
  \itemsep0.7em
  \item Visibility vs Reachability
  \item Private module fragment (\texttt{module :private;})
  \item Interface and Implementation partitions
  \item Exported \texttt{using} declarations (\texttt{export using X;})
  \item What about \texttt{main()}?
  \item What about module versioning? Inline modules anyone?
\end{itemize}
\end{frame}

%
%
%\begin{frame}[fragile]
%\frametitle{Questions?}
%\begin{center}\colorhref{\LARGE \texttt{build2.org}}{https://build2.org}\end{center}
%\end{frame}

%
%
\end{document}
