%%% 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{1}                  %% Lecture number
\title{Introduction}   %% Title of lecture
\author{Ravikant Dintyala}       %% name of scribe
\date{26 August 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})

\begin{document}

\maketitle

\section{Introduction}

What is a program? Is it just something that tells the
computer what to do? That misses the point.  If a program
were just a simple list of instructions we wouldn't be able to do
much useful with computers. Programs are much more
interesting than that.

And if we think about a program as just a description of
what to do, then part of what a program means is baked into
the computer that interprets it. So you need to describe
that computer too, and _that's_ clearly more interesting than
just a list of instructions.

Programs describe computation, but they're really a kind of information
as well.  Suppose we step back from my initial question and ask a truly
fundamental question: ``what is information?''. For most of the
information we normally think about, familiar mathematical tools like
sets and sequences are adequate to describe that information. Programs
describe computation, but programs are information too---a particularly
interesting kind of information, especially for computer scientists. In
this course we'll see some of the mathematical, formal tools that are
needed to precisely describe what programs are, what programming
languages are, and maybe better answers to the two questions above.

This is a course about the _semantics_ of programs and programming
languages. ``Semantics'' is simply a fancy way of saying ``meaning'';
we want to give a precise meaning to programs. This is useful for many
reasons.  It means that we can understand
what they are going to do, which is clearly helpful in writing programs
that work. It also helps us when building tools like compilers,
optimizers, and interpreters because it means we can judge whether these
tools are implemented correctly.

There are three major components to this course.
\begin{itemize}
\item Dynamic Semantics. We will study methods for describing what a
program does when it runs.
\item Static Semantics. We will also study methods for reasoning about
programs before they run. We would like to rule out programs that are
bad in various senses before they run. For example, programs that
contain run-time (dynamic) type errors.
\item Language features. We will apply methods for dynamic and static
semantics to study actual language features of interest, probably
including some interesting features that many students have not seen
before.
\end{itemize}

We would like to characterize the semantics of a program as a function
produces the output based on inputs. More generally, real programs
are reactive and interact with their inputs arriving from the
environment. Describing this kind of program is more challenging,
though we can view the reactive behavior of the program again as a
function of the inputs it receives from the environment as it runs.
Thus, to describe program semantics, we will build up some mathematical
tools for constructing and reasoning about functions.

\subsection{Review of mathematical functions}

A (_total_) _function_ is a relation, in which each element of a set $A$
is associated with a unique element of another (possibly the same)
set $B$. If $f$ is such a function, we write:

\[
f : A \rightarrow B
\]

Here, $A$ is the _domain_ of the function and $B$ the
_codomain_. The _image_ of the function is the set of elements in
$B$ that at least one element in $A$ is mapped to.

\[
{\mathit{image}}(f) = \{ x \in B : x = f(a) \mbox{~for some~} a \in A \}
\]

\noindent
We avoid the the word _range_ because it is ambiguous:
sometimes it is used to refer to the codomain, sometimes to the image.
A _partial function_ $f: A \rightharpoonup B$ is a relation that is a function on
some subset of the domain $\dom(f) \subseteq A$.

\subsection{Function representation}

One way of describing functions mathematically is via their
_extension_: essentially, the set of all pairs of (input,output) values. Other
way is to give an _intensional_ representation---a program, or what
you have to do in order to evaluate the function.

As an aside, this class is quite a bit about how to get from an
intensional representation of a program to some more extensional
representation of the program, often a function. In this class, program texts actually refer
to their parsed abstract syntax trees \nm(AST)

%AST -> (Static semantics) -> valid AST -> (Dynamic semantics) -> Extensional representation.

\subsection{Lambda Calculus}

Introduced by Alonzo Church and Stephen Cole Kleene in the 1930s to
describe functions in an unambiguous and compact manner, lambda
calculus\footnote{Why $\lambda$? Church wanted to separate the bound
variables from the unbound (free) variables and he used a caret on top of
the bound variables. $f(x) = x + yx^2$ was represented as
 $\hat{x} . x + yx^2$. Apparently, the printers could not handle the caret 
and it moved to the front and became a $\lambda$;
the expression became $\lam{x}{x + yx^2}$}
gives an _intensional_ representation for a function. The
lambda calculus is universal in the sense that any computable
function can be expressed and evaluated using this formalism. It is
thus equivalent to a _Turing machine_.

