1899 lines
62 KiB
TeX
1899 lines
62 KiB
TeX
|
|
\documentclass[onecolumn, 12pt, twoside, openright, dvipdfm]{book}
|
|
\usepackage{fontspec}
|
|
|
|
\defaultfontfeatures{Scale=MatchLowercase}
|
|
%\setmainfont[Mapping=tex-text]{Cochin}
|
|
%\setmainfont[Mapping=tex-text]{Palatino}
|
|
%\setmainfont[Mapping=tex-text]{Baskerville}
|
|
\setmainfont[Mapping=tex-text]{Perpetua}
|
|
\setsansfont[Mapping=tex-text]{Geneva}
|
|
\setmonofont{Monaco}
|
|
|
|
\usepackage{fancyhdr}
|
|
\usepackage{makeidx}
|
|
\usepackage{fancyvrb}
|
|
\makeindex
|
|
|
|
\usepackage[dvipdfm,CJKbookmarks,bookmarks=true,bookmarksopen=true]{hyperref}
|
|
\hypersetup{
|
|
pdftitle={},
|
|
pdfauthor={Abdulaziz Ghuloum},
|
|
pdfkeywords={},
|
|
bookmarksnumbered=true,
|
|
%pagebackref=true,
|
|
breaklinks=true,
|
|
% pdfview=FitH, % Or try pdfstartview={FitV}, This lead to uncorrect bookmarks
|
|
urlcolor=cyan,
|
|
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{\defref}[1]{\texttt{#1}~(page~\pageref{#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{\idxdefun}[3]{
|
|
\vspace{1ex}
|
|
\rule{\textwidth}{2pt}
|
|
{\index{#1@\texttt{#2}}\label{#1}{\Large\texttt{#2}} \hfill \textbf{#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}
|
|
|
|
{
|
|
\fontsize{66}{66}
|
|
\fontspec{Hoefler Text Italic}
|
|
% \fontspec{Palatino}
|
|
% \rnrs{6} Libraries
|
|
% {
|
|
% \fontsize{36}{36}
|
|
% \fontspec{Palatino}
|
|
% and syntax-case system
|
|
% }
|
|
\begin{center}
|
|
Ikarus Scheme User's Guide
|
|
\end{center}
|
|
}
|
|
\noindent
|
|
\rule{\textwidth}{6pt}
|
|
{\fontsize{18}{18}
|
|
\fontspec{Hoefler Text Italic}
|
|
\hfill{}
|
|
% Quick Start\\
|
|
% \rnrs{6} Crash Course\\
|
|
% Ikarus
|
|
(Preliminary Document)
|
|
\hfill Version~0.0.2
|
|
}
|
|
\vfill
|
|
{
|
|
\fontsize{24}{24}
|
|
\fontspec{Hoefler Text Italic}
|
|
\hfill{} Abdulaziz Ghuloum
|
|
}
|
|
|
|
{
|
|
\fontsize{18}{18}
|
|
\fontspec{Hoefler Text Italic}
|
|
\hfill{} \today
|
|
}
|
|
|
|
\newpage
|
|
\mbox{}
|
|
\vfill{}
|
|
\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}
|
|
\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 80\%
|
|
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/}.
|
|
|
|
\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.59)
|
|
and GNU Automake (version 1.9) 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.
|
|
|
|
\end{itemize}
|
|
|
|
\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.}
|
|
|
|
|
|
\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 (Build 2007-10-20)
|
|
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}
|
|
|
|
\newpage
|
|
|
|
\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 attempts to guess the location
|
|
of the boot file using the following strategy:
|
|
\begin{enumerate}
|
|
|
|
\item If \texttt{ikarus} was started by supplying an explicit
|
|
location such as
|
|
\texttt{/usr/local/bin/ikarus} or
|
|
\texttt{./ikarus},
|
|
then the name of the boot file is the concatenation of a
|
|
\texttt{.boot} prefix to the executable file name (e.g.
|
|
\texttt{/usr/local/bin/ikarus.boot} or \texttt{./ikarus.boot}).
|
|
|
|
\item Otherwise, \texttt{ikarus} assumes that it was started from a
|
|
location in the \texttt{PATH} environment variable. In that case,
|
|
it searches for the location of \texttt{ikarus} in the
|
|
\texttt{PATH}. If \texttt{ikarus} is found in
|
|
\texttt{/path/to/ikarus}, then the name of the boot file
|
|
becomes \texttt{/path/to/ikarus.boot}.
|
|
|
|
\item Failing both guesses, \texttt{ikarus} prints an error message
|
|
and exits.
|
|
|
|
\end{enumerate}
|
|
|
|
The motivation for this strategy was to allow one to (1) rename the
|
|
\texttt{ikarus} executable and the corresponding boot file to some
|
|
new names (e.g. \texttt{my-ikarus} and \texttt{my-ikarus.boot}) without
|
|
conflicting with other installed versions of Ikarus, and (2)
|
|
override the location of the boot file for testing and building
|
|
purposes (e.g. the installation process using one boot file to build
|
|
another).
|
|
|
|
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{Executable Scripts}
|
|
%FIXME
|
|
%\subsection{Mac OS X}
|
|
%FIXME
|
|
%\subsection{GNU/Linux}
|
|
%FIXME
|
|
%\subsection{Windows/Cygwin}
|
|
%FIXME
|
|
|
|
|
|
\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 a
|
|
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 \emph{loaded}
|
|
imperatively into the top-level environments, \rnrs{6} libraries can
|
|
be \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}
|
|
(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 library.
|
|
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}
|
|
(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}
|
|
(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 libraries or imported from another
|
|
library. Library exports include variables, keywords, record names,
|
|
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}
|
|
(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{set-point-x!} and \texttt{set-point-y!} 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 in such way 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 take 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 procedure
|
|
\texttt{raise-continuable}
|
|
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 calls 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.
|
|
|
|
\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 mutate the variable \texttt{*screen-width*} with
|
|
\texttt{set!}, we could wrap \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 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 used 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 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 \texttt{\#\{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
|
|
\texttt{\#\{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.
|
|
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}
|
|
\index{\#\{pretty unique\}@\texttt{\#\{pretty unique\}} reader syntax}
|
|
\index{\#\{unique\}@\texttt{\#\{unique\}} reader syntax}
|
|
\index{\#:pretty@\texttt{\#:pretty} reader syntax}
|
|
\texttt{\#\{unique-name\}}\\
|
|
\texttt{\#\{pretty-name unique-name\}}\\
|
|
\texttt{\#:pretty-name}
|
|
|
|
Ikarus's \texttt{read} and \texttt{write} procedures extends the
|
|
lexical syntax of Scheme by the ability to read and write gensyms
|
|
using one of the three forms listed above.
|
|
|
|
\texttt{\#\{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 \texttt{\#\{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 the value of \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:
|
|
|
|
\begin{itemize}
|
|
|
|
\item[\texttt{"\~{}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 \texttt{\#\\x} notation.
|
|
|
|
\item[\texttt{"\~{}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.
|
|
|
|
\item[\texttt{"\~{}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.
|
|
|
|
\item[\texttt{"\~{}o"}] is similar to \texttt{"\~{}b"} except that
|
|
the number is printed in octal (base 8).
|
|
|
|
\item[\texttt{"\~{}x"}] is similar to \texttt{"\~{}b"} except that
|
|
the number is printed in hexadecimal (base 16).
|
|
|
|
\item[\texttt{"\~{}d"}] outputs the next argument, which can be an
|
|
exact or inexact number in its decimal (base 10) representation.
|
|
|
|
\item[\texttt{"\~{}\~{}"}] instructs the formatter to place a tilde
|
|
character, \texttt{\~{}}, in the output without consuming an
|
|
argument.
|
|
|
|
\end{itemize}
|
|
|
|
\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}
|
|
> (printf "message: ~s, ~s, and ~s\n" 'symbol "string" #\c)
|
|
message: symbol, "string", and #\c
|
|
|
|
> (printf "message: ~a, ~a, and ~a\n" 'symbol "string" #\c)
|
|
message: symbol, string, and c
|
|
\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)}
|
|
|
|
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}
|
|
|
|
|
|
% FIXME
|
|
% \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 \texttt{\#\{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 value of \texttt{gensym-count}
|
|
starts at 0 when the system starts 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{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 80\% 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 Reader does not recognize \texttt{\#!r6rs} syntax. It should
|
|
be modified to accept both \texttt{\#!r6rs} and \texttt{\#!ikarus}
|
|
so that Ikarus-specific reader features (gensym syntax, record
|
|
syntax, shared graphs, fasl objects, etc.) can be enabled/disabled as needed.
|
|
\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.
|
|
\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 form \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-foldcase 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-copy-bit-field bitwise-bit-set? bitwise-copy-bit
|
|
bitwise-first-bit-set bitwise-bit-count bitwise-bit-field
|
|
bitwise-reverse-bit-field bitwise-rotate-bit-field bitwise-length
|
|
\end{Verbatim}
|
|
|
|
|
|
The following procedures are missing from \texttt{(rnrs arithmetic
|
|
fixnum)}:
|
|
\begin{Verbatim}
|
|
fxbit-count fxbit-field fxbit-set? fxcopy-bit fxcopy-bit-field
|
|
fxfirst-bit-set fxlength fxreverse-bit-field fxrotate-bit-field
|
|
\end{Verbatim}
|
|
|
|
|
|
The following procedures are missing from \texttt{(rnrs hashtables)}:
|
|
\begin{Verbatim}
|
|
hashtable-copy
|
|
make-eqv-hashtable make-hashtable
|
|
hashtable-hash-function hashtable-equivalence-function
|
|
equal-hash string-hash string-ci-hash symbol-hash
|
|
\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 close-port
|
|
get-bytevector-all get-bytevector-some
|
|
get-bytevector-n get-bytevector-n!
|
|
get-char put-char lookahead-char
|
|
get-u8 lookahead-u8 put-u8
|
|
get-string-all get-string-n get-string-n! put-string
|
|
get-datum put-datum
|
|
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
|
|
open-string-input-port open-string-output-port
|
|
output-port-buffer-mode
|
|
transcoded-port port-transcoderput-bytevector
|
|
standard-error-port standard-input-port standard-output-port
|
|
string->bytevector bytevector->string
|
|
\end{Verbatim}
|
|
|
|
|
|
|
|
|
|
\nocite{ghuloum-implicit}
|
|
\nocite{ghuloum-generation}
|
|
|
|
\backmatter
|
|
\appendix
|
|
\bibliographystyle{plain}
|
|
\bibliography{ikarus-users-guide}
|
|
\printindex
|
|
|
|
|
|
|
|
\end{document}
|
|
|
|
|
|
|
|
|
|
|
|
|