2248 lines
76 KiB
TeX
2248 lines
76 KiB
TeX
%!TEX TS-program = xelatex
|
|
|
|
\documentclass[onecolumn, 12pt, twoside, openright, dvipdfm]{book}
|
|
|
|
\usepackage{fontspec}
|
|
\usepackage{hanging}
|
|
\usepackage{xltxtra}
|
|
|
|
\defaultfontfeatures{Scale=MatchLowercase}
|
|
%\setmainfont[Mapping=tex-text]{Cochin}
|
|
%\setmainfont[Mapping=tex-text]{Palatino}
|
|
%\setmainfont[Mapping=tex-text]{Baskerville}
|
|
%\setmainfont[Mapping=tex-text]{Perpetua}
|
|
%\setmainfont[Mapping=tex-text]{Lido STF}
|
|
%\setmainfont[Mapping=tex-text]{Perpetua}
|
|
\setmainfont[Mapping=tex-text]{Charis SIL}
|
|
%\setmainfont[Mapping=tex-text]{Gentium}
|
|
%\setmainfont[Mapping=tex-text]{DejaVu Serif}
|
|
%\setmainfont[Mapping=tex-text]{Palatino}
|
|
%\setmainfont[Mapping=tex-text]{URWPalladioL}
|
|
%\setmainfont[Mapping=tex-text]{GentiumAlt}
|
|
\setsansfont[Mapping=tex-text]{Geneva}
|
|
%\setmonofont{DejaVu Sans Mono}
|
|
%\setmonofont{Monaco}
|
|
\setmonofont{Inconsolata}
|
|
|
|
\usepackage{fancyhdr}
|
|
\usepackage{makeidx}
|
|
\usepackage{fancyvrb}
|
|
\makeindex
|
|
|
|
\usepackage[dvipdfm,CJKbookmarks,bookmarks=true,bookmarksopen=true]{hyperref}
|
|
\hypersetup{
|
|
pdftitle={Ikarus Scheme User's Guide},
|
|
pdfauthor={Abdulaziz Ghuloum},
|
|
pdfkeywords={Scheme, R6RS, Compiler, Ikarus},
|
|
bookmarksnumbered=true,
|
|
pagebackref=true,
|
|
breaklinks=true,
|
|
% pdfview=FitH, % Or try pdfstartview={FitV}, This lead to uncorrect bookmarks
|
|
urlcolor=blue,
|
|
colorlinks=true,
|
|
citecolor=blue, %citeref's color
|
|
linkcolor=blue,
|
|
}
|
|
|
|
\usepackage{rotating}
|
|
\usepackage{multicol,ragged2e}
|
|
|
|
|
|
\renewcommand{\sectionmark}[1]{\markright{\thesection\ #1}}
|
|
\fancyhf{}
|
|
\fancyhead[LE,RO]{\bfseries\thepage}
|
|
\fancyhead[LO]{\bfseries\rightmark}
|
|
\fancyhead[RE]{\bfseries\leftmark}
|
|
\renewcommand{\headrulewidth}{0pt}
|
|
\renewcommand{\footrulewidth}{0pt}
|
|
\renewcommand{\headheight}{15pt}
|
|
|
|
\newcommand{\coderefpage}[1]{figure~\ref{#1}, p.~\pageref{#1}}
|
|
\newcommand{\figrefpage}[1]{figure~\ref{#1}, p.~\pageref{#1}}
|
|
\newcommand{\deflabelref}[2]{\texttt{#1}~(page~\pageref{#2})}
|
|
\newcommand{\defref}[1]{\deflabelref{#1}{#1}}
|
|
|
|
\newcommand{\coderef}[1]{figure~\ref{#1}}
|
|
\newcommand{\figref}[1]{figure~\ref{#1}}
|
|
|
|
\newcommand{\secref}[1]{section~\ref{#1}}
|
|
\newcommand{\rnrs}[1]{R$^{\mathrm{#1}}$RS}
|
|
|
|
\newcommand{\BoxedText}[2]{
|
|
\vspace{.05in}
|
|
\begin{center}
|
|
\begin{tabular}{|p{4.6in}|} {\large \emph{#1}} #2 \end{tabular}
|
|
\end{center}
|
|
\vspace{.05in}
|
|
}
|
|
|
|
\newcommand{\testfile}[2]{\texttt{tests-{\ref{#1}}-{#2}.ss}}
|
|
|
|
\newcommand{\idxtt}[1]{\index{#1 @ \texttt{#1}}\texttt{#1}}
|
|
|
|
\newenvironment{Language}
|
|
{
|
|
\begin{center}
|
|
\begin{tabular}{|p{4.5in}|} {\large \emph{Input Language:}}
|
|
\begin{center}
|
|
\begin{tabular}{@{}r@{ }c@{ }l@{}}
|
|
}{
|
|
\end{tabular}
|
|
\end{center}
|
|
\end{tabular}
|
|
\end{center}
|
|
}
|
|
|
|
|
|
\DefineVerbatimEnvironment{CodeInline}{Verbatim}
|
|
{gobble=0, xleftmargin=2em, xrightmargin=0em,
|
|
%numbers=left, numbersep=2mm,
|
|
frame=lines ,framerule=1pt}
|
|
|
|
|
|
|
|
\DefineVerbatimEnvironment{CodeInlineIdx}{Verbatim}
|
|
{gobble=0, xleftmargin=3em, xrightmargin=0em,
|
|
numbers=left, numbersep=1ex,
|
|
frame=lines ,framerule=1pt}
|
|
|
|
\newcommand{\idxlabeldefun}[5]{
|
|
\vspace{1ex}
|
|
\rule{\textwidth}{2pt}
|
|
{\phantomsection\index{#1@\texttt{#2}}\label{#3}{\Large\texttt{#4}}\hfill\textbf{#5}}\\}
|
|
|
|
|
|
\newcommand{\idxdefun}[3]{\idxlabeldefun{#1}{#2}{#1}{#2}{#3}}
|
|
|
|
|
|
\newcommand{\defun}[2]{\idxdefun{#1}{#1}{#2}}
|
|
|
|
\begin{document}
|
|
\frontmatter
|
|
|
|
\VerbatimFootnotes
|
|
|
|
\title{Ikarus Scheme User's Guide}
|
|
|
|
\author{Abdulaziz Ghuloum}
|
|
|
|
\pagestyle{empty}
|
|
|
|
\mbox{}
|
|
\vspace{3in}
|
|
|
|
\newcommand{\fstpagefont}[0]
|
|
{\fontspec{Charis SIL}}
|
|
|
|
{ \fontsize{66}{66} \fstpagefont{}
|
|
\noindent Ikarus Scheme\\ User's Guide\\ }
|
|
\noindent \rule{\textwidth}{6pt}
|
|
{\fontsize{18}{18} \fstpagefont{}
|
|
\hfill{} (Preliminary Document) \hfill Version~0.0.2+ }
|
|
\vfill
|
|
{ \fontsize{24}{24} \fstpagefont{}
|
|
\hfill{} Abdulaziz Ghuloum}
|
|
|
|
{ \fontsize{18}{18} \fstpagefont{}
|
|
\hfill{} \today \\}
|
|
|
|
\newpage
|
|
\mbox{}
|
|
\vfill{}
|
|
%\addcontentsline{toc}{section}{Copyrights}
|
|
\noindent
|
|
Ikarus Scheme User's Guide\\
|
|
Copyright \copyright{} 2007, Abdulaziz Ghuloum\\
|
|
|
|
\noindent
|
|
Permission is granted to copy, distribute and/or modify this
|
|
document under the terms of the GNU Free Documentation License,
|
|
Version 1.2 published by the Free Software
|
|
Foundation; with no Invariant Sections, the Front-Cover Texts
|
|
being \emph{``Ikarus Scheme User's Guide''}, and
|
|
no Back-Cover Texts. A copy of the license is included in the
|
|
section entitled ``GNU Free Documentation License''.
|
|
|
|
\newpage
|
|
|
|
\pagestyle{fancy}
|
|
\phantomsection
|
|
\addcontentsline{toc}{section}{Contents}
|
|
\tableofcontents
|
|
|
|
\newpage
|
|
|
|
\mainmatter
|
|
\setlength{\parindent}{0pt}
|
|
\setlength{\parskip}{2.0ex plus 0ex minus 0ex}
|
|
\chapter{Getting Started}
|
|
\section{Introduction}
|
|
|
|
Ikarus Scheme is an implementation of the Scheme programming
|
|
language. The preliminary release of Ikarus implements the majority
|
|
of the features found in the current standard, the
|
|
Revised$^\mathrm{6}$ report on the algorithmic language
|
|
Scheme\cite{r6rs} including full \rnrs{6} library and script syntax,
|
|
syntax-case, unicode strings, bytevectors, user-defined record
|
|
types, exception handling, conditions, and enumerations. Over 90\%
|
|
of the \rnrs{6} procedures and keywords are currently implemented
|
|
and subsequent releases will proceed towards brining Ikarus to full
|
|
\rnrs{6} conformance.
|
|
|
|
The main purpose behind releasing Ikarus early is to give Scheme
|
|
programmers the opportunity to experiment with the various new
|
|
features that were newly introduced in \rnrs{6}. The most important
|
|
of such features is the ability to structure large programs into
|
|
libraries; where each library extends the language through
|
|
procedural and syntactic abstractions. Many useful libraries can be
|
|
written using the currently supported set of \rnrs{6} features
|
|
including text processing tools, symbolic logic systems,
|
|
interpreters and compilers, and many mathematical and scientific
|
|
packages. It is my hope that this release will encourage the
|
|
Scheme community to write and to share their most useful \rnrs{6}
|
|
libraries.
|
|
|
|
|
|
\newpage
|
|
|
|
\section{Technology overview}
|
|
|
|
Ikarus Scheme provides the programmer with many advantages:
|
|
|
|
\textbf{Optimizing code generator:} The compiler's backend employs
|
|
state of the art technologies in code generation that produce fast
|
|
efficient machine code. When developing computationally intensive
|
|
programs, one is not constrained by using a slow interpreter.
|
|
|
|
\textbf{Fast incremental compilation:} Every library and script is
|
|
quickly compiled to native machine code. When developing large
|
|
software, one is not constrained by how slow the batch compiler
|
|
runs.
|
|
|
|
\textbf{Robust and fine-tuned standard libraries:} The standard
|
|
libraries are written such that they perform as much error checking
|
|
as required to provide a safe and fast runtime environment.
|
|
|
|
\textbf{Multi-generational garbage collector:} The
|
|
BiBOP\cite{dybvig:sm} based garbage collector used in Ikarus allows
|
|
the runtime system to expand its memory footprint as needed. The
|
|
entire 32-bit virtual address space could be used and unneeded
|
|
memory is released back to the operating system.
|
|
|
|
\textbf{Supports many operating systems:} Ikarus runs on the most
|
|
popular and widely used operating systems for servers and personal
|
|
computers. The supported systems include Mac~OS~X,
|
|
GNU/Linux, FreeBSD, NetBSD, and Microsoft Windows.
|
|
|
|
|
|
\section{System requirements}
|
|
|
|
\subsection{Hardware}
|
|
|
|
Ikarus Scheme runs on the IA-32 (\emph{x86}) architecture
|
|
supporting SSE2 extensions. This includes the Athlon 64,
|
|
Sempron 64, and Turion 64 processors from AMD and the Pentium 4, Xeon,
|
|
Celeron, Pentium M, Core, and Core2 processors from Intel. The
|
|
system does not run on Intel Pentium III or earlier
|
|
processors.
|
|
|
|
The Ikarus compiler generates SSE2 instructions to handle Scheme's
|
|
IEEE floating point representation (\emph{flonums}) for inexact
|
|
numbers.
|
|
|
|
\subsection{Operating systems}
|
|
|
|
Ikarus is tested under the following operating systems:
|
|
|
|
\begin{itemize}
|
|
\item Mac OS X version 10.4.
|
|
\item Linux 2.6.18 (Debian, Fedora, Gentoo, and Ubuntu).
|
|
\item FreeBSD version 6.2.
|
|
\item NetBSD version 3.1.
|
|
\item Microsoft Windows XP (using Cygwin 1.5.24).
|
|
\end{itemize}
|
|
|
|
\subsection{Additional software}
|
|
|
|
\begin{itemize}
|
|
\item\textbf{GMP:} Ikarus uses the GNU Multiple Precision Arithmetic
|
|
Library (GMP) for some bignum arithmetic operations. To build
|
|
Ikarus from scratch, GMP version 4.2 or better must be installed
|
|
along with the required header files. Pre-built GMP packages are
|
|
available for most operating systems. Alternatively, GMP can be
|
|
downloaded from \\
|
|
\url{http://gmplib.org/}.
|
|
|
|
\BoxedText{Note:}{Ikarus runs in 32-bit mode only.
|
|
To run it in 64-bit environments, you will have to obtain the 32-bit
|
|
version of GMP, or compile it yourself after adding \texttt{ABI=32}
|
|
to its configuration options.}
|
|
|
|
|
|
\item\textbf{GCC:} The GNU C Compiler is required to build the Ikarus
|
|
executable (e.g. the garbage collector, loader, and OS-related
|
|
runtime). GCC versions 4.1 and 4.2 were successfully used to build
|
|
Ikarus.
|
|
|
|
\item\textbf{Autoconf and Automake:} The GNU Autoconf (version 2.61)
|
|
and GNU Automake (version 1.10) tools are required if one
|
|
wishes to modify the Ikarus source base. They are not
|
|
required to build the official release of Ikarus.
|
|
|
|
\item\textbf{\XeLaTeX{}:} The \XeLaTeX\ typesetting system is
|
|
required for building the documentation. \XeLaTeX\ (and \XeTeX) is
|
|
an implementation of the \LaTeX\ (and \TeX) typesetting system.
|
|
\XeLaTeX\ can be obtained from \url{http://scripts.sil.org/xetex}
|
|
and is included with \TeX-Live\footnote{
|
|
\url{http://tug.org/texlive/}} and and
|
|
Mac-\TeX\footnote{\url{http://tug.org/mactex/}} distributions.
|
|
|
|
|
|
\end{itemize}
|
|
|
|
\section{Installation}
|
|
|
|
If you are familiar with installing Unix software on your system,
|
|
then all you need to know is that Ikarus uses the standard
|
|
installation method found in most other Unix software. Simply run
|
|
the following commands from the shell:
|
|
\begin{verbatim}
|
|
$ tar -zxf ikarus-n.n.n.tar.gz
|
|
$ cd ikarus-n.n.n
|
|
$ ./configure [--prefix=path] [CFLAGS=-I/dir] [LDFLAGS=-L/dir]
|
|
$ make
|
|
$ make install
|
|
$
|
|
\end{verbatim}
|
|
|
|
The rest of this section describes the build process in more
|
|
details. It is targeted to users who are unfamiliar with steps
|
|
mentioned above.
|
|
|
|
\subsection{Installation details}
|
|
|
|
\begin{enumerate}
|
|
|
|
\item Download the Ikarus source distribution. The source is
|
|
distributed as a \texttt{gzip}-compressed \texttt{tar} file
|
|
(\texttt{ikarus-n.n.n.tar.gz} where \texttt{n.n.n} is a 3-digit
|
|
number indicating the current revision). The latest revision can be
|
|
downloaded from the following URL:\\
|
|
\url{http://www.cs.indiana.edu/~aghuloum/ikarus/}
|
|
|
|
\item Unpack the source distribution package. From your shell
|
|
command, type:
|
|
\begin{verbatim}
|
|
$ tar -zxf ikarus-n.n.n.tar.gz
|
|
$
|
|
\end{verbatim}
|
|
This creates the base directory \texttt{ikarus-n.n.n}.
|
|
|
|
\item Configure the build system by running the \texttt{configure}
|
|
script located in the base directory. To do this, type the
|
|
following commands:
|
|
\begin{verbatim}
|
|
$ cd ikarus-n.n.n
|
|
$ ./configure
|
|
checking build system type... i386-apple-darwin8.10.1
|
|
checking host system type... i386-apple-darwin8.10.1
|
|
...
|
|
configure: creating ./config.status
|
|
config.status: creating Makefile
|
|
config.status: creating src/Makefile
|
|
config.status: creating scheme/Makefile
|
|
config.status: creating doc/Makefile
|
|
config.status: executing depfiles commands
|
|
$
|
|
\end{verbatim}
|
|
|
|
This configures the system to be built then installed in the
|
|
system-wide location (binaries are installed in
|
|
\texttt{/usr/local/bin}) . If you wish to install it
|
|
in another location (e.g. in your home directory), you can supply
|
|
a \texttt{--prefix} location to the \texttt{configure} script as
|
|
follows:
|
|
|
|
\begin{verbatim}
|
|
$ ./configure --prefix=/path/to/installation/location
|
|
\end{verbatim}
|
|
|
|
The \texttt{configure} script will fail if it cannot locate the
|
|
location where GMP is installed. If running \texttt{configure}
|
|
fails to locate GMP, you should supply the location in which the GMP
|
|
header file, \texttt{gmp.h}, and the GMP library file,
|
|
\texttt{libgmp.so}, are installed. This is done by supplying the
|
|
two paths in the \texttt{CFLAGS} and \texttt{LDFLAGS} arguments:
|
|
|
|
\begin{verbatim}
|
|
$ ./configure CFLAGS=-I/path/to/include LDFLAGS=-L/path/to/lib
|
|
\end{verbatim}
|
|
|
|
\item Build the system by running:
|
|
\begin{verbatim}
|
|
$ make
|
|
\end{verbatim}
|
|
This performs two
|
|
tasks. First, it builds the \texttt{ikarus} executable from the C
|
|
files located in the \texttt{src} directory. It then uses the
|
|
\texttt{ikarus} executable and the pre-built
|
|
\texttt{ikarus.boot.orig} boot file to rebuild the Scheme boot image
|
|
file \texttt{ikarus.boot} from the Scheme sources located in the
|
|
\texttt{scheme} directory.
|
|
|
|
\item Install Ikarus by typing:
|
|
\begin{verbatim}
|
|
$ make install
|
|
\end{verbatim}
|
|
If you are installing Ikarus in a system-wide location, you might
|
|
need to have administrator privileges (use the \texttt{sudo} or
|
|
\texttt{su} commands).
|
|
|
|
\item Test that Ikarus runs from the command line.
|
|
\begin{verbatim}
|
|
$ ikarus
|
|
Ikarus Scheme version 0.0.2
|
|
Copyright (c) 2006-2007 Abdulaziz Ghuloum
|
|
|
|
>
|
|
\end{verbatim}
|
|
If you get the prompt, then Ikarus was successfully installed on
|
|
your system. You may need to update the \texttt{PATH} variable in
|
|
your environment to contain the directory in which the
|
|
\texttt{ikarus} executable was installed.
|
|
|
|
Do not delete the \texttt{ikarus-n.n.n} directory from which you
|
|
configured, built, and installed Ikarus. It will be needed if you
|
|
decide at a later time to uninstall Ikarus.
|
|
|
|
\end{enumerate}
|
|
|
|
\subsection{Uninstalling Ikarus}
|
|
|
|
To uninstall Ikarus, use the following steps:
|
|
|
|
\begin{verbatim}
|
|
$ cd path/to/ikarus-n.n.n
|
|
$ make uninstall
|
|
$
|
|
\end{verbatim}
|
|
|
|
|
|
\section{\index{Command-line switches}Command-line switches}
|
|
|
|
The \texttt{ikarus} executable recognizes a few command-line
|
|
switches that influence how Ikarus starts.
|
|
|
|
\begin{itemize}
|
|
|
|
\item \texttt{ikarus -h}
|
|
|
|
The presence of the \texttt{-h} flag causes \texttt{ikarus} to
|
|
display a help message then exits. The help message summarizes the
|
|
command-line switches. No further action is performed.
|
|
|
|
\item \texttt{ikarus -b path/to/boot/file.boot}
|
|
|
|
The \texttt{-b} flag (which requires an extra argument) directs
|
|
\texttt{ikarus} to use the specified boot file as the initial system
|
|
boot file. \index{Boot files} The boot file is a binary file that
|
|
contains all the code and data of the Scheme system. In the absence
|
|
of \texttt{-b} flag, the executable will use the default boot file.
|
|
Running \texttt{ikarus~-h} shows the location where the default boot
|
|
file was installed.
|
|
|
|
The rest of the command-line arguments are recognized by the
|
|
standard Scheme run time system. They are processed after the
|
|
boot file is loaded.
|
|
|
|
\item \texttt{ikarus --r6rs-script script-file-name [arguments ...]}
|
|
|
|
\index{R6RS Script@\rnrs{6} Script} The \texttt{--r6rs-script} argument
|
|
instructs Ikarus that the supplied file is an \rnrs{6} script. See
|
|
Section~\ref{sec:scripts} for a short introduction to writing \rnrs{6}
|
|
scripts. The script file name and any additional optional
|
|
\texttt{arguments}
|
|
can be obtained by calling the
|
|
\idxtt{command-line} procedure.
|
|
|
|
\begin{verbatim}
|
|
$ cat test.ss
|
|
(import (rnrs))
|
|
(write (command-line))
|
|
(newline)
|
|
|
|
$ ikarus --r6rs-script test.ss hi there
|
|
("test.ss" "hi" "there")
|
|
$
|
|
\end{verbatim}
|
|
|
|
\item \texttt{ikarus files ... [-- arguments ...]}
|
|
|
|
The lack of an \texttt{--r6rs-script} argument causes Ikarus to
|
|
start in interactive mode. Each of the \texttt{files} is first
|
|
loaded, in the interaction environment. The interaction environment
|
|
initially contains all the bindings exported from the
|
|
\texttt{(ikarus)} library (see Chapter~\ref{chapter:ikarus}). The
|
|
optional \texttt{arguments} following the \texttt{--} marker can be
|
|
obtained by calling the \texttt{command-line} procedure. In
|
|
interactive mode, the first element of the returned list will be the
|
|
string \texttt{"*interactive*"}, corresponding to the script name in
|
|
\rnrs{6}-script mode.
|
|
|
|
|
|
\BoxedText{Note:}{The interactive mode is intended for quickly
|
|
experimenting with the built-in features. It is intended neither
|
|
for developing applications nor for writing any substantial pieces
|
|
of code. The main reason for this is that the interaction between
|
|
\rnrs{6} libraries and the interactive environment is not well
|
|
understood. We hope to achieve better interaction between the two
|
|
subsystems in the future.}
|
|
|
|
\end{itemize}
|
|
|
|
\section{Using \texttt{scheme-script}}
|
|
|
|
Scheme scripts can be executed using the
|
|
\texttt{ikarus~--r6rs-script~\textit{script-name}} command as
|
|
described in the previous section. For convenience, Ikarus
|
|
follows the \rnrs{6} recommendations and installs a wrapper program
|
|
called \texttt{scheme-script}. Typically, a script you write would
|
|
start with a \texttt{\#!}\ line that directs your operating system
|
|
to the interpreter used to evaluate the script file. The following
|
|
example shows a very simple script that uses the
|
|
\texttt{scheme-script} command.
|
|
|
|
\begin{CodeInline}
|
|
#!/usr/bin/env scheme-script
|
|
|
|
(import (rnrs))
|
|
(display "Hello World\n")
|
|
\end{CodeInline}
|
|
|
|
If the above script was placed in a file called
|
|
\texttt{hello-world}, then one can make it executable using the
|
|
\texttt{chmod} Unix command.
|
|
|
|
\begin{verbatim}
|
|
$ cat hello-world
|
|
#!/usr/bin/env scheme-script
|
|
|
|
(import (rnrs))
|
|
(display "Hello World\n")
|
|
|
|
$ chmod 755 hello-world
|
|
$ ./hello-world
|
|
Hello World
|
|
$
|
|
\end{verbatim}
|
|
|
|
\BoxedText{Under Mac OS X,}{if a script name ends with the
|
|
\texttt{.command} extension, then it can be executed from the Finder
|
|
by double-clicking on it. This brings up a terminal window in which
|
|
the script is executed. The \texttt{.command} extension can be
|
|
hidden from the \emph{Get Info} item from the Finder's File menu.}
|
|
|
|
\newpage
|
|
|
|
\section{Mapping library names to file names}
|
|
|
|
The name of an \rnrs{6} library consists of a non-empty list of
|
|
identifiers (symbols), followed by an optional version number. All
|
|
of the standard \rnrs{6} libraries are built into Ikarus, thus
|
|
importing any one of them does not require any special action other
|
|
than listing the library name in the \texttt{import} part of a
|
|
library or a script. The same holds for the \texttt{(ikarus)}
|
|
library (chapter~\ref{chapter:ikarus},
|
|
page~\pageref{chapter:ikarus}).
|
|
|
|
When writing a new library to a file, Ikarus uses a simple mechanism
|
|
to map library names to file names. A library name is converted to
|
|
a file path by joining the library identifiers with a path
|
|
separator, e.g. \verb|"/"|, and appending the \emph{scheme source},
|
|
e.g. \verb|".ss"|, suffix at the end.
|
|
|
|
\begin{center}
|
|
\begin{tabular}{lcl}
|
|
Library Name & \hspace{2em}$\Rightarrow$\hspace{2em} & File path \\
|
|
\hline
|
|
\verb|(foo)| & $\Rightarrow$ & \verb|foo.ss| \\
|
|
\verb|(foo bar)| & $\Rightarrow$ & \verb|foo/bar.ss| \\
|
|
\verb|(foo bar baz)| & $\Rightarrow$ & \verb|foo/bar/baz.ss|
|
|
\end{tabular}
|
|
\end{center}
|
|
|
|
Having mapped a library name to a file path, Ikarus attempts to
|
|
locate that file in one of several locations. First, Ikarus
|
|
attempts to locate the file in the current working directory from
|
|
which Ikarus was invoked. If the file is not found in the current
|
|
directory, Ikarus tries to find it in the Ikarus library directory.
|
|
The Ikarus library directory is determined when Ikarus is installed
|
|
(based on the \texttt{--prefix} argument that was passed to the
|
|
\texttt{configure} script). If Ikarus failes to locate the library
|
|
file, it raises an exception and exits.
|
|
See Chapter~\ref{chapter:contributed} for more details about the
|
|
library locations.
|
|
|
|
|
|
\BoxedText{Tip:}{Use simple library names for the libraries that
|
|
you define. Library names that contain non-printable characters,
|
|
complex punctuations, or unicode may pose a challenge for some
|
|
operating systems. If Ikarus cannot find a library, it will raise
|
|
an error listing the locations in which it looked, helping you move
|
|
the library file to a place where Ikarus can find it.}
|
|
|
|
\chapter{\rnrs{6} Crash Course}
|
|
|
|
The major difference between \rnrs{5} and \rnrs{6} is the way
|
|
in which programs are loaded and evaluated.
|
|
|
|
In \rnrs{5}, Scheme implementations typically start as an
|
|
interactive session (often referred to as the REPL, or
|
|
read-eval-print-loop). Inside the interactive session, the user
|
|
enters definitions and expressions one at a time using the keyboard.
|
|
Files, which also contain definitions and expressions, can be loaded
|
|
and reloaded by calling the \texttt{load} procedure. The
|
|
environment in which the interactive session starts often contains
|
|
implementation-specific bindings that are not found \rnrs{5} and
|
|
users may redefine any of the initial bindings. The semantics of
|
|
loading a file depends on the state of the environment at the time
|
|
the file contents are evaluated.
|
|
|
|
\index{R6RS Script@\rnrs{6} Script!Import}
|
|
%
|
|
\rnrs{6} differs from \rnrs{5} in that it specifies how \emph{whole
|
|
programs}, or scripts, are compiled and evaluated. An \rnrs{6}
|
|
script is closed in the sense that all the identifiers found in the
|
|
body of the script must either be defined in the script or imported
|
|
from a library. \rnrs{6} also specifies how \emph{libraries} can be
|
|
defined and used. While files in \rnrs{5} are typically
|
|
\emph{loaded} imperatively into the top-level environments, \rnrs{6}
|
|
libraries are \emph{imported} declaratively in scripts and in other
|
|
\rnrs{6} libraries.
|
|
|
|
\section{\label{sec:scripts}Writing a simple script}
|
|
|
|
An \rnrs{6} script is a set of definitions and expressions preceded
|
|
by an \texttt{import} form. The \texttt{import} form specifies
|
|
the language (i.e. the variable and keyword bindings) in which the
|
|
library body is written. A very simple example of an \rnrs{6}
|
|
script is listed below.
|
|
|
|
\index{Examples!Hello World}
|
|
\begin{CodeInline}
|
|
#!/usr/bin/env scheme-script
|
|
(import (rnrs))
|
|
(display "Hello World!\n")
|
|
\end{CodeInline}
|
|
|
|
The first line imports the \texttt{(rnrs)} library. All the
|
|
bindings exported from the \texttt{(rnrs)} library are made
|
|
available to be used within the body of the script.
|
|
The exports of the \texttt{(rnrs)} library include variables
|
|
(e.g. \texttt{cons}, \texttt{car}, \texttt{display}, etc.) and
|
|
keywords (e.g. \texttt{define}, \texttt{lambda}, \texttt{quote},
|
|
etc.). The second line displays the string \texttt{Hello World!}
|
|
followed by a new line character.
|
|
|
|
In addition to expressions, such as the call to \texttt{display} in
|
|
the previous example, a script may define some variables. The
|
|
script below defines the variable \texttt{greeting} and calls the
|
|
procedure bound to it.
|
|
|
|
\begin{CodeInline}
|
|
#!/usr/bin/env scheme-script
|
|
(import (rnrs))
|
|
|
|
(define greeting
|
|
(lambda ()
|
|
(display "Hello World!\n")))
|
|
|
|
(greeting)
|
|
\end{CodeInline}
|
|
|
|
Additional keywords may be defined within a script. In the example
|
|
below, we define the \texttt{(do-times n exprs ...)} macro that
|
|
evaluates the expressions \texttt{exprs} \texttt{n} times. Running
|
|
the script displays \texttt{Hello World} 3 times.
|
|
\newpage
|
|
|
|
\begin{CodeInline}
|
|
#!/usr/bin/env scheme-script
|
|
(import (rnrs))
|
|
|
|
(define greeting
|
|
(lambda ()
|
|
(display "Hello World!\n")))
|
|
|
|
(define-syntax do-times
|
|
(syntax-rules ()
|
|
[(_ n exprs ...)
|
|
(let f ([i n])
|
|
(unless (zero? i)
|
|
exprs ...
|
|
(f (- i 1))))]))
|
|
|
|
(do-times 3 (greeting))
|
|
\end{CodeInline}
|
|
|
|
|
|
\section{Writing simple libraries}
|
|
|
|
A script is intended to be a small piece of the program---useful
|
|
abstractions belong to libraries. The \texttt{do-times} macro that
|
|
was defined in the previous section may be useful in places other
|
|
than printing greeting messages. So, we can create a small library,
|
|
\texttt{(iterations)} that contains common iteration forms.
|
|
|
|
An \rnrs{6} library form is made of four essential parts: (1) the
|
|
library name, (2) the set of identifiers that the library exports,
|
|
(3) the set of libraries that the library imports, and (4) the body
|
|
of the library.
|
|
|
|
|
|
The library name can be any non-empty list of identifiers.
|
|
\rnrs{6}-defined libraries includes \texttt{(rnrs)},
|
|
\texttt{(rnrs~unicode)}, \texttt{(rnrs~bytevectors)}, and so on.
|
|
|
|
The library exports are a set of identifiers that are made available
|
|
to importing libraries. Every exported identifier must be bound: it
|
|
may either be defined in the library or imported using the
|
|
\texttt{import} form. Library exports include variables, keywords,
|
|
record names, and condition names.
|
|
|
|
Library imports are similar to script imports: they specify the set
|
|
of libraries whose exports are made visible within the body of the
|
|
library.
|
|
|
|
\index{Invoke}
|
|
The body of a library contains definitions (variable, keyword,
|
|
record, condition, etc.) followed by an optional set of expressions.
|
|
The expressions are evaluated for side effect when needed.
|
|
|
|
|
|
The \texttt{(iteration)} library may be written as follows:
|
|
|
|
\begin{CodeInline}
|
|
(library (iteration)
|
|
(export do-times)
|
|
(import (rnrs))
|
|
|
|
(define-syntax do-times
|
|
(syntax-rules ()
|
|
[(_ n exprs ...)
|
|
(let f ([i n])
|
|
(unless (zero? i)
|
|
exprs ...
|
|
(f (- i 1))))])))
|
|
\end{CodeInline}
|
|
|
|
To use the \texttt{(iteration)} library in our script, we add the
|
|
name of the library to the script's \texttt{import} form. This
|
|
makes all of \texttt{(iteration)}'s exported identifiers, e.g.
|
|
\texttt{do-times}, visible in the body of the script.
|
|
|
|
\begin{CodeInline}
|
|
#!/usr/bin/env scheme-script
|
|
(import (rnrs) (iteration))
|
|
|
|
(define greeting
|
|
(lambda ()
|
|
(display "Hello World!\n")))
|
|
|
|
(do-times 3 (greeting))
|
|
\end{CodeInline}
|
|
|
|
\section{\rnrs{6} record types}
|
|
|
|
\rnrs{6} provides ways for users to define new types, called record
|
|
types. A record is a fixed-size data structure with a unique type
|
|
(called a record type). A record may have any finite number of
|
|
fields that hold arbitrary values. This section briefly describes
|
|
what we expect to be the most commonly used features of the record
|
|
system. Full details are in the \rnrs{6} Standard Libraries
|
|
document\cite{r6rs:lib}.
|
|
|
|
\subsection{Defining new record types}
|
|
|
|
To define a new record type, use the \texttt{define-record-type}
|
|
form. For example, suppose we want to define a new record type for
|
|
describing points, where a point is a data structure that has two
|
|
fields to hold the point's $x$ and $y$ coordinates. The following
|
|
definition achieves just that:
|
|
|
|
\begin{CodeInline}
|
|
(define-record-type point
|
|
(fields x y))
|
|
\end{CodeInline}
|
|
|
|
The above use of \texttt{define-record-type} defines the following
|
|
procedures automatically for you:
|
|
\begin{itemize}
|
|
\item The constructor \texttt{make-point} that takes two arguments,
|
|
\texttt{x} and \texttt{y} and returns a new record whose type is
|
|
point.
|
|
\item The predicate \texttt{point?}\ that takes an arbitrary value
|
|
and returns \texttt{\#t} if that value is a point, \texttt{\#f}
|
|
otherwise.
|
|
\item The accessors \texttt{point-x} and \texttt{point-y} that,
|
|
given a record of type point, return the value stored in the
|
|
\texttt{x} and \texttt{y} fields.
|
|
\end{itemize}
|
|
|
|
Both the \texttt{x} and \texttt{y} fields of the \texttt{point}
|
|
record type are \emph{immutable}, meaning that once a record is
|
|
created with specific \texttt{x} and \texttt{y} values, they cannot
|
|
be changed later. If you want the fields to be \emph{mutable}, then
|
|
you need to specify that explicitly as in the following example.
|
|
\newpage
|
|
|
|
\begin{CodeInline}
|
|
(define-record-type point
|
|
(fields (mutable x) (mutable y)))
|
|
\end{CodeInline}
|
|
|
|
This definition gives us, in addition to the constructor, predicate,
|
|
and accessors, two additional procedures:
|
|
\begin{itemize}
|
|
\item The mutators \texttt{point-x-set!} and \texttt{point-y-set!} that,
|
|
given a record of type point, and a new value, sets the value stored in the
|
|
\texttt{x} field or \texttt{y} field to the new value.
|
|
\end{itemize}
|
|
|
|
|
|
\BoxedText{Note:}{Records in Ikarus have a printable representation
|
|
in order to enable debugging programs that use records. Records are
|
|
printed in the \texttt{\#[type-name field-values ...]} notation.
|
|
For example, \texttt{(write (make-point 1 2))} produces
|
|
\texttt{\#[point 1 2]}.}
|
|
|
|
\subsection{Extending existing record types}
|
|
|
|
A record type may be extended by defining new variants of a record
|
|
with additional fields. In our running example, suppose we want
|
|
to define a \texttt{colored-point} record type that, in addition to
|
|
being a \texttt{point}, it has an additional field: a \emph{color}.
|
|
A simple way of achieving that is by using the following record
|
|
definition:
|
|
|
|
\begin{CodeInline}
|
|
(define-record-type cpoint
|
|
(parent point)
|
|
(fields color))
|
|
\end{CodeInline}
|
|
|
|
Here, the definition of \texttt{cpoint} gives us:
|
|
\begin{itemize}
|
|
\item A constructor \texttt{make-cpoint} that takes three arguments
|
|
(\texttt{x}, \texttt{y}, and \texttt{color} in that order) and returns a
|
|
\texttt{cpoint} record.
|
|
\item A predicate \texttt{cpoint?}\ that takes a single argument and
|
|
determines whether the argument is a \texttt{cpoint} record.
|
|
\item An accessor \texttt{cpoint-color} that returns the value of
|
|
the \texttt{color} field of a \texttt{cpoint} object.
|
|
\end{itemize}
|
|
|
|
All procedures that are applicable to records of type
|
|
\texttt{point} (\texttt{point?}, \texttt{point-x},
|
|
\texttt{point-y}) are also applicable to records of type
|
|
\texttt{cpoint} since a \texttt{cpoint} is also a \texttt{point}.
|
|
|
|
\subsection{Specifying custom constructors}
|
|
|
|
The record type definitions explained so far use the default
|
|
constructor that takes as many arguments as there are fields and
|
|
returns a new record type with the values of the fields initialized
|
|
to the arguments' values. It is sometimes necessary or convenient
|
|
to provide a constructor that performs more than the default
|
|
constructor. For example, we can modify the definition of our
|
|
\texttt{point} record so that the constructor takes either
|
|
no arguments, in which case it would return a point located at the
|
|
origin, or two arguments specifying the $x$ and $y$ coordinates. We
|
|
use the \texttt{protocol} keyword for specifying such constructor as
|
|
in the following example:
|
|
|
|
\begin{CodeInline}
|
|
(define-record-type point
|
|
(fields x y)
|
|
(protocol
|
|
(lambda (new)
|
|
(case-lambda
|
|
[(x y) (new x y)]
|
|
[() (new 0 0)]))))
|
|
\end{CodeInline}
|
|
|
|
The protocol here is a procedure that takes a constructor procedure
|
|
\texttt{new} (\texttt{new} takes as many arguments as there are
|
|
fields.) and returns the desired custom constructor that we want
|
|
(The actual constructor will be the value of the
|
|
\texttt{case-lambda} expression in the example above).
|
|
Now the constructor \texttt{make-point} would either take two
|
|
arguments which constructs a \texttt{point} record as before, or no
|
|
arguments, in which case \texttt{(new 0 0)} is called to construct a
|
|
point at the origin.
|
|
|
|
Another reason why one might want to use custom constructors is to
|
|
precompute the initial values of some fields based on the values of
|
|
other fields. An example of this case is adding a \texttt{distance}
|
|
field to the record type which is computed as
|
|
$d = \sqrt{x^2+y^2}$. The protocol in this case may be defined as:
|
|
|
|
\begin{CodeInline}
|
|
(define-record-type point
|
|
(fields x y distance)
|
|
(protocol
|
|
(lambda (new)
|
|
(lambda (x y)
|
|
(new x y (sqrt (+ (expt x 2) (expt y 2))))))))
|
|
\end{CodeInline}
|
|
|
|
Note that derived record types need not be modified when additional
|
|
fields are added to the parent record type. For example, our
|
|
\texttt{cpoint} record type still works unmodified even after we
|
|
added the new \texttt{distance} field to the parent.
|
|
Calling \texttt{(point-distance (make-cpoint 3 4 \#xFF0000))}
|
|
returns \texttt{5.0} as expected.
|
|
|
|
\subsection{Custom constructors for derived record types}
|
|
|
|
Just like how base record types (e.g. \texttt{point} in the running
|
|
example) may have a custom constructor, derived record types can
|
|
also have custom constructors that do other actions. Suppose that
|
|
you want to construct \texttt{cpoint} records using an optional
|
|
color that, if not supplied, defaults to the value 0. To do so, we
|
|
supply a \texttt{protocol} argument to \texttt{define-record-type}.
|
|
The only difference here is that the procedure \texttt{new} is a
|
|
\emph{curried} constructor. It first takes as many arguments as the
|
|
constructor of the parent record type, and returns a procedure that
|
|
takes the initial values of the new fields.
|
|
|
|
In our example, the constructor for the \texttt{point} record type
|
|
takes two arguments. \texttt{cpoint} extends \texttt{point} with
|
|
one new field. Therefore, \texttt{new} in the definition below
|
|
first takes the arguments for \texttt{point}'s constructor, then
|
|
takes the initial color value. The definition below shows how the
|
|
custom constructor may be defined.
|
|
|
|
\begin{CodeInline}
|
|
(define-record-type cpoint
|
|
(parent point)
|
|
(fields color)
|
|
(protocol
|
|
(lambda (new)
|
|
(case-lambda
|
|
[(x y c) ((new x y) c)]
|
|
[(x y) ((new x y) 0)]))))
|
|
\end{CodeInline}
|
|
|
|
|
|
\section{Exception handling}
|
|
|
|
The procedure \texttt{with-exception-handler} allows the programmer
|
|
to specify how to handle exceptional situations. It takes two
|
|
procedures as arguments:
|
|
\begin{itemize}
|
|
\item An exception handler which is a procedure that takes a
|
|
single argument, the object that was raised.
|
|
\item A body thunk which is a procedure with no arguments whose body
|
|
is evaluated with the exception handler installed.
|
|
\end{itemize}
|
|
|
|
In addition to installing exception handlers, \rnrs{6} provides two
|
|
ways of raising exceptions: \texttt{raise} and
|
|
\texttt{raise-continuable}. We describe the
|
|
\texttt{raise-continuable} procedure
|
|
first since it's the simpler of the two.
|
|
For the code below, assume that \texttt{print} is defined as:
|
|
\begin{CodeInline}
|
|
(define (print who obj)
|
|
(display who)
|
|
(display ": ")
|
|
(display obj)
|
|
(newline))
|
|
\end{CodeInline}
|
|
|
|
The first example, below, shows how a simple exception handler is
|
|
installed. Here, the exception handler prints the object it
|
|
receives and returns the symbol \texttt{there}. The call to
|
|
\texttt{raise-continuable} calls the exception handler, passing it
|
|
the symbol \texttt{here}. When the handler returns, the returned
|
|
value becomes the value of the call to \texttt{raise-continuable}.
|
|
|
|
\begin{CodeInline}
|
|
(with-exception-handler
|
|
(lambda (obj) ;;; prints
|
|
(print "handling" obj) ;;; handling: here
|
|
'there) ;;; returned: there
|
|
(lambda ()
|
|
(print "returned" (raise-continuable 'here))))
|
|
\end{CodeInline}
|
|
|
|
Exceptional handlers may nest, and in that case, if an exception is
|
|
raised while evaluating an inner handler, the outer handler is
|
|
called as the following example illustrates:
|
|
|
|
\begin{CodeInline}
|
|
(with-exception-handler
|
|
(lambda (obj) ;;; prints
|
|
(print "outer" obj) ;;; inner: here
|
|
'outer) ;;; outer: there
|
|
(lambda () ;;; returned: outer
|
|
(with-exception-handler
|
|
(lambda (obj)
|
|
(print "inner" obj)
|
|
(raise-continuable 'there))
|
|
(lambda ()
|
|
(print "returned" (raise-continuable 'here))))))
|
|
\end{CodeInline}
|
|
|
|
In short, \texttt{with-exception-handler} binds an exception handler
|
|
within the dynamic context of evaluating the thunk, and
|
|
\texttt{raise-continuable} calls it.
|
|
|
|
The procedure \texttt{raise} is similar to
|
|
\texttt{raise-continuable} except that if the handler returns, a new
|
|
exception is raised, calling the next handler in sequence until the
|
|
list of handlers is exhausted.
|
|
|
|
\begin{CodeInline}
|
|
(call/cc ;;; prints
|
|
(lambda (escape) ;;; inner: here
|
|
(with-exception-handler ;;; outer: #[condition ---]
|
|
(lambda (obj) ;;; returns
|
|
(print "outer" obj) ;;; 12
|
|
(escape 12))
|
|
(lambda ()
|
|
(with-exception-handler
|
|
(lambda (obj)
|
|
(print "inner" obj)
|
|
'there)
|
|
(lambda ()
|
|
(print "returned" (raise 'here))))))))
|
|
\end{CodeInline}
|
|
|
|
Here, the call to \texttt{raise} calls the inner exception handler,
|
|
which returns, causing \texttt{raise} to re-raise a non-continuable
|
|
exception to the outer exception handler. The outer exception
|
|
handler then calls the escape continuation.
|
|
|
|
The following procedure provides a useful example of using the
|
|
exception handling mechanism. Consider a simple definition of the
|
|
procedure \texttt{configuration-option} which returns the value
|
|
associated with a key where the key/value pairs are stored in an
|
|
association list in a configuration file.
|
|
|
|
\begin{CodeInline}
|
|
(define (configuration-option filename key)
|
|
(cdr (assq key (call-with-input-file filename read))))
|
|
\end{CodeInline}
|
|
|
|
Possible things may go wrong with calling
|
|
\texttt{configuration-option} including errors opening the file,
|
|
errors reading from the file (file may be corrupt), error in
|
|
\texttt{assq} since what's read may not be an association list, and
|
|
error in \texttt{cdr} since the key may not be in the association
|
|
list. Handling all error possibilities is tedious and error prone.
|
|
Exceptions provide a clean way of solving the problem. Instead of
|
|
guarding against all possible errors, we install a handler that
|
|
suppresses all errors and returns a default value if things go
|
|
wrong. Error handling for \texttt{configuration-option} may be
|
|
added as follows:
|
|
|
|
\begin{CodeInline}
|
|
(define (configuration-option filename key default)
|
|
(define (getopt)
|
|
(cdr (assq key (call-with-input-file filename read))))
|
|
(call/cc
|
|
(lambda (k)
|
|
(with-exception-handler
|
|
(lambda (_) (k default))
|
|
getopt))))
|
|
\end{CodeInline}
|
|
|
|
|
|
\chapter{\label{chapter:ikarus}The \texttt{(ikarus)} library}
|
|
|
|
In addition to the libraries listed in the \rnrs{6} standard, Ikarus
|
|
contains the \texttt{(ikarus)} library which provides additional
|
|
useful features. The \texttt{(ikarus)} library is a composite
|
|
library---it exports a superset of all the supported bindings of
|
|
\rnrs{6}. While not all of the exports of \texttt{(ikarus)} are
|
|
documented at this time, this chapter attempts to describe a few of
|
|
these useful extensions. Extansions to Scheme's lexical syntax are
|
|
also documented.
|
|
|
|
\idxlabeldefun{\#"!ikarus}{\#"!ikarus}{shebang-ikarus}{\#!ikarus}{reader syntax}
|
|
|
|
Ikarus extends Scheme's lexical syntax (\rnrs{6}~Chapter~4) in a
|
|
variety of ways including:\\
|
|
$\bullet$ end-of-file marker, \deflabelref{\#!eof}{shebang-eof}\\
|
|
$\bullet$ gensym syntax, \deflabelref{\#\{gensym\}}{gensym syntax}\\
|
|
$\bullet$ graph syntax, \deflabelref{\#nn= \#nn\#}{graph-syntax}
|
|
|
|
The syntax extensions are made available by default on all input
|
|
ports, until the \texttt{\#!r6rs} token is read. Thus, reading the
|
|
\texttt{\#!r6rs} token disables all extensions to the lexical syntax
|
|
on the specific port, and the \texttt{\#!ikarus} enables them again.
|
|
|
|
If you are writing code that is intended to be portable across
|
|
different Scheme implementations, we recommend adding the
|
|
\texttt{\#!r6rs} token to the top of every script and library that
|
|
you write. This allows Ikarus to alert you when using non-portable
|
|
features. If you're writing code that's intended to be
|
|
Ikarus-specific, we recommend adding the \texttt{\#!ikarus} token in
|
|
order to get an immediate error when your code is run under other
|
|
implementations.
|
|
|
|
\defun{port-mode}{procedure}
|
|
\texttt{(port-mode ip)}
|
|
|
|
The \texttt{port-mode} procedure accepts an input port as an
|
|
argument and returns one of \texttt{r6rs-mode} or
|
|
\texttt{ikarus-mode} as a result. All input ports initially start
|
|
in the \texttt{ikarus-mode} and thus accept Ikarus-specific reader
|
|
extensions. When the \texttt{\#!r6rs} token is read from a port,
|
|
its mode changes to \texttt{ikarus-mode}.
|
|
|
|
\begin{verbatim}
|
|
> (port-mode (current-input-port))
|
|
ikarus-mode
|
|
> #!r6rs (port-mode (current-input-port))
|
|
r6rs-mode
|
|
> #!ikarus (port-mode (current-input-port))
|
|
ikarus-mode
|
|
\end{verbatim}
|
|
|
|
\idxlabeldefun{set-port-mode"!}{set-port-mode"!}{set-port-mode-bang}{set-port-mode!}{procedure}
|
|
%\defun{set-port-mode!}{procedure}
|
|
%\index{set-port-mode@\texttt{set-port-mode"!}}
|
|
\texttt{(set-port-mode!\ ip mode)}
|
|
|
|
The \texttt{set-port-mode!} procedure modifies the lexical syntax
|
|
accepted by subsequent calls to \texttt{read} on the input port.
|
|
The mode is a symbol which should be one of \texttt{r6rs-mode} or
|
|
\texttt{ikarus-mode}. The effect of setting the port mode is
|
|
similar to that of reading the \texttt{\#!r6rs} or \texttt{\#ikarus}
|
|
from that port.
|
|
|
|
\begin{verbatim}
|
|
> (set-port-mode! (current-input-port) 'r6rs-mode)
|
|
> (port-mode (current-input-port))
|
|
r6rs-mode
|
|
\end{verbatim}
|
|
|
|
\newpage
|
|
\idxlabeldefun{\#"!eof}{\#"!eof}{shebang-eof}{\#!eof}{reader syntax}
|
|
|
|
The end-of-file marker, \texttt{\#!eof}, is an extension to the
|
|
\rnrs{6} syntax. The primary utility of the \texttt{\#!eof} marker
|
|
is to stop the reader (e.g. \texttt{read} and \texttt{get-datum})
|
|
from reading the rest of the file.
|
|
\begin{verbatim}
|
|
#!/usr/bin/env scheme-script
|
|
(import (ikarus))
|
|
<some code>
|
|
(display "goodbye\n")
|
|
|
|
#!eof
|
|
<some junk>
|
|
\end{verbatim}
|
|
|
|
|
|
The \texttt{\#!eof} marker also serves as a datum in Ikarus, much
|
|
like \texttt{\#t} and \texttt{\#f}, when it is found inside other
|
|
expressions.
|
|
|
|
\begin{verbatim}
|
|
> (eof-object)
|
|
#!eof
|
|
> (read (open-input-string ""))
|
|
#!eof
|
|
> (read (open-input-string "#!eof"))
|
|
#!eof
|
|
> (quote #!eof)
|
|
#!eof
|
|
> (eof-object? '#!eof)
|
|
#t
|
|
> #!r6rs #!eof
|
|
Unhandled exception
|
|
Condition components:
|
|
1. &error
|
|
2. &who: tokenize
|
|
3. &message: "invalid syntax: #!e"
|
|
> #!ikarus #!eof
|
|
$
|
|
\end{verbatim}
|
|
|
|
\newpage
|
|
\section{Parameters}
|
|
|
|
Parameters in Ikarus\footnote{Parameters are found in many Scheme
|
|
implementations such as Chez Scheme and MzScheme.} are intended for
|
|
customizing the behavior of a procedure during the dynamic execution
|
|
of some piece of code. Parameters are first class entities
|
|
(represented as procedures) that hold the parameter value. A
|
|
parameter procedure accepts either zero or one argument. If given
|
|
no arguments, it returns the current value of the parameter. If
|
|
given a single argument, it must set the state to the value of the
|
|
argument. Parameters replace the older concept of using starred
|
|
\texttt{*global*} customization variables. For example, instead of
|
|
writing:
|
|
\begin{verbatim}
|
|
(define *screen-width* 72)
|
|
\end{verbatim}
|
|
and then mutating the variable \texttt{*screen-width*} with
|
|
\texttt{set!}, we could wrap the variable \texttt{*screen-width*} with a
|
|
\texttt{screen-width} parameter as follows:
|
|
\begin{verbatim}
|
|
(define *screen-width* 72)
|
|
(define screen-width
|
|
(case-lambda
|
|
[() *screen-width*]
|
|
[(x) (set! *screen-width* x)]))
|
|
\end{verbatim}
|
|
|
|
The value of \texttt{screen-width} can now be passed as argument,
|
|
returned as a value, and exported from libraries.
|
|
|
|
\defun{make-parameter}{procedure}
|
|
\texttt{
|
|
(make-parameter x)\\
|
|
(make-parameter x f)
|
|
}
|
|
|
|
As parameters are common in Ikarus, the procedure
|
|
\texttt{make-parameter} is defined to model the common usage pattern
|
|
of parameter construction.
|
|
|
|
\paragraph{\texttt{(make-parameter x)}} constructs a parameter
|
|
with \texttt{x} as the initial value. For example, the code above
|
|
could be written succinctly as:
|
|
\begin{verbatim}
|
|
(define screen-width (make-parameter 72))
|
|
\end{verbatim}
|
|
|
|
\paragraph{\texttt{(make-parameter x f)}} constructs a parameter
|
|
which filters the assigned values through the procedure \texttt{f}.
|
|
The initial value of the parameter is the result of calling
|
|
\texttt{(f~x)}. Typical uses of the filter procedure include
|
|
checking some constraints on the passed argument or converting it to
|
|
a different data type. The \texttt{screen-width} parameter may be
|
|
constructed more robustly as:
|
|
\begin{verbatim}
|
|
(define screen-width
|
|
(make-parameter 72
|
|
(lambda (w)
|
|
(assert (and (integer? w) (exact? w)))
|
|
(max w 1))))
|
|
\end{verbatim}
|
|
This definition ensures, through \texttt{assert}, that the argument
|
|
passed is an exact integer. It also ensures, through \texttt{max}
|
|
that the assigned value is always positive.
|
|
|
|
|
|
\defun{parameterize}{syntax}
|
|
\texttt{(parameterize ([lhs* rhs*] ...) body body* ...)}
|
|
|
|
Parameters can be assigned to by simply calling the parameter
|
|
procedure with a single argument. The \texttt{parameterize} syntax
|
|
is used to set the value of a parameter within the dynamic extent of
|
|
the \texttt{body~body*~...} expressions.
|
|
|
|
The \texttt{lhs* ...} are expressions, each of which must evaluate
|
|
to a parameter. Such parameters are not necessarily constructed by
|
|
\texttt{make-parameter}---any procedure that follows the parameters
|
|
protocol works.
|
|
|
|
The advantage of using \texttt{parameterize} over explicitly
|
|
assigning to parameters (same argument applies to global variables)
|
|
is that you're guaranteed that whenever control exits the body of a
|
|
\texttt{parameterize} expression, the value of the parameter is
|
|
reset back to what it was before the body expressions were entered.
|
|
This is true even in the presence of \texttt{call/cc}, errors, and
|
|
exceptions.
|
|
|
|
The following example shows how to set the text property of a
|
|
terminal window. The parameter \texttt{terminal-property} sends an
|
|
ANSI escape sequence to the terminal whenever the parameter value is
|
|
changed. The use of \texttt{terminal-property} within
|
|
\texttt{parameterize} changes the property before
|
|
\texttt{(display~"RED!")} is called and resets it back to normal
|
|
when the body returns.
|
|
|
|
\begin{CodeInline}
|
|
(define terminal-property
|
|
(make-parameter "0"
|
|
(lambda (x)
|
|
(display "\x1b;[")
|
|
(display x)
|
|
(display "m")
|
|
x)))
|
|
|
|
(display "Normal and ")
|
|
(parameterize ([terminal-property "41;37"])
|
|
(display "RED!"))
|
|
(newline)
|
|
\end{CodeInline}
|
|
|
|
\newpage
|
|
\section{Local library imports}
|
|
\defun{import}{syntax}
|
|
\texttt{(import import-spec* ...)}
|
|
|
|
The \texttt{import} keyword which is exported from the
|
|
\texttt{(ikarus)} library can be used anywhere definitions can
|
|
occur: at a script body, library's top-level, or in internal
|
|
definitions context. The syntax of the local \texttt{import} form
|
|
is similar to the \texttt{import} that appears at the top of a
|
|
library or a script form, and carries with it the same restrictions:
|
|
no identifier name may be imported twice unless it denotes the same
|
|
identifier; no identifier may be both imported and defined; and
|
|
imported identifiers are immutable.
|
|
|
|
Local \texttt{import} forms are useful for two reasons: (1) they
|
|
minimize the namespace clutter that usually occurs when many
|
|
libraries are imported at the top level, and (2) they limit the
|
|
scope of the import and thus help modularize a library's
|
|
dependencies.
|
|
|
|
Suppose you are constructing a large library and at some point you
|
|
realize that one of your procedures needs to make use of some other
|
|
library for performing a specific task. Importing that library at
|
|
top level makes it available for the entire library. Consequently,
|
|
even if that library is no longer used anywhere in the code (say
|
|
when the code that uses it is deleted), it becomes very hard to
|
|
delete the import without first examiniming the entire library body
|
|
for potential usage leaks. By locally importing a library into the
|
|
appropriate scope, we gain the ability to delete the \texttt{import}
|
|
form when the procedure that was using it is deleted.
|
|
|
|
|
|
\newpage
|
|
\section{Local modules}
|
|
|
|
This section is not documented yet.
|
|
Please refer to Section~10.5 of Chez Scheme
|
|
User's Guide~\cite{csug7}, Chapter~3 of Oscar Waddel's Ph.D
|
|
Thesis~\cite{waddell-thesis}, and its POPL99
|
|
paper~\cite{waddell-extending} for details on using the
|
|
\texttt{module} and \texttt{import} keywords. Ikarus's internal
|
|
module system is similar in spirit to that of Chez Scheme.
|
|
|
|
|
|
\defun{module}{syntax}
|
|
\texttt{(module M definitions ... expressions ...)}\\
|
|
\texttt{(module definitions ... expressions ...)}
|
|
|
|
\defun{import}{syntax}
|
|
\texttt{(import M)}
|
|
|
|
|
|
\newpage
|
|
|
|
\section{\label{sec:gensyms}Gensyms}
|
|
|
|
Gensym stands for a \emph{generated symbol}---a fresh symbol that is
|
|
generated at run time and is guaranteed to be \emph{not}
|
|
\texttt{eq?} to any other symbol present in the system. Gensyms are
|
|
useful in many applications including expanders, compilers, and
|
|
interpreters when generating an arbitrary number of unique names is
|
|
needed.
|
|
|
|
Ikarus is similar to Chez Scheme in that the readers (including the
|
|
\texttt{read} procedure) and writers (including \texttt{write} and
|
|
\texttt{pretty-print}) maintain the read/write invariance on
|
|
gensyms. When a gensym is written to an output port, the system
|
|
automatically generates a random unique identifier for the gensym.
|
|
When the gensym is read back though the \verb|#{gensym}| read
|
|
syntax, a new gensym is \emph{not} regenerated, but instead, it is
|
|
looked up in the global symbol table.
|
|
|
|
A gensym's name is composed of two parts: a \emph{pretty} string and
|
|
a \emph{unique} string. The Scheme procedure
|
|
\texttt{symbol->string} returns the pretty string of the gensym and
|
|
not its unique string. Gensyms are printed by default as \\
|
|
\verb|#{pretty-string unique-string}|.
|
|
|
|
\defun{gensym}{procedure}
|
|
\texttt{(gensym)}\\
|
|
\texttt{(gensym string)}\\
|
|
\texttt{(gensym symbol)}
|
|
|
|
The procedure \texttt{gensym} constructs a new gensym. If passed no
|
|
arguments, it constructs a gensym with no pretty name. The pretty
|
|
name is constructed when and if the pretty name of the resulting
|
|
gensym is needed. If \texttt{gensym} is passed a string, that
|
|
string is used as the pretty name. If \texttt{gensym} is passed a
|
|
symbol, the pretty name of the symbol is used as the pretty name of
|
|
the returned gensym.
|
|
See \defref{gensym-prefix} and \defref{gensym-count} for details.
|
|
|
|
\begin{verbatim}
|
|
> (gensym)
|
|
#{g0 |y0zf>GlFvcTJE0xw|}
|
|
> (gensym)
|
|
#{g1 |U%X&sF6kX!YC8LW=|}
|
|
> (eq? (gensym) (gensym))
|
|
#f
|
|
\end{verbatim}
|
|
|
|
\texttt{(gensym string)} constructs a new gensym with
|
|
\texttt{string} as its pretty name. Similarly,
|
|
\texttt{(gensym~symbol)} constructs a new gensym with the pretty
|
|
name of \texttt{symbol}, if it has one, as its pretty name.
|
|
|
|
\begin{verbatim}
|
|
> (gensym "foo")
|
|
#{foo |>VgOllCM&$dSvRN=|}
|
|
> (gensym 'foo)
|
|
#{foo |!TqQLmtw2hoEYfU>|}
|
|
> (gensym (gensym 'foo))
|
|
#{foo |N2C>5O0>C?OROUBU|}
|
|
\end{verbatim}
|
|
|
|
|
|
|
|
\defun{gensym?}{procedure}
|
|
\texttt{(gensym? x)}
|
|
|
|
The \texttt{gensym?}\ predicate returns \texttt{\#t} if its argument
|
|
is a gensym, and returns \texttt{\#f} otherwise.
|
|
|
|
\begin{verbatim}
|
|
> (gensym? (gensym))
|
|
#t
|
|
> (gensym? 'foo)
|
|
#f
|
|
> (gensym? 12)
|
|
#f
|
|
\end{verbatim}
|
|
|
|
\defun{gensym->unique-string}{procedure}
|
|
\texttt{(gensym->unique-string gensym)}
|
|
|
|
The \texttt{gensym->unique-string} procedure returns the unique name
|
|
associated with the gensym argument.
|
|
|
|
\begin{verbatim}
|
|
> (gensym->unique-string (gensym))
|
|
"YukrolLMgP?%ElcR"
|
|
\end{verbatim}
|
|
|
|
|
|
\idxdefun{gensym syntax}{\#\{gensym\}}{reader syntax}
|
|
\texttt{\#\{unique-name\}}
|
|
\index{\#\{pretty unique\}@\texttt{\#\{pretty unique\}} reader syntax}
|
|
\\
|
|
\texttt{\#\{pretty-name unique-name\}}
|
|
\index{\#\{unique\}@\texttt{\#\{unique\}} reader syntax}
|
|
\\
|
|
\texttt{\#:pretty-name}
|
|
\index{\#:pretty@\texttt{\#:pretty} reader syntax}
|
|
|
|
Ikarus's \texttt{read} and \texttt{write} procedures extend the
|
|
lexical syntax of Scheme by the ability to read and write gensyms
|
|
using one of the three forms listed above.
|
|
|
|
\verb|#{unique-name}| constructs, at read time, a gensym whose
|
|
unique name is the one specified. If a gensym with the same unique
|
|
name already exists in the system's symbol table, that gensym is
|
|
returned.
|
|
\begin{verbatim}
|
|
> '#{some-long-name}
|
|
#{g0 |some-long-name|}
|
|
> (gensym? '#{some-long-unique-name})
|
|
#t
|
|
> (eq? '#{another-unique-name} '#{another-unique-name})
|
|
#t
|
|
\end{verbatim}
|
|
|
|
The two-part \verb|#{pretty-name unique-name}| gensym syntax is
|
|
similar to the syntax shown above with the exception that if a new
|
|
gensym is constructed (that is, if the gensym did not already exist
|
|
in the symbol table), the pretty name of the constructed gensym is
|
|
set to \texttt{pretty-name}.
|
|
|
|
\begin{verbatim}
|
|
> '#{foo unique-identifier}
|
|
#{foo |unique-identifier|}
|
|
> '#{unique-identifier}
|
|
#{foo |unique-identifier|}
|
|
> '#{bar unique-identifier}
|
|
#{foo |unique-identifier|}
|
|
\end{verbatim}
|
|
|
|
The \texttt{\#:pretty-name} form constructs, at read time, a gensym
|
|
whose pretty name is \texttt{pretty-name} and whose unique name is
|
|
fresh. This form guarantees that the resulting gensym is not
|
|
\texttt{eq?}\ to any other symbol in the system.
|
|
|
|
\begin{verbatim}
|
|
> '#:foo
|
|
#{foo |j=qTGlEwS/Zlp2Dj|}
|
|
> (eq? '#:foo '#:foo)
|
|
#f
|
|
\end{verbatim}
|
|
|
|
\defun{generate-temporaries}{example}
|
|
\index{Examples!generate-temporaries@\texttt{generate-temporaries}}
|
|
|
|
The \texttt{(rnrs syntax-case)} library provides a
|
|
\texttt{generate-temporaries} procedure, which takes a syntax object
|
|
(representing a list of things) and returns a list of fresh
|
|
identifiers. Using \texttt{gensym}, that procedure can be defined
|
|
as follows:
|
|
|
|
\begin{CodeInline}
|
|
(define (generate-temporaries* stx)
|
|
(syntax-case stx ()
|
|
[(x* ...)
|
|
(map (lambda (x)
|
|
(datum->syntax #'unimportant
|
|
(gensym
|
|
(if (identifier? x)
|
|
(syntax->datum x)
|
|
't))))
|
|
#'(x* ...))]))
|
|
\end{CodeInline}
|
|
|
|
The above definition works by taking the input \texttt{stx} and
|
|
destructuring it into the list of syntax objects \texttt{x*~...}.
|
|
The inner procedure maps each \texttt{x} into a new syntax object
|
|
(constructed with \texttt{datum->syntax}). The datum is a gensym,
|
|
whose name is the same name as \texttt{x} if \texttt{x} is an
|
|
identifier, or the symbol \texttt{t} if \texttt{x} is not an
|
|
identifier. The output of \texttt{generate-temporaries*} generates
|
|
names similar to their input counterpart:
|
|
|
|
\begin{verbatim}
|
|
> (print-gensym #f)
|
|
> (generate-temporaries* #'(x y z 1 2))
|
|
(#<syntax x> #<syntax y> #<syntax z> #<syntax t> #<syntax t>)
|
|
\end{verbatim}
|
|
|
|
\newpage
|
|
\section{Printing}
|
|
|
|
\defun{pretty-print}{procedure}
|
|
\texttt{(pretty-print datum)}\\
|
|
\texttt{(pretty-print datum output-port)}
|
|
|
|
The procedure \texttt{pretty-print} is intended for printing Scheme
|
|
data, typically Scheme programs, in a format close to how a Scheme
|
|
programmer would write it. Unlike \texttt{write}, which writes its
|
|
input all in one line, \texttt{pretty-print} inserts spaces and new
|
|
lines in order to produce more pleasant output.
|
|
|
|
\begin{verbatim}
|
|
(define fact-code
|
|
'(letrec ([fact (lambda (n) (if (zero? n) 1 (* n (fact (- n 1)))))])
|
|
(fact 5)))
|
|
|
|
> (pretty-print fact-code)
|
|
(letrec ((fact
|
|
(lambda (n) (if (zero? n) 1 (* n (fact (- n 1)))))))
|
|
(fact 5))
|
|
\end{verbatim}
|
|
|
|
The second argument to \texttt{pretty-print}, if supplied, must be
|
|
an output port. If not supplied, the \texttt{current-output-port}
|
|
is used.
|
|
|
|
\BoxedText{Limitations:}{As shown in the output above, the current
|
|
implementation of \texttt{pretty-print} does not handle printing of
|
|
square brackets properly.}
|
|
|
|
\defun{pretty-width}{parameter}
|
|
\texttt{(pretty-width)}\\
|
|
\texttt{(pretty-width n)}
|
|
|
|
The parameter \texttt{pretty-width} controls the number of
|
|
characters after which the \texttt{pretty-print} starts breaking
|
|
long lines into multiple lines. The initial value of
|
|
\texttt{pretty-width} is set to 60 characters, which is suitable for most
|
|
terminals and printed material.
|
|
|
|
\begin{verbatim}
|
|
> (parameterize ([pretty-width 40])
|
|
(pretty-print fact-code))
|
|
(letrec ((fact
|
|
(lambda (n)
|
|
(if (zero? n)
|
|
1
|
|
(* n (fact (- n 1)))))))
|
|
(fact 5))
|
|
\end{verbatim}
|
|
|
|
Note that \texttt{pretty-width} does not guarantee that
|
|
the output will not extend beyond the specified number. Very long
|
|
symbols, for examples, cannot be split into multiple lines and may
|
|
force the printer to go beyond the value of \texttt{pretty-width}.
|
|
|
|
\defun{format}{procedure}
|
|
\texttt{(format fmt-string args ...)}
|
|
|
|
The procedure \texttt{format} produces a string formatted according
|
|
to \texttt{fmt-string} and the supplied
|
|
arguments. The format string contains markers in which the string
|
|
representation of each argument is placed. The markers include:
|
|
|
|
|
|
\hangpara{2em}{1}
|
|
\verb|"~s"| instructs the formatter to place the next argument
|
|
as if the procedure \texttt{write} has printed it. If the argument
|
|
contains a string, the string will be quoted and all quotes and
|
|
backslashes in the string will be escaped. Similarly, characters
|
|
will be printed using the \verb|#\x| notation.
|
|
|
|
\hangpara{2em}{1}
|
|
\verb|"~a"| instructs the formatter to place the next argument
|
|
as if the procedure \texttt{display} has printed it. Strings and
|
|
characters are placed as they are in the output.
|
|
|
|
\hangpara{2em}{1}
|
|
\verb|"~b"| instructs the formatter to convert the next
|
|
argument to its binary (base 2) representation. The argument must be an
|
|
exact number. Note that the \texttt{\#b} numeric prefix is not
|
|
produced in the output.
|
|
|
|
\hangpara{2em}{1}
|
|
\verb|"~o"| is similar to \verb|"~b"| except that
|
|
the number is printed in octal (base 8).
|
|
|
|
\hangpara{2em}{1}
|
|
\verb|"~x"| is similar to \verb|"~b"| except that
|
|
the number is printed in hexadecimal (base 16).
|
|
|
|
\hangpara{2em}{1}
|
|
\verb|"~d"| outputs the next argument, which can be an
|
|
exact or inexact number, in its decimal (base 10) representation.
|
|
|
|
\hangpara{2em}{1}
|
|
\verb|"~~"| instructs the formatter to place a tilde
|
|
character, \verb|~|, in the output without consuming an
|
|
argument.
|
|
|
|
Note that the \texttt{\#b}, \texttt{\#o}, and \texttt{\#x} numeric
|
|
prefixes are not added to the output when \verb|~b|, \verb|~o|, and
|
|
\verb|~x| are used.
|
|
|
|
\begin{verbatim}
|
|
> (format "message: ~s, ~s, and ~s" 'symbol "string" #\c)
|
|
"message: symbol, \"string\", and #\\c"
|
|
|
|
> (format "message: ~a, ~a, and ~a" 'symbol "string" #\c)
|
|
"message: symbol, string, and c"
|
|
\end{verbatim}
|
|
|
|
\defun{printf}{procedure}
|
|
\texttt{(printf fmt-string args ...)}
|
|
|
|
The procedure \texttt{printf} is similar to \texttt{format} except
|
|
that the output is sent to the \texttt{current-output-port} instead
|
|
of being collected in a string.
|
|
|
|
\begin{verbatim}
|
|
> (let ([n (+ (expt 2 32) #b11001)])
|
|
(printf "~d = #b~b = #x~x\n" n n n))
|
|
4294967321 = #b100000000000000000000000000011001 = #x100000019
|
|
\end{verbatim}
|
|
|
|
|
|
\defun{fprintf}{procedure}
|
|
\texttt{(fprintf output-port fmt-string args ...)}
|
|
|
|
The procedure \texttt{fprintf} is similar to \texttt{printf} except
|
|
that the output port to which the output is sent is specified as the
|
|
first argument.
|
|
|
|
\defun{print-graph}{parameter}
|
|
\texttt{(print-graph)} \\
|
|
\texttt{(print-graph \#t)}\\
|
|
\texttt{(print-graph \#f)}
|
|
|
|
\phantomsection
|
|
\label{graph-syntax}
|
|
The graph notation is a way of marking and referencing parts of a
|
|
data structure and, consequently, creating shared and cyclic data
|
|
structures at read time instead of resorting to explicit mutation at
|
|
run time. The \texttt{\#$n$=} marks the following data structure with
|
|
mark $n$, where $n$ is a nonnegative integer. The \texttt{\#$n$\#}
|
|
references the data structure marked $n$. Marks can be assigned and
|
|
referenced in any order but each mark must be assigned to exactly
|
|
once in an expression.
|
|
|
|
\begin{verbatim}
|
|
> (let ([x '#0=(1 2 3)])
|
|
(eq? x '#0#))
|
|
#t
|
|
> (let ([x '#0#] [y '#0=(1 2 3)])
|
|
(eq? x y))
|
|
#t
|
|
> (eq? (cdr '(12 . #1#)) '#1=(1 2 3))
|
|
#t
|
|
> (let ([x '#1=(#1# . #1#)])
|
|
(and (eq? x (car x))
|
|
(eq? x (cdr x))))
|
|
#t
|
|
\end{verbatim}
|
|
|
|
The \texttt{print-graph} parameter controls how the writers (e.g.
|
|
\texttt{pretty-print} and \texttt{write}) handle shared and cyclic
|
|
data structures. In Ikarus, all writers detect cyclic data
|
|
structures and they all terminate on all input, cyclic or otherwise.
|
|
|
|
If the value of \texttt{print-graph} is set to \texttt{\#f} (the
|
|
default), then the writers does not attempt to detect shared data
|
|
structures. Any part of the input that is shared is printed as if
|
|
no sharing is present.
|
|
If the value of \texttt{print-graph} is set to \texttt{\#t}, all
|
|
sharing of data structures is marked using the \texttt{\#$n$=} and
|
|
\texttt{\#$n$\#} notation.
|
|
|
|
|
|
\begin{verbatim}
|
|
> (parameterize ([print-graph #f])
|
|
(let ([x (list 1 2 3 4)])
|
|
(pretty-print (list x x x))))
|
|
((1 2 3 4) (1 2 3 4) (1 2 3 4))
|
|
|
|
> (parameterize ([print-graph #t])
|
|
(let ([x (list 1 2 3 4)])
|
|
(pretty-print (list x x x))))
|
|
(#0=(1 2 3 4) #0# #0#)
|
|
|
|
> (parameterize ([print-graph #f])
|
|
(let ([x (list 1 2)])
|
|
(let ([y (list x x x x)])
|
|
(set-car! (last-pair y) y)
|
|
(pretty-print (list y y)))))
|
|
(#0=((1 2) (1 2) (1 2) #0#) #0#)
|
|
|
|
> (parameterize ([print-graph #t])
|
|
(let ([x (list 1 2)])
|
|
(let ([y (list x x x x)])
|
|
(set-car! (last-pair y) y)
|
|
(pretty-print (list y y)))))
|
|
(#0=(#1=(1 2) #1# #1# #0#) #0#)
|
|
\end{verbatim}
|
|
|
|
|
|
% \defun{print-unicode}{parameter}
|
|
% \texttt{(print-unicode)} \\
|
|
% \texttt{(print-unicode \#t)} \\
|
|
% \texttt{(print-unicode \#f)}
|
|
|
|
|
|
\defun{print-gensym}{parameter}
|
|
\texttt{(print-gensym)}\\
|
|
\texttt{(print-gensym \#t)}\\
|
|
\texttt{(print-gensym \#f)}\\
|
|
\texttt{(print-gensym 'pretty)}
|
|
|
|
The parameter \texttt{print-gensym} controls how gensyms are printed
|
|
by the various writers.
|
|
|
|
If the value of \texttt{print-gensym} is \texttt{\#f}, then gensym
|
|
syntax is suppressed by the writers and only the gensyms' pretty
|
|
names are printed. If the value of \texttt{print-gensym} is
|
|
\texttt{\#t}, then the full \verb|#{pretty unique}| syntax is
|
|
printed. Finally, if the value of \texttt{print-gensym} is the
|
|
symbol \texttt{pretty}, then gensyms are printed using the
|
|
\texttt{\#:pretty} notation.
|
|
|
|
\begin{verbatim}
|
|
> (parameterize ([print-gensym #f])
|
|
(pretty-print (list (gensym) (gensym))))
|
|
(g0 g1)
|
|
|
|
> (parameterize ([print-gensym #t])
|
|
(pretty-print (list (gensym) (gensym))))
|
|
(#{g2 |KR1M2&CTt1<B0n/m|} #{g3 |FBAb&7NC6&=c82!O|})
|
|
|
|
> (parameterize ([print-gensym 'pretty])
|
|
(pretty-print (list (gensym) (gensym))))
|
|
(#:g4 #:g5)
|
|
\end{verbatim}
|
|
|
|
The initial value of \texttt{print-gensym} is \texttt{\#t}.
|
|
|
|
|
|
\defun{gensym-prefix}{parameter}
|
|
\texttt{(gensym-prefix)}\\
|
|
\texttt{(gensym-prefix string)}
|
|
|
|
The parameter \texttt{gensym-prefix} specifies the string to be used
|
|
as the prefix to generated pretty names. The default value of
|
|
\texttt{gensym-prefix} is the string \texttt{"g"}, which causes
|
|
generated strings to have pretty names in the sequence \texttt{g0},
|
|
\texttt{g1}, \texttt{g2}, etc.
|
|
|
|
\begin{verbatim}
|
|
> (parameterize ([gensym-prefix "var"]
|
|
[print-gensym #f])
|
|
(pretty-print (list (gensym) (gensym) (gensym))))
|
|
(var0 var1 var2)
|
|
\end{verbatim}
|
|
|
|
Beware that the \texttt{gensym-prefix} controls how pretty names are
|
|
generated, and has nothing to do with how \texttt{gensym} constructs
|
|
a new gensym. In particular, notice the difference between the
|
|
output in the first example with the output of the examples below:
|
|
|
|
\begin{verbatim}
|
|
> (pretty-print
|
|
(parameterize ([gensym-prefix "var"] [print-gensym #f])
|
|
(list (gensym) (gensym) (gensym))))
|
|
(g3 g4 g5)
|
|
|
|
> (let ([ls (list (gensym) (gensym) (gensym))])
|
|
(parameterize ([gensym-prefix "var"] [print-gensym #f])
|
|
(pretty-print ls)))
|
|
(var5 var6 var7)
|
|
\end{verbatim}
|
|
|
|
|
|
|
|
\defun{gensym-count}{parameter}
|
|
\texttt{(gensym-count)}\\
|
|
\texttt{(gensym-count n)}
|
|
|
|
The parameter \texttt{gensym-count} determines the number
|
|
which is attached to the \texttt{gensym-prefix} when gensyms'
|
|
pretty names are generated. The initial value of \texttt{gensym-count}
|
|
is 0 and is incremented every time a
|
|
pretty name is generated. It might be set to any non-negative
|
|
integer value.
|
|
|
|
\begin{verbatim}
|
|
> (let ([x (gensym)])
|
|
(parameterize ([gensym-count 100] [print-gensym #f])
|
|
(pretty-print (list (gensym) x (gensym)))))
|
|
(g100 g101 g102)
|
|
\end{verbatim}
|
|
|
|
Notice from all the examples so far that pretty names are generated
|
|
in the order at which the gensyms are printed, not in the order in
|
|
which gensyms were created.
|
|
|
|
\newpage
|
|
\section{Tracing}
|
|
|
|
\defun{trace-define}{syntax}
|
|
\texttt{(trace-define (name . args) body body* ...)}\\
|
|
\texttt{(trace-define name expression)}
|
|
|
|
The \texttt{trace-define} syntax is similar to \texttt{define}
|
|
except that the bound value, which must be a procedure, becomes a
|
|
traced procedure. A traced procedure prints its arguments when it
|
|
is called and prints its values when it returns.
|
|
|
|
\begin{verbatim}
|
|
> (trace-define (fact n)
|
|
(if (zero? n) 1 (* n (fact (- n 1)))))
|
|
> (fact 5)
|
|
|(fact 5)
|
|
| (fact 4)
|
|
| |(fact 3)
|
|
| | (fact 2)
|
|
| | |(fact 1)
|
|
| | | (fact 0)
|
|
| | | 1
|
|
| | |1
|
|
| | 2
|
|
| |6
|
|
| 24
|
|
|120
|
|
120
|
|
\end{verbatim}
|
|
|
|
The tracing facility in Ikarus preserves and shows tail recursion
|
|
and distinguishes it from non-tail recursion by showing tail calls
|
|
starting at the same line in which their parent was called.
|
|
|
|
\begin{verbatim}
|
|
> (trace-define (fact n)
|
|
(trace-define (fact-aux n m)
|
|
(if (zero? n) m (fact-aux (- n 1) (* n m))))
|
|
(fact-aux n 1))
|
|
> (fact 5)
|
|
|(fact 5)
|
|
|(fact-aux 5 1)
|
|
|(fact-aux 4 5)
|
|
|(fact-aux 3 20)
|
|
|(fact-aux 2 60)
|
|
|(fact-aux 1 120)
|
|
|(fact-aux 0 120)
|
|
|120
|
|
120
|
|
\end{verbatim}
|
|
|
|
Moreover, the tracing facility interacts well with continuations and
|
|
exceptions.
|
|
|
|
\begin{verbatim}
|
|
> (call/cc
|
|
(lambda (k)
|
|
(trace-define (loop n)
|
|
(if (zero? n)
|
|
(k 'done)
|
|
(+ (loop (- n 1)) 1)))
|
|
(loop 5)))
|
|
|(loop 5)
|
|
| (loop 4)
|
|
| |(loop 3)
|
|
| | (loop 2)
|
|
| | |(loop 1)
|
|
| | | (loop 0)
|
|
done
|
|
\end{verbatim}
|
|
|
|
|
|
\defun{trace-lambda}{syntax}
|
|
\texttt{(trace-lambda name args body body* ...)}
|
|
|
|
The \texttt{trace-lambda} macro is similar to \texttt{lambda} except
|
|
that the resulting procedure is traced: it prints the arguments it
|
|
receives and the results it returns.
|
|
|
|
\defun{make-traced-procedure}{procedure}
|
|
\texttt{(make-traced-procedure name proc)}
|
|
|
|
The procedure \texttt{make-traced-procedure} takes a name (typically
|
|
a symbol) and a procedure. It returns a procedure similar to
|
|
\texttt{proc} except that it traces its arguments and values.
|
|
|
|
\begin{verbatim}
|
|
> (define (fact n)
|
|
(if (zero? n)
|
|
(lambda (k) (k 1))
|
|
(lambda (k)
|
|
((fact (- n 1))
|
|
(make-traced-procedure `(k ,n)
|
|
(lambda (v)
|
|
(k (* v n))))))))
|
|
> (call/cc
|
|
(lambda (k)
|
|
((fact 5) (make-traced-procedure 'K k))))
|
|
|((k 1) 1)
|
|
|((k 2) 1)
|
|
|((k 3) 2)
|
|
|((k 4) 6)
|
|
|((k 5) 24)
|
|
|(K 120)
|
|
120
|
|
\end{verbatim}
|
|
|
|
|
|
\newpage
|
|
\section{Timing}
|
|
|
|
This section describes some of Ikarus's timing facilities which may
|
|
be useful for benchmarking and performance tuning.
|
|
|
|
\defun{time}{syntax}
|
|
\texttt{(time expression)}
|
|
|
|
The \texttt{time} macro performs the following: it evaluates
|
|
\texttt{expression}, then prints a summary of the run time
|
|
statistics, then returns the values returned by \texttt{expression}.
|
|
The run-time summary includes the number of bytes allocated, the
|
|
number of garbage collection runs, and the time spent in both the
|
|
mutator and the collector.
|
|
|
|
|
|
\begin{verbatim}
|
|
> (let () ;;; 10 million
|
|
(define ls (time (vector->list (make-vector 10000000))))
|
|
(time (append ls ls))
|
|
(values))
|
|
running stats for (vector->list (make-vector 10000000)):
|
|
3 collections
|
|
672 ms elapsed cpu time, including 547 ms collecting
|
|
674 ms elapsed real time, including 549 ms collecting
|
|
120012328 bytes allocated
|
|
running stats for (append ls ls):
|
|
4 collections
|
|
1536 ms elapsed cpu time, including 1336 ms collecting
|
|
1538 ms elapsed real time, including 1337 ms collecting
|
|
160000040 bytes allocated
|
|
\end{verbatim}
|
|
|
|
Note: The output listed above is \emph{just a sample} that was
|
|
taken at some point on some machine. The output on your
|
|
machine at the time you read this may vary.
|
|
|
|
\newpage
|
|
\defun{time-it}{procedure}
|
|
\texttt{(time-it who thunk)}
|
|
|
|
The procedure \texttt{time-it} takes a datum denoting the name of
|
|
the computation and a thunk (i.e. a
|
|
procedure with no arguments), invokes the thunk, prints the stats,
|
|
and returns the values obtained from invoking the thunk.
|
|
If the value of \texttt{who} is non-false, \texttt{who}
|
|
is used when displaying the run-time statistics. If the value of
|
|
\texttt{who} is \texttt{\#f}, then no name for the computation is
|
|
displayed.
|
|
|
|
\begin{verbatim}
|
|
> (time-it "a very fast computation"
|
|
(lambda () (values 1 2 3)))
|
|
running stats for a very fast computation:
|
|
no collections
|
|
0 ms elapsed cpu time, including 0 ms collecting
|
|
0 ms elapsed real time, including 0 ms collecting
|
|
56 bytes allocated
|
|
1
|
|
2
|
|
3
|
|
|
|
> (time-it #f (lambda () 12))
|
|
running stats:
|
|
no collections
|
|
0 ms elapsed cpu time, including 0 ms collecting
|
|
0 ms elapsed real time, including 0 ms collecting
|
|
32 bytes allocated
|
|
12
|
|
\end{verbatim}
|
|
|
|
\chapter{\label{chapter:contributed}Contributed Libraries}
|
|
|
|
We try to keep Ikarus Scheme small and its complexity manageable.
|
|
Libraries that are not an essential part of Ikarus are not included
|
|
in the Ikarus proper, instead, they are distributed with Ikarus in
|
|
source form. Such libraries may be written specifically
|
|
for Ikarus, or they may be portable libraries that can be used in
|
|
Ikarus. SRFIs or other libraries contributed by members of the
|
|
Scheme community belong to this section.
|
|
|
|
Using contributed libraries is no different from using any of the
|
|
built-in libraries---all one has to do is add the library name to
|
|
the \texttt{import} clause and the rest is done by the system.
|
|
|
|
If you have written a useful \rnrs{6} library and wish for it to be
|
|
available for a wider audience, contact us and we would be delighted
|
|
to include it in the next release of Ikarus. High quality SRFIs
|
|
with \rnrs{6} reference implementations will be distributed with
|
|
Ikarus as they become available.
|
|
|
|
\BoxedText{Note:}{Contributed libraries may have bugs on their own
|
|
or may exhibit bugs in Ikarus itself. If you have a problem using
|
|
any of these libraries, please try to resolve the issue by
|
|
contacting the library author first. Do not hesitate to file a bug
|
|
on Ikarus if you believe that Ikarus is at fault.}
|
|
|
|
\newpage
|
|
\section*{Library files}
|
|
|
|
The contributed libraries are installed in your system when Ikarus
|
|
was installed. By default, running the \texttt{configure} script
|
|
installs the contributed libraries into the
|
|
\verb|/usr/local/lib/ikarus| directory. If a \verb|--prefix DIR|
|
|
argument was supplied to \texttt{configure}, then the libraries are
|
|
installed in the \verb|DIR/ikarus/lib| directory.
|
|
|
|
You may install additional libraries into the Ikarus library
|
|
directory. Doing so makes them available for \texttt{import} into
|
|
other libraries and script regardless of where the importing code is
|
|
located or the current directory in which it is executed.
|
|
|
|
\section*{Defining \texttt{IKARUS\_LIBRARY\_PATH}}
|
|
\index{ikarus library path@\texttt{IKARUS\_LIBRARY\_PATH}}
|
|
|
|
There may be situations in which you may wish to install your own
|
|
libraries into a different location. For example, you may not have
|
|
sufficient administrative privileges to write to the system
|
|
directory, or you may wish to keep your own libraries separate from
|
|
the standard libraries. Whatever the reason is, your can store your
|
|
library files in any location you want and set up the
|
|
\verb|IKARUS_LIBRARY_PATH| environment variable to point to these
|
|
locations. The value of \verb|IKARUS_LIBRARY_PATH| is a
|
|
colon-separated list of directories in which Ikarus will search.
|
|
|
|
For example, suppose your script imports the
|
|
\texttt{(streams~derived)} library. First, Ikarus will map the
|
|
library name to the file path \verb|streams/derived.ss|. Suppose
|
|
that Ikarus was installed using the \verb|--prefix /usr/local|
|
|
configuration option, and suppose further that the value of
|
|
\verb|IKARUS_LIBRARY_PATH| is set by the user to be
|
|
\verb|/home/john/ikarus-libraries:/home/john/srfis|. Ikarus will
|
|
search in the following locations in sequence until it finds the
|
|
file it is looking for.
|
|
|
|
\begin{verbatim}
|
|
./streams/derived.ss
|
|
/home/john/ikarus-libraries/streams/derived.ss
|
|
/home/john/srfis/streams/derived.ss
|
|
/usr/local/lib/ikarus/streams/derived.ss
|
|
\end{verbatim}
|
|
|
|
\BoxedText{Warning:}{The current behavior of Ikarus regarding the
|
|
\texttt{IKARUS\_LIBRARY\_PATH} is preliminary and is likely to change
|
|
in future releases.}
|
|
|
|
The method in which the value of \verb|IKARUS_LIBRARY_PATH| is
|
|
defined is typically shell dependant. If you use GNU Bash, you
|
|
typically set the values of environment variables in the
|
|
\verb|~/.bash_profile| or \verb|~/.bashrc| file by adding the
|
|
following lines:
|
|
|
|
\begin{verbatim}
|
|
IKARUS_LIBRARY_PATH=/path/to/some/directory:/and/another
|
|
export IKARUS_LIBRARY_PATH
|
|
\end{verbatim}
|
|
|
|
|
|
|
|
\newpage
|
|
\section{SRFI-41: \texttt{(streams)}}
|
|
\index{SRFI-41: Streams}
|
|
\index{SRFI-41: Streams!1@\texttt{(streams)}}
|
|
\index{SRFI-41: Streams!2@\texttt{(streams primitive)}}
|
|
\index{SRFI-41: Streams!3@\texttt{(streams derived)}}
|
|
The \texttt{(streams)}, \texttt{(streams~primitive)}, and
|
|
\texttt{(streams~derived)} libraries are written by Philip L.~Bewig
|
|
as the reference implementation for SRFI-41.
|
|
See \url{http://srfi.schemers.org/srfi-41/srfi-41.html} for more
|
|
details. The following abstract is excerpted from the SRFI document.
|
|
\nocite{srfi41}
|
|
|
|
\begin{center}
|
|
\rule{\textwidth}{1pt}
|
|
Abstract
|
|
\end{center}
|
|
|
|
Streams, sometimes called lazy lists, are a sequential data
|
|
structure containing elements computed only on demand. A stream is
|
|
either null or is a pair with a stream in its cdr. Since elements of
|
|
a stream are computed only when accessed, streams can be infinite.
|
|
Once computed, the value of a stream element is cached in case it is
|
|
needed again.
|
|
|
|
Streams without memoization were first described by Peter Landin in
|
|
1965. Memoization became accepted as an essential feature of streams
|
|
about a decade later. Today, streams are the signature data type of
|
|
functional programming languages such as Haskell.
|
|
|
|
This Scheme Request for Implementation describes two libraries for
|
|
operating on streams: a canonical set of stream primitives and a set
|
|
of procedures and syntax derived from those primitives that permits
|
|
convenient expression of stream operations. They rely on facilities
|
|
provided by \rnrs{6}, including libraries, records, and error reporting.
|
|
To load both stream libraries, say:
|
|
|
|
\texttt{(import (streams))}
|
|
|
|
\chapter{Missing Features}
|
|
|
|
Ikarus does not fully conform to \rnrs{6} yet. Although it
|
|
implements the most immediately useful features of \rnrs{6}
|
|
including more than 90\% of \rnrs{6}'s macros and procedures, some
|
|
areas are still lacking. This section summarizes the set of
|
|
missing features and procedures.
|
|
|
|
|
|
\begin{itemize}
|
|
\item Numeric tower is complete except for complex numbers.\\
|
|
Consequences: \\
|
|
-- Reader does not recognize complex number notation
|
|
(e.g.~\texttt{5-7i}).\\
|
|
-- Procedures that may construct complex numbers from non-complex
|
|
arguments may signal an error or return an incorrect value
|
|
(for example, \texttt{(sqrt -1)} should \emph{not} be \texttt{+nan.0}).
|
|
\item The procedure \texttt{equal?}\ may not terminate on
|
|
\texttt{equal?}\ infinite (circular) input.
|
|
\item Representation of I/O ports is missing a transcoder field.
|
|
\item \texttt{number->string} does not accept the third argument
|
|
(precision). Similarly, \texttt{string->number} and the reader do
|
|
not recognize the \texttt{|p} notation.
|
|
\end{itemize}
|
|
\newpage
|
|
\section{List of missing \rnrs{6} procedures}
|
|
|
|
The following procedures are missing from \texttt{(rnrs base)}:
|
|
\begin{Verbatim}
|
|
angle magnitude make-polar make-rectangular
|
|
\end{Verbatim}
|
|
|
|
The following procedures are missing from \texttt{(rnrs bytevectors)}:
|
|
\begin{Verbatim}
|
|
string->utf16 string->utf32 utf16->string utf32->string
|
|
\end{Verbatim}
|
|
|
|
|
|
The following procedures are missing from \texttt{(rnrs unicode)}:
|
|
\begin{Verbatim}
|
|
string-downcase string-titlecase string-upcase
|
|
string-normalize-nfc string-normalize-nfd
|
|
string-normalize-nfkc string-normalize-nfkd
|
|
\end{Verbatim}
|
|
|
|
|
|
The following procedures are missing from \texttt{(rnrs arithmetic
|
|
bitwise)}:
|
|
\begin{Verbatim}
|
|
bitwise-ior bitwise-xor bitwise-if bitwise-bit-field
|
|
bitwise-copy-bit-field bitwise-copy-bit bitwise-length
|
|
bitwise-reverse-bit-field bitwise-rotate-bit-field
|
|
\end{Verbatim}
|
|
|
|
|
|
The following procedures are missing from \texttt{(rnrs arithmetic
|
|
fixnum)}:
|
|
\begin{Verbatim}
|
|
fxreverse-bit-field fxrotate-bit-field
|
|
\end{Verbatim}
|
|
|
|
|
|
The following procedures are missing from \texttt{(rnrs hashtables)}:
|
|
\begin{Verbatim}
|
|
make-eqv-hashtable make-hashtable equal-hash
|
|
hashtable-hash-function hashtable-equivalence-function
|
|
\end{Verbatim}
|
|
|
|
|
|
|
|
The following procedures are missing from \texttt{(rnrs io ports)}:
|
|
\begin{Verbatim}
|
|
call-with-bytevector-output-port call-with-string-output-port
|
|
binary-port? textual-port? port-eof?
|
|
port-has-port-position? port-position
|
|
port-has-set-port-position!? set-port-position!
|
|
call-with-port lookahead-char lookahead-u8
|
|
get-bytevector-all get-bytevector-some get-string-all
|
|
make-custom-binary-input-port make-custom-binary-input/output-port
|
|
make-custom-binary-output-port make-custom-textual-input-port
|
|
make-custom-textual-input/output-port make-custom-textual-output-port
|
|
open-bytevector-input-port open-bytevector-output-port
|
|
open-file-input-port open-file-input/output-port open-file-output-port
|
|
output-port-buffer-mode transcoded-port port-transcoderput-bytevector
|
|
string->bytevector bytevector->string
|
|
\end{Verbatim}
|
|
|
|
|
|
|
|
|
|
\nocite{ghuloum-implicit}
|
|
\nocite{ghuloum-generation}
|
|
|
|
\newpage
|
|
\backmatter
|
|
\appendix
|
|
\phantomsection
|
|
%\addcontentsline{toc}{chapter}{Bibliogaraphy}
|
|
\addcontentsline{toc}{chapter}{\bibname}
|
|
\bibliographystyle{plain}
|
|
\bibliography{ikarus-scheme-users-guide}
|
|
\newpage
|
|
\phantomsection
|
|
\addcontentsline{toc}{chapter}{Index}
|
|
\printindex
|
|
\end{document}
|
|
|
|
|
|
|
|
|
|
|
|
|