Real programming languages such as Lisp, Scheme, Haskell and ML are
very much based on lambda calculus, although there are differences
as well.

\section{Untyped Lambda Calculus}
\subsection{Syntax}
The following is the syntax of the $\lambda$-calculus. A term is
defined as follows:

\medskip

$\begin{array}{rcll}
\nm{e} & ::= & x & x \in \Set{Var} \qquad~\mbox{where \Set{Var} is some
countable set} \\
& \bnf & e_0~e_1 & \textit{(application)} \\
& \bnf & \lam{x}{e} & \textit{(abstraction)} \\
\end{array}$

\medskip

In an abstraction, $x$ is the _argument_, $e$ is the _body_ of the
function. Notice that this function doesn't have a name.  In
mathematics it is common to define functions as $f(x)=x^2$. A
corresponding anonymous notation that is frequently used is $x
\mapsto x^2$; this is really the same thing as $\lam x{x^2}$. One
nice thing about lambda terms is that they are an _anonymous_
representation of functions: the function doesn't have to have a
name like $f$ in order to talk about this.

Here are some examples of terms. First, we present (and define) the
identity function:

\[\nm{ID} = \lam xx \]

The next example is a function that will ignore its argument and
return the identity function.

\[ \lam x {\lam aa} \]

This is the same as

\[ \lam x {ID} \]

Parentheses are used to show explicitly how to parse expressions,
but they are not strictly necessary. It's a good idea to include
them if you aren't sure. Lambda terms are like sums: they extend as
far to the right as they can. For example, $(\lam{x}{x}~\lam{y}{y})$
is the same thing as $(\lam{x}{(x~\lam{y}{y})})$, not
$((\lam{x}{x})~(\lam{y}{y}))$. Application is _left-associative_ -
that is, $e_1~e_2~e_3$ is the same thing as $(e_1~ e_2)~ e_3$.

\subsection{Closed terms}

An occurrence of a variable _x_ in a term is said to be _bound_ if
there is an enclosing $\lam x {e}$; otherwise, it is _free_. A
_closed term_ is one in which all identifiers are bound.

Consider the following term:

\[ \lam{x}{(x~(\lam{y}{y~a})~x)~y} \]

Both occurrences of _x_ are bound, the first occurrence of _y_ is
bound, the _a_ is free, and the last _y_ is also free, since it is
outside the scope of the $\lambda y$.

If a program has some variables that are free, then you do not have
a complete program as you do not know what to do with the free
variables. Hence, a well formed program in lambda calculus is a
closed term.

\subsection{Higher-order functions}

In lambda calculus, we can define functions that can take functions
as arguments and/or return functions as results. In fact, every
argument is a function and every result is a function.  That is,
functions are first-class values.

This example takes a function as an argument and applies it to 5:
\[ \lam{f}{(f~5)} \]

We can further generalize. This function takes an argument $v$ and
returns a function that calls its argument on $v$:

\[ \lam{v}{\lam{f}{(f~v)}} \]

\subsection{Multi-argument functions and currying}

A mutli-argument lambda calculus (functions having multiple
arguments) could be defined as

\medskip

\[\begin{array}{rcll}
\nm{e} & ::= & \ldots \mbox{\em earlier stuff} \ldots \\
       & \bnf & \lam {x_1 \ldots x_n}{e}
                    & \mbox{(multi-argument abstraction)} \\
& \bnf & e_0~e_1~e_2~\ldots~e_n
                    & \mbox{(multi-argument application)} \\
\end{array}\]

\medskip

In the multi-argument application, $e_0$ is a $n$-argument function and
$e_1\ldots e_n$ are the arguments.

It is known that this isn't any more expressive than basic lambda
calculus. So, we stick to basic lambda calculus but we may
occasionally write down terms that look like the above for
convenience. It's just _syntactic sugar_. It can be transformed into
something more basic that does not require the extended syntax. A
transformation that removes syntactic sugar is called _desugaring_.

Desugaring multi-argument functions:

\begin{eqnarray*}
\lam{x_1\ldots x_n}{e}  & \Rightarrow & \lam{x_1}{\lam{x_2}{ \lam{x_n}~{e} }}
\\
e_0~e_1~\ldots~e_n & \Rightarrow &
(\ldots((e_0~e_1)~e_2)~\ldots e_n)
\end{eqnarray*}

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