\documentstyle{slides}
\begin{document}
\small
\def\Title#1{\begin{center}{\large #1}\end{center}\par}
\hyphenpenalty=500
\catcode`@=11
\def\BeginBlackAndWhite{\newpage\setcounter{page}{0}\@bwtrue\@visibletrue
\if@onlyslidesw \xdef\@doslidelist{\@doglslidelist}%
\@setlimits\@doslidelist\@doslidelow\@doslidehigh\fi
\if@onlynotesw \xdef\@donotelist{\@doglnotelist}%
\@setlimits\@donotelist\@donotelow\@donotehigh\fi
\normalsize\setcounter{slide}{0}\setcounter{overlay}{0}%
\setcounter{note}{0}\@makingslidestrue}
\def\@listi{\parsep=.5\parskip\topsep=.1\parskip\itemsep=.2\parskip\partopsep=0p
t}
\def\@listii{\leftmargin\leftmarginii
 \labelwidth\leftmarginii\advance\labelwidth-\labelsep
 \parsep .5\parskip \topsep \parsep \itemsep .5\parskip}

\def\Eval#1{{\hbox{$Eval[\![$\tt #1$]\!]$}}}
\newcommand{\Tilde}{\raisebox{-0.6ex}{\tt\char`\~}}
\def\Item{\hspace*{0.8em}$\bullet$\hspace{0.8em}}
\def\docspecials{\do\ \do\$\do\&%
  \do\#\do\^\do\^^K\do\_\do\^^A\do\%\do\~}

\def\alltt{\trivlist \item[]\if@minipage\else\vskip\parskip\fi
\leftskip\@totalleftmargin\rightskip\z@
\parindent\z@\parfillskip\@flushglue\parskip\z@
\@tempswafalse \def\par{\if@tempswa\hbox{}\fi\@tempswatrue\@@par}
\obeylines \tt \catcode``=13 \@noligs \let\do\@makeother \docspecials
\frenchspacing\@vobeyspaces}
\let\endalltt=\endtrivlist

\def\EvalsTo{\(\Rightarrow\)}
\newcommand{\backsl}{{\tt\char"5C}}

\catcode`@=12

\BeginBlackAndWhite
\begin{slide}{}
\begin{center}
{\Large Q: A Uniform Language for Writing and Running Programs}

Per Bothner

(Cygnus Support)\\
(bothner@cygnus.com)
\end{center}
\end{slide}

\begin{slide}{}
\Title{What is Q?}
\small
\Item A very high-level programming language

\Item Multiple data types (like Lisp):\\
Numbers, vectors, strings, 1st-class functions, ...
% (String-only languages like Tcl are elegantly simple, but:
%  - constant re-parsing is expensive, and:
%  - difficult to construct non-trivial data structures.)

\Item Abstract sequences used for all repetition.\\
(Like APL's use of arrays, or Smalltalk collections.)\\
Sequences can be stored, or calculated on demand.

\Item Powerful operations used uniformly in\\
multiple domains.

\Item ``Medium terse'' syntax is designed for interaction.

\Item "Mostly-functional"\\
(encourages side-effect-free computation, like Lisp).

\Item Builtin shell-style features\\
(running programs, globbing).
\end{slide}


\begin{slide}{}
\Title{Lazy vectors}

\small
\verb'{f(A?)}'  - sequence whose i'th element is \verb'f(A i)'

Elements are calculated on demand.\\
Each element is only calculated at most once;\\
hence must be saved (memoized) (unless optimized).

Replaces many kinds of loops.

Example: Fibonacci function.\\
Standard recursive definition:

\begin{alltt}
:(Fib :i)=if i<2 => 1 || Fib(i-1) + Fib(i-2)
\end{alltt}

Very slow (exponential run time).\\
Use a lazy vector as a cache:

\begin{alltt}
:(Fib :i)=if i<2 => 1 || FibCache(i-1) + FibCache(i-2)
:FibCache = \{Fib ?\}
\end{alltt}

Fast (linear because the {\tt FibCache} lazy vector\\
remembers calculated {\tt Fib} values, so they don't\\
need to be re-calculated).
\begin{alltt}
(Fib 200) {\EvalsTo} 453973694165307953197296969697410619233826
\end{alltt}
\end{slide}

\begin{slide}{}
\Title{Uniformity}

\small
Indexing:

{\tt [3 4 5] i}  {\EvalsTo}  {\tt i}'th element of vector\\
{\tt "abcd" i}  {\EvalsTo} {\tt i}'the character of string\\
{\tt (0 to 100) i}  {\EvalsTo} {\tt i}\\
{\tt ./Makefile i}  {\EvalsTo}  {\tt i}'th character in file\\
\verb'{A? + 100} i'  {\EvalsTo} \verb'(A i)+100'

Length of sequence:
\begin{alltt}
size [3 4 5]  {\EvalsTo} 3
size "abcd"  {\EvalsTo} 4
size (0 to 100) {\EvalsTo} 100
size ./Makefile  {\EvalsTo} {\rm \# of bytes in file {\tt Makefile}}
size {A? + 100}  {\EvalsTo}  size A
\end{alltt}

An (open) file is an iterator over a sequence of\\
characters.

A Unix executable program is a function\\
(with a different calling convention).

Standard input and output are abstractly strings.\\
Files in a Unix file system are also abstractly strings.\\
A pipeline is a special case of function composition.
\end{slide}


\begin{slide}{}
\Title{Running programs}
\small
\begin{alltt}
\# Search source files for PATTERN
{\tt grep $(PATTERN) *.([Cch] cc)}
\end{alltt}

is macro-expanded (at compile time) into:

\begin{alltt}
run_program "grep" (
  glob_expand_list [PATTERN "*.[Cch]" "*.cc")
\end{alltt}

A prefixed argument is evaluated and passed as\\
stdin to the program.

Converting strings to upper-case (inefficiently):
	
\begin{alltt}
:(upper_case :arg) = arg run /bin/tr a-z A-Z
\end{alltt}

\begin{alltt}
printf "<%#s>{\backsl}n" (upper_case "Hello World!{\backsl}n")
{\EvalsTo} <"HELLO WORLD!{\backsl}n">
\end{alltt}
\end{slide}

\begin{slide}{}
\Title{Rename files using patterns}
\small
\begin{alltt}
:(__ren :src :dst)=(
  :X=(glob src)
  \{run mv $(X?) $(X? match $src $dst)\} do)
:(macro ren :args@) =
  parse "__ren (quote " args@ ")@"
\end{alltt}

Example:  {\tt ren *.c.BAK BAK/*.c}

Macro-expands to:  \verb|__ren "*.c.BAK" "BAK/*.c"|

'{\tt (glob src")}' might return {\tt ["main.c.BAK" "misc.c.BAK"]}

'{\tt \{ ... \} do}' repeats '...' until {\tt X} is exhausted.

For each element of {\tt X} (say {\tt "main.c.BAK"}) translate it
(using '{\tt match}') (into say {\tt "BAK/main.c"}),
and use the "{\tt mv}" command to rename it.
\end{slide}

\begin{slide}{}
\Title{Implementation}
\small

\Item Written in C++.
  Most types inherit from "Root" class.

\Item Interpreter for interactive use,
  or compile into C++ (both share front end).

\Item Multi-language run-time system.\\
(Includes incomplete Scheme and Common Lisp.)

\Item Q objects are C++ objects.\\
Trivial to add new Q or Lisp builtins written in C++.

\Item The Q version of a shell command line will\\
generally use Unix primitives (forks, pipes, ...)\\
as efficiently as a shell (avoids needless copying).
\end{slide}

\begin{slide}{}
\Title{Availabilty}
\small

\Item Freely re-distributed (contains GNU code).

\Item Pre-alpha:  currently for hackers only!

\Item See \verb|cygnus.com:~ftp/pub/Q.README| for directions.

\Item Not supported by Cygnus Support.
\end{slide}

\end{document}
