\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{proof}
\usepackage{mathpartir}
\usepackage{url}
\usepackage{listings}
\usepackage{color}
\definecolor{eclipseBlue}{RGB}{42,0.0,255}
\definecolor{eclipseGreen}{RGB}{63,127,95}

\lstset {
  basicstyle=\small\ttfamily,
  captionpos=b,
  tabsize=2,
  columns=fixed,
  breaklines=true,
  frame=l,
  numbers=left,
  numberstyle=\small\ttfamily,
  morekeywords= {
    EQUAL, GREATER, LESS, NONE, SOME, abstraction, abstype, and, andalso, array, as, before, bool, case, char, datatype, do, else, end, eqtype, exception, exn, false, fn, fun, functor, handle, if, in, include, infix, infixr, int, let, list, local, nil, nonfix, not, o, of, op, open, option, orelse, overload, print, raise, real, rec, ref, sharing, sig, signature, string, struct, structure, substring, then, true, type, unit, val, vector, where, while, with, withtype, word
  },
  morestring=[b]",
  morecomment=[s]{(*}{*)},
  stringstyle=\color{black},
  identifierstyle=\color{eclipseBlue},
  keywordstyle=\color{red},
  commentstyle=\color{eclipseGreen}
} 

\newcommand{\texttilde}{\url{~}}
\newcommand{\step}{\stackrel{1}{\Longrightarrow}}
\newcommand{\stepk}[1]{\stackrel{#1}{\Longrightarrow}}

\title{Lecture 2 - Patterns and Functions}
\author{David M Kahn
  \footnote{Adapted from Michael Erdmann's Spring 2022 notes, 
  in turn adapted from a draft of Frank Pfenning}
}
\date{Summer 2022}

\begin{document}

\maketitle

\section{Patterns}

Patterns are ways of referring to the structure 
of some value. There are (so far in the 
course) 4 different kinds of patterns to 
be aware of: 

\begin{itemize}
  \item constants\footnote{
    The constants cannot be functions or 
    reals though. This is because there is 
    no easy way to check equality 
    between them - there are infinitely many 
    digits of precision between real numbers,
    and infinitely many possible 
    inputs between functions (which might 
    not even terminate). This is similar 
    to the restrictions on the use of 
    \texttt{=} and \texttt{<>}; 
    you can only use constants in 
    a pattern that can be compared with
    \texttt{=} or \texttt{<>}.
  } -- these patterns match only to 
  the constant that they are
  \item variables -- these match to any 
  value, and bind that value to the 
  variable in the environment
  \item the wildcard (underscore) -- this 
  matches to any value, but does nothing 
  with it
  \item tuples of other patterns -- this 
  matches tuples of the same length where 
  each element matches the pattern in the 
  same position
\end{itemize}

For example, \texttt{(\_, 5, x)} is a pattern 
matching 3-tuples with a middle element of 5, 
and the use of this pattern binds 
the third element of the tuple to \texttt{x}.
This happens to use all the pattern 
components we have gone over so far, but 
later in the course we will learn some other
patterns.

Multiple patterns are often used to 
consider different cases of what some 
value looks like. For such uses, 
we will find that the patterns are 
separated with the vertical line symbol $\texttt{|}$.
This symbol is not itself a pattern.

One thing to keep in mind is SML patterns 
do not allow one to reuse variables. 
Thus, the ``pattern'' \texttt{(x, x)} is
simply not 
allowed -- it is \textit{not} used match 
pairs where both elements are the same.
To do that, one would need to write 
code like the following:

\begin{lstlisting}
  case p of (a, b) =>
    if a=b 
    then ... 
    else ...
\end{lstlisting}


\subsection{Case Expressions}
One place patterns can be used is in 
case expressions. These can be used to 
break up data into its constituent components,
and also to branch based upon how those 
components look. It is very general, can 
actually replace both if-then-else and 
let-in-end expressions. If you are trying to 
\textit{use} some compound type, and the type is 
not a function, you probably will use
the type through breaking it up 
with a case expression.

\paragraph{Expression}
\texttt{case }$e_0$\texttt{ of }
$p_1$\texttt{ => }$e_1$\texttt{ | }\dots 
\texttt{ | }$p_n$\texttt{ => }$e_n$
where each $p_i$ is a pattern

\paragraph{Typing}
\texttt{case }$e_0$\texttt{ of }
$p_1$\texttt{ => }$e_1$\texttt{ | }\dots 
\texttt{ | }$p_n$\texttt{ => }$e_n$\texttt{ : }$t$
\\
if $e_0$\texttt{:}$t'$ and, for each $i$, 
\begin{itemize}
  \item the pattern $p_i$ could apply
to values of 
the type $t'$
  \item $e_i$\texttt{:}$t$
given the types of any new variables bound 
in $p_i$ 
\end{itemize}

\paragraph{Reduction}
\begin{itemize}
  \item \texttt{case }$e_0$\texttt{ of }
  $p_1$\texttt{ => }$e_1$\texttt{ | }\dots 
  \texttt{ | }$p_n$\texttt{ => }$e_n$
  \\
  $\step$
  \texttt{case }$e_0'$\texttt{ of }
  $p_1$\texttt{ => }$e_1$\texttt{ | }\dots 
  \texttt{ | }$p_n$\texttt{ => }$e_n$
  \\
  if $e_0 \step e_0'$

  \item \texttt{case }$v$\texttt{ of }
  $p_1$\texttt{ => }$e_1$\texttt{ | }\dots 
  \texttt{ | }$p_n$\texttt{ => }$e_n
  \step [\mathit{env}]e_i$ where 
  $v$ is a value,
  $p_i$ is the first pattern to match $v$,
  and $\mathit{env}$ contains
  any new bindings to the appropriate 
  components of $v$ that $p_i$ induces
\end{itemize}


\paragraph{Examples}
\begin{itemize}
  \item \texttt{case (a, b) of }$e_1$\texttt{ => }$e_2$ 
  is a way to break up pairs, since we 
  can now use the variables \texttt{a} and 
  \texttt{b} to refer to its elements, and is far 
  preferable to projections (e.g. \texttt{\#1}) stylistically

  \item \texttt{case }$e_1$\texttt{ of x => }$e_2$ 
  is extensionally equivalent to (i.e, behaves exactly like)
  the expression
  \texttt{let val x = }$e_1$\texttt{ in }$e_2$\texttt{ end}

  \item \texttt{case }$e_1$\texttt{ of true => }$e_2$
  \texttt{ | false => }$e_3$
  is extensionally equivalent to (i.e., behaves exactly like)
  the expression \texttt{if }$e_1$\texttt{ then }$e_2$\texttt{ else }$e_3$
\end{itemize}

\paragraph{Special Notes} It is 
highly recommended to always put parentheses
around
case statements. This ensures they are 
parsed correctly, which otherwise 
is a major source of errors, especially 
when case statements are nested.

Case statement patterns do not need to 
be exhaustive, but they will throw an 
exception at runtime if no pattern matches 
the data being cased on. Also, an error 
will be thrown if further 
clauses are written past when 
the clauses' patterns become exhaustive.



\subsection{Val Declarations}
Val declarations can bind value components 
directly just like case statements, as long 
as the pattern uses variables. Otherwise,
if the pattern is a constant, the effect of 
the let binding is a test that the value to 
be bound equals that constant. Or if the pattern is 
a wildcard, the value to be bound is 
evaluated and then discarded.

For example, consider using 
patterns in the declarations 
of our let statements:

\paragraph{Expressions}\texttt{let }$p$\texttt{ = }$e_1$\texttt{ in }
$e_2$\texttt{ end} where $p$ is a pattern.

\paragraph{Typing} The typing is the same as 
previous let expressions, except 
the variables typings assumed are those
determined by the pattern $p$ and the 
type of $e_1$.

\paragraph{Reduction} The reducton is the 
same as previous let expressions, except 
the bindings made are those determined by 
the pattern $p$ and the 
value of $e_1$. Also, if constants are used 
and the value of $e_1$ does not match those 
constants, then an exception is thrown 
instead of reduction continuing.

\paragraph{Examples}
Here are some examples of val
declarations using patterns.
\begin{itemize}
  \item \texttt{val x = 5} is our 
  ``normal'' declaration, but it is already 
  using a pattern -- the variable

  \item \texttt{val (a, b) = (1, true)} is 
  another way to break up tuples -- the 
  first element is bound to \texttt{a} and 
  the second to \texttt{b}

  \item \texttt{val \_ = }$e$ evaluates $e$ 
  and throws the value away -- this 
  has no effect unless $e$ has side effects

  \item \texttt{val (\_, false) = }$e$ tests 
  whether the second element of $e$ evaluates
  to \texttt{false} -- if not, an error would be 
  thrown at runtime
\end{itemize}


\subsection{Functions}

Patterns provide us with 
a special syntactic sugar (i.e.,
code shorthand) for automatically casing on the
input to a function.
For functions like 
\texttt{fn x => }$e$, to use 
this feature, the syntax is the following:

\texttt{fn }$p_1$\texttt{ => }$e_1$\texttt{ | }
\dots\texttt{ | }$p_n$\texttt{ => }$e_n$

This is extensionally equivalent to:

\texttt{fn x => case x of }$p_1$\texttt{ => }$e_1$\texttt{ | }
\dots\texttt{ | }$p_n$\texttt{ => }$e_n$

\section{Functions}

\subsection{Anonymous Functions}
The functions we've been using so far,
which look like \texttt{fn x => }$e$, 
are called \textit{anonymous}. This is 
because they do not come with a name. 
Lacking a name is normal for expressions -- 
we are not bothered by the fact that 
\texttt{(true, 5 + 7)} has no special name,
and likewise we should not be bothered 
that our functions can lack names.

If we want to give an anonymous
function a name, we can 
name it using a declaration like so:
\begin{lstlisting}
  (* 
   * square : int -> int
   * REQUIRES: true
   * ENSURES: square x evaluates to x * x
   *)
  val square = fn (x:int) => x * x
\end{lstlisting}
It is also good practice to include a 
header for top-level functions, and to 
annotated the function, as shown. (Note 
that anonymous functions do not 
allow you to annotate the return 
type directly.) It is also good 
practice to include tests, which 
have not been shown.

In the expression \texttt{fn x => }$e$,
we call \texttt{x} the \textit{formal parameter}
of the function, and $e$ the \textit{body}.

\subsection{Recursive Functions}
While there is no direct expression 
for recursive functions like there is 
for anonymous ones, there is a declaration:

\begin{lstlisting}
  (* 
   * fac : int -> int
   * REQUIRES: x >= 0
   * ENSURES: fac x evaluates to x!
   *)
  fun fac (x:int) : int = 
    if x = 0 
    then 1 
    else x * fac (x - 1)
\end{lstlisting}
Again, it is good practice to include
a header like that shown. (This time 
the return type can be annotated directly.)

We can reason about these recursive functions 
similarly to anonymous functions. They 
still have formal parameters and bodies, 
still result in closure values, and 
still can be applied, but recursive functions 
also come
with the new feature that their 
name (which is \texttt{fac} in the
above case) is recursively bound in their body.
We can examine this formally using let expressions.

\paragraph{Expressions}
\texttt{let fun f x = }$e_1$\texttt{ in }$e_2$\texttt{ end}

\paragraph{Values} The values bound by recursive
function declarations are closures just like those 
of anonymous functions\footnote{
  However, it is useful to extend our notion 
  of closure to include the function name now. 
  That way we can write out the application
  reduction finitely 
  like so: 
  \\
  $\langle \mathit{env},$ \texttt{fn x => }$e\rangle_f \; v
  \step [\mathit{env}, v/x,  \langle \mathit{env},$ \texttt{fn x => }$e\rangle_f / f]\;e$
  \\
  Otherwise our environment would contain a closure 
  containing the same environment containing 
  the same closure and so on infinitely, since 
  the function recursively refers to itself. 
  This is fine to reason about, but hard to 
  write down, hence the use of now including 
  the function name in recursive closures. 
  However, we usually elide environments, so 
  this detail does not usually matter.
}. 

\paragraph{Typing}
\texttt{let fun f x = }$e_1$\texttt{ in }$e_2$\texttt{ end:}$t$
\\
if \begin{itemize}
  \item $e_1$\texttt{:}$t_2$ assuming that 
  $f$\texttt{:}$t_1 \rightarrow t_2$ and 
  $x$\texttt{:}$t_1$

  \item $e_2$\texttt{:}$t$ assuming that 
  $f$\texttt{:}$t_1 \rightarrow t_2$ 
\end{itemize}
This is a lot like how we typed let expressions 
before, except notice that the declaration 
of $f$ causes $f$ to be typed in both 
the usual scope $e_2$, and also the 
function body $e_1$. 

\paragraph{Reduction} These functions 
reduce the same way as anonymous functions
\footnote{\dots with the caveat from the 
previous footnote}.

\paragraph{Special Notes} Recursive functions
also allow the use of patterns similarly to 
anonymous functions, except they require 
their name to be repeated in each clause.
The exact syntax for this feature is the following:

\texttt{fun f }$p_1$\texttt{ = }$e_1$\texttt{ | }
\dots\texttt{ | f }$p_n$\texttt{ = }$e_n$

This is just syntactic sugar for the declaration:

\texttt{fun f x = case x of }$p_1$\texttt{ => }$e_1$\texttt{ | }
\dots\texttt{ | }$p_n$\texttt{ => }$e_n$




\section{Fixity}

\textit{Fixity} is the categorization of 
the order of functions and arguments in 
our syntax. It is nice to know, but not 
necessary for the course.

\subsection{Prefix}
  By default, the fixity of 
  functions that we 
  define in SML is prefix, 
  meaning the function 
  appears before its arguments. For 
  example, we write the application of 
  the function \texttt{square} to the argument 5
  as \texttt{square 5}, with the function first.

\subsection{Postfix} 
  SML has no way of writing 
  postfix functions, which is where the function 
  comes after the argument. However,
  it is not uncommon to see in mathematics. 
  The common notation for the factorial uses
  the exclamation point as a postfix function, 
  so that, e.g., $5!$ means the application 
  of the factorial function to 5.
  
\subsection{Infix}

Infix means that the function appears 
between its arguments. This is commonly 
used for functions of 2 arguments, like addition, 
which we write like $5 + 7$. 
Indeed, you
might have considered SML features like addition 
to be ``primitive'' operations, but they are in fact
functions with special syntactic sugar. 
If you ever want to refer to the 
function and not the operation for these 
special functions, simply put \texttt{op} 
before the desired symbol, like \texttt{op+}.
Note the type of \texttt{op+} is \texttt{int * int -> int};
these infix functions always take a pair as 
an argument.
Also note that writing \texttt{op} only works for functions 
whose name does not start with a letter, 
like \texttt{+}.

To make an infix function \texttt{f} in SML, you simply 
write \texttt{infix f} as a declaration, and 
elsewhere define \texttt{f} to take a pair as 
an argument. After declaring \texttt{infix f},
the function \texttt{f} will be treated as 
infix. 

If you declare \texttt{f} before the 
declaration \texttt{infix f}, then \texttt{f}
should be defined as usual for a function 
taking a pair as an argument. Additionally, 
if the function name \texttt{f} begins 
with \texttt{op} followed by some non-letter 
symbol, then \texttt{op} will be dropped in 
later infix use.

\begin{lstlisting}
  fun plus (x, y) = x + y
  infix plus
  val 12 = 5 plus 7

  fun op& (x, y) = x andalso y
  infix &
  val false = true & false
\end{lstlisting}

If you declare \texttt{f} to be infix 
prior to defining $f$, then you must either define 
$f$ with an \textit{infix} declaration like \texttt{fun x f y = }$e$ 
or by using our standard declarations while 
adding \texttt{op} to the function name. The 
latter is only available for function names 
that can use \texttt{op}, meaning those 
that do not start with a letter.

\begin{lstlisting}
  infix plus
  fun x plus y = x + y
  val 12 = 5 plus 7
  
  infix &
  fun op& (x, y) = x andalso y
  val false = true & false
  \end{lstlisting}





\section{Extensional Equivalence and Reduction Tricks}

Extensional equivalence ($\cong$) and reduction-in-any-number-of-steps 
($\Longrightarrow$)
are closely related, but not identical. 
Here are some tricks to help reason 
about them.

\begin{itemize}
  \item $\cong$ is an equivalence relation, 
  so it satisfies: 
  \begin{itemize} 
    \item reflexivity: $e \cong e$
    \item symmetry: if $e_1 \cong e_2$ then 
    $e_2 \cong e_1$ 
    \item transitivity: if $e_1 \cong e_2$ and 
    $e_2 \cong e_3$ then $e_1 \cong e_3$
  \end{itemize}

  \item $\Longrightarrow$ is a partial order 
  relation, so it satisfies:
  \begin{itemize} 
    \item reflexivity: $e \Longrightarrow e$
    \item antisymmetry: if $e_1 \Longrightarrow e_2$ and 
    $e_2 \Longrightarrow e_1$, then $e_1 = e_2$
    \item transitivity: if $e_1 \Longrightarrow e_2$ and 
    $e_2 \Longrightarrow e_3$ then $e_1 \Longrightarrow e_3$
  \end{itemize}

  \item $\cong$ is closed under 
  (side-effect free) reduction, so 
  if $e \Longrightarrow e'$ then 
  $e \cong e'$

  \item $e_1 \cong e_2$ does \textit{not} 
  mean that $e_1 \Longrightarrow e_2$ or 
  $e_2 \Longrightarrow e_1$ -- 
  a counter example is \texttt{fn x => x + 1} and 
  \texttt{fn x => 1 + x}, which are extensionally 
  equivalent but do not reduce to each other

  \item we can combine the previous properties 
  to learn that if $e_1 \Longrightarrow e$ and 
  $e_2 \Longrightarrow e$, i.e., if 
  two expressions reduce to the same 
  expression, then those two 
  expressions are extensionally equivalent $e_1 \cong e_2$

  \item similarly, if $e_1 \Longrightarrow e_1'$ 
  and $e_2 \Longrightarrow e_2'$ where $e_1' \cong e_2'$, 
  then $e_1 \cong e_2$

  \item thanks to referential transparency, 
  we can replace extensionally equivalent 
  subexpressions without affecting 
  extensional equivalence, so that 
   $[e_1/x]\;e \cong [e_2/x]\;e$ 
  if $e_1 \cong e_2$; for example, 
  we know the extensional equivalence
  \texttt{f 3 + (2 * 3)}$\cong$
  \texttt{f 3 + (5 + 1)} since 
  $2*3\cong 5+1$, and we do not 
  need to know anything about
  the function application \texttt{f 3}
  (except that \texttt{f:int -> int})

  \item for the \textit{values} of most types, 
  extensional equivalence ($\cong$) coincides 
  with normal equality (=), but this is not 
  true for the values of 
  types that cannot be compared with \texttt{=}
  like functions and reals

  \item if $e \hookrightarrow v$ then 
  $e \cong v$, since $e \hookrightarrow v$
  entails that $e \Longrightarrow v$

  \item there exist many examples of 
  an expression $e$\texttt{:}$t$ 
  that is not extensionally equivalent 
  to any values type $t$ -- this happens 
  when $e$ is not valuable, i.e., when 
  $e$ does not evaluate to a value, and 
  instead does something like loop forever
  or throw an exception

  

\end{itemize}




\end{document}