stk/Doc/Reference/Reference1.tex

1451 lines
46 KiB
TeX

%
% STk Reference manual (Part 1)
%
% Author: Erick Gallesio [eg@unice.fr]
% Creation date: ??-Nov-1993 ??:??
% Last file update: 18-Apr-1998 14:47
%
\section*{Introduction}
This document provides a complete list of procedures and special forms
implemented in version {\stkversion} of {\stk}. Since {\stk} is (nearly)
compliant with the language described in the {\em Revised$^{4}$ Report on the
Algorithmic Language Scheme} \mainindex{R4RS}(denoted {\rrrr} hereafter{\footnote{The {\em
Revised$^{4}$ Report on the Algorithmic Language Scheme} is available
through anonymous FTP from {\tt ftp.cs.indiana.edu} in the directory
{\tt /pub/scheme-repository/doc}}})\cite{R4RS}, the organization of
this manual follows the {\rrrr} and only describes extensions.
\section{Overview of \stk}
Today's graphical toolkits for applicative languages are often not
satisfactory. Most of the time, they ask the user to be an X window system
\mainindex{X window system} expert and force him/her to cope with arcane
details such as server connections and event queues. This is a real
problem, since programmers using this kind of languages are generally not
inclined to system programming, and few of them will bridge the gap between
the different abstraction levels.
~~~~Tk\index{Tk toolkit}\index{toolkit} is a powerful graphical tool\-kit
promising to fill that gap. It was developed at the University of Berkeley
by John Ousterhout~\cite{Ouster-Tk}. The toolkit offers high level widgets
such as buttons or menus and is easily programmable, requiring little
knowledge of X fundamentals. Tk relies on an interpretative shell-like
language named Tcl~\cite{Ouster-Tcl}.
~~~~{\stk} is an implementation of the Scheme programming language,
providing a full integration of the Tk toolkit. In this implementation,
Scheme establishes the link between the user and the Tk toolkit, replacing
Tcl.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{Lexical conventions}
\subsection{Identifiers}
Syntactic keywords can be used as variables in \stk. Users must be
aware that this extension of the language could lead to ambiguities in
some situations.
\subsection{Comments}
There are three types of comments in {\stk}:
\begin{enumerate}
\item a semicolon (;) indicates the start of a comment.
This kind of comment extends to the end of the line (as described in \rrrr).
\item multi-lines comment use the classical Lisp convention: a comment
begins with \verb+#|+ and ends with \verb+|#+.
\item comments can also be introduced by \sharpsign$!$. This
extension is particularly useful for building {\stk} scripts. On most
Unix implementations, if the first line of a script looks like this:
\begin{scheme}
\sharpsign$!$/usr/local/bin/stk -file
\end{scheme}
then the script can be started directly as if it were a binary. {\stk}
is loaded behind the scenes and reads and executes the script as a
Scheme program. Of course this assumes that {\stk} is located in {\tt
/usr/local/bin}.
\end{enumerate}
\subsection{Other notations}
{\stk} accepts all the notations defined in {\rrrr} plus
\begin{description}{}{}
\setbox0\hbox{\tt \char"5B{} \char"5D{} }
\item[\copy0] Brackets are equivalent to parentheses. They are used
for grouping and to notate lists. A list opened with a left square
bracket must be closed with a right square bracket
(section~\ref{listsection}).
\item[\tt:] A colon at the beginning of a symbol introduces a keyword.
Keywords are described in section~\ref{keywords}.
\item[\tt\sharpsign.<expr>] is read as the evaluation of the Scheme
expression {\tt <expr>}. The evaluation is done during the
\ide{read} process, when the \var{\sharpsign.} is encountered.
Evaluation is done in the environment of the current module.
\begin{scheme}
(define foo 1)
\sharpsign.foo \lev 1
'(foo \sharpsign.foo \sharpsign.(+ foo foo)) \lev (foo 1 2)
(let ((foo 2))
\sharpsign.foo) \lev 1
\end{scheme}
\end{description}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{Basic concepts}
{\doc}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{Expressions}
\subsection{Primitive expression types}
\begin{entry}{%
\proto{quote}{ \hyper{datum}}{\exprtype}
\pproto{\singlequote\hyper{datum}}{\exprtype}}
\saut
The quoting mechanism is identical to {\rrrr}. Keywords (see
section~\ref{keywords}), as
numerical constants, string constants, character constants, and boolean
constants evaluate ``to themselves''; they need not be quoted.
\begin{scheme}
'"abc" \ev "abc"
"abc" \ev "abc"
'145932 \ev 145932
145932 \ev 145932
'\schtrue \ev \schtrue
\schtrue \ev \schtrue
':key \ev {:key}
:key \ev {:key}
\end{scheme}
\begin{note}
{\rrrr} requires to quote constant lists and constant vectors. This
is not necessary with {\stk}.
\end{note}
\end{entry}
\begin{entry}{%
\pproto{(\hyper{operator} \hyperi{operand} \dotsfoo)}{\exprtype}}
\saut
{\doc} Furthermore, \hyper{operator} can be a macro (see section~\ref{macros}).
\end{entry}
\begin{entry}{%
\proto{lambda}{ \hyper{formals} \hyper{body}}{\exprtype}
\proto{if}{ \hyper{test} \hyper{consequent} \hyper{alternate}} {\exprtype}
\proto{if}{ \hyper{test} \hyper{consequent}}{\exprtype}
\proto{set!}{ \hyper{variable} \hyper{expression}}{\exprtype}}
\saut
\doc
\end{entry}
\subsection{Derived expression types}
\begin{entry}{%
\proto{cond}{ \hyperi{clause} \hyperii{clause} \dotsfoo}{\exprtype}
\proto{case}{ \hyper{key} \hyperi{clause} \hyperii{clause} \dotsfoo}{\exprtype}
\proto{and}{ \hyperi{test} \dotsfoo}{\exprtype}
\proto{or}{ \hyperi{test} \dotsfoo}{\exprtype}}
\saut
\doc
\end{entry}
\begin{entry}{%
\proto{when}{ \hyper{test} \hyperi{expression} \hyperii{expression} \dotsfoo}{\exprtype}}
\saut
If the \hyper{test} expression yields a true value, the \hyper{expression}s are
evaluated from left to right and the value of the last \hyper{expression} is
returned.
\end{entry}
\begin{entry}{%
\proto{unless}{ \hyper{test} \hyperi{expression} \hyperii{expression} \dotsfoo}
{\exprtype}}
\saut
If the \hyper{test} expression yields a false value, the \hyper{expression}s are
evaluated from left to right and the value of the last \hyper{expression} is
returned.
\end{entry}
\begin{entry}{%
\proto{let}{ \hyper{bindings} \hyper{body}}{\exprtype}
\proto{let}{ \hyper{variable} \hyper{bindings} \hyper{body}}{\exprtype}
\proto{let*}{ \hyper{bindings} \hyper{body}}{\exprtype}}
\saut
\doc
\end{entry}
\begin{entry}{%
\proto{fluid-let}{ \hyper{bindings} \hyper{body}}{\exprtype}}
\saut
The \var{bindings} are evaluated in the current environment, in some
unspecified order, the current values of the variables present in
\var{bindings} are saved, and the new evaluated values are assigned to the
\var{bindings} variables. Once this is done, the expressions of \var{body}
are evaluated sequentially in the current environment; the value of the
last expression is the result of {\tt fluid-let}. Upon exit, the stored
variables values are restored. An error is signalled if any of the
\var{bindings} variable is unbound.
\begin{scheme}
(let* ((a 'out)
(f (lambda () a)))
(list a
(fluid-let ((a 'in)) (f))
a)) \lev (out in out)
\end{scheme}
When the body of a \ide{fluid-let} is exited by invoking a continuation,
the new variable values are saved, and the variables are set to their old
values. Then, if the body is reentered by invoking a continuation, the old
values are saved and new values are restored. The following example illustrates
this behaviour
\begin{scheme}
(let ((cont \schfalse)
(l '())
(a 'out))
(set! l (cons a l))
(fluid-let ((a 'in))
(set! cont (call/cc (lambda (k) k)))
(set! l (cons a l)))
(set! l (cons a l))
(if cont (cont \schfalse) l)) \lev (out in out in out)
\end{scheme}
\end{entry}
\begin{entry}{%
\proto{letrec}{ \hyper{bindings} \hyper{body}}{\exprtype}
\proto{begin}{ \hyperi{expression} \hyperii{expression} \dotsfoo}{\exprtype}
\proto{do} { \hyper{inits} \hyper{test} \hyper{body}}{\exprtype}
\proto{delay}{ \hyper{expression}}{\exprtype}
\proto{quasiquote}{ \hyper{template}}{\exprtype} \nopagebreak
\pproto{\backquote\hyper{template}}{\exprtype}}
\saut
\doc
\end{entry}
\begin{entry}{
\proto{dotimes}{ (var count) \hyperi{expression} \hyperii{expression} \dotsfoo} {\exprtype}
\proto{dotimes}{ (var count result) \hyperi{expression} \hyperii{expression} \dotsfoo} {\exprtype}}
\saut
\ide{Dotimes} evaluates the \var{count} form, which must return an
integer. It then evaluates the \hyper{expression}s once for each
integer from zero (inclusive) to \var{count} (exclusive), in order,
with the variable \var{var} bound to the integer; if the value of
\var{count} is zero or negative, then the \hyper{expression}s are not
evaluated. When the loop completes, \var{result} is evaluated and its
value is returned as the value of the \ide{dotimes} expression. If
\var{result} is omitted, \ide{dotimes} returns {\schfalse}.
\begin{scheme}
(let ((l '()))
(dotimes (i 4 l)
(set! l (cons i l)))) \lev (3 2 1 0)
\end{scheme}
\end{entry}
\begin{entry}{
\proto{while} { \hyper{test} \hyperi{expression} \hyperii{expression} \dotsfoo}{\exprtype}}
\saut
\ide{While} evaluates the \hyper{expression}s until \hyper{test}
returns a false value. The value of a \ide{while} construct is unspecified.
\end{entry}
\begin{entry}{
\proto{until} { \hyper{test} \hyperi{expression} \hyperii{expression} \dotsfoo}{\exprtype}}
\saut
\ide{Until} evaluates the \hyper{expression}s while \hyper{test}
returns a false value. The value of an \ide{unless} construct is unspecified.
\end{entry}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{Program structure}
\doc
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{Standard procedures}
\label{initialenv}
\label{builtinchapter}
\mainindex{initial environment}
\mainindex{top level environment}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{Booleans}
\label{booleansection}
In {\stk} the boolean value {\schfalse} is different from the empty list, as
required by \rrrr.
\begin{entry}{%
\proto{not}{ obj}{procedure}
\proto{boolean?}{ obj}{procedure}}
\saut
\doc
\end{entry}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{Equivalence predicates}
\label{equivalencesection}
\begin{entry}{%
\proto{eqv?}{ \vari{obj} \varii{obj}}{procedure}}
\saut
{\stk} extends the \ide{eqv?} predicate defined in the {\rrrr} to take
keywords into account: if \vari{obj} and \varii{obj} are both
keywords, the \ide{eqv?} predicate will yield {\schtrue} if and only
if
\begin{scheme}
(string=? (keyword->string obj1)
(keyword->string obj2))
\ev \schtrue%
\end{scheme}
\end{entry}
%%%% EQ?
\begin{entry}{%
\proto{eq?}{ \vari{obj} \varii{obj}}{procedure}}
\saut
{\stk} extends the \ide{eq?} predicate defined in {\rrrr} to take
keywords into account. On keywords, \ide{eq?} behaves like \ide{eqv?}.
\begin{scheme}
(eq? :key :key) \ev \schtrue
\end{scheme}
\end{entry}
%%%% EQUAL?
\begin{entry}{%
\proto{equal?}{ \vari{obj} \varii{obj}}{procedure}}
\saut
{\doc}
\end{entry}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{Pairs and lists}
\label{listsection}
\begin{entry}{%
\proto{pair?}{ obj}{procedure}
\proto{cons}{ \vari{obj} \varii{obj}}{procedure}
\proto{car}{ pair}{procedure}
\proto{cdr}{ pair}{procedure}
\proto{set-car!}{ pair obj}{procedure}
\proto{set-cdr!}{ pair obj}{procedure}
\setbox0\hbox{\tt(cadr \var{pair})}
\setbox1\hbox{procedure}
\proto{caar}{ pair}{procedure}
\proto{cadr}{ pair}{procedure}
\pproto{\hbox to 1\wd0 {\hfil$\vdots$\hfil}}{\hbox to 1\wd1 {\hfil$\vdots$\hfil}}
\proto{cdddar}{ pair}{procedure}
\proto{cddddr}{ pair}{procedure}
\proto{null?}{ obj}{procedure}
\proto{list?}{ obj}{procedure}
\proto{list}{ \var{obj} \dotsfoo}{procedure}
\proto{length}{ list}{procedure}
\proto{append}{ list \dotsfoo}{procedure}}
\saut
\doc
\end{entry}
\begin{entry}{%
\proto{append!}{ list \ldots}{procedure}}
\saut
Returns a list consisting of the elements of the first \var{list}
followed by the elements of the other lists, as with \texttt{append}.
The differenece with \texttt{append} is that the arguments are {\em
changed} rather than {\em copied}.
\begin{scheme}
(append! '(1 2) '(3 4) '(5 6)) \lev '(1 2 3 4 5 6)
(let ((l1 '(1 2))
(l2 '(3 4))
(l3 '(5 6)))
(append! l1 l2 l3)
(list l1 l2 l3)) \lev ((1 2 3 4 5 6) (3 4 5 6) (5 6))
\end{scheme}
\end{entry}
\begin{entry}{%
\proto{reverse}{ list}{procedure}
\proto{list-tail}{ list \vr{k}}{procedure}
\proto{list-ref}{ list \vr{k}}{procedure}
\proto{memq}{ obj list}{procedure}
\proto{memv}{ obj list}{procedure}
\proto{member}{ obj list}{procedure}
\proto{assq}{ obj alist}{procedure}
\proto{assv}{ obj alist}{procedure}
\proto{assoc}{ obj alist}{procedure}}
\saut
\doc
\end{entry}
\begin{entry}{%
\proto{remq}{ obj list}{procedure}
\proto{remv}{ obj list}{procedure}
\proto{remove}{ obj list}{procedure}}
\saut
Each function return a copy of \var{list} where all the occurences of \var{obj}
have been deleted. The predicate used to test the presence of \var{obj} in
\var{list} is respectively \ide{eq}, \ide{eqv} and \ide{equal}.
\begin{note}
It is not an error if \var{obj} does not appear in \var{list}.
\end{note}
\begin{scheme}
(remq 1 '(1 2 3)) \ev (2 3)
(remq "foo" '("foo" "bar")) \ev ("foo" "bar")
(remove "foo" '("foo" "bar"))
\ev ("bar")
\end{scheme}
\end{entry}
\begin{entry}{%
\proto{last-pair}{ list}{procedure}}
\saut
Returns the last pair of \var{list}\footnote{\ide{Last-pair} was a standard
procedure in {\rthree}.}.
\begin{scheme}
(last-pair '(1 2 3)) \lev 3
(last-pair '(1 2 . 3)) \lev (2 . 3)
\end{scheme}
\end{entry}
\begin{entry}{%
\proto{list*}{ obj}{procedure}}
\saut
\ide{list*} is like \ide{list} except that the last argument to \ide{list*} is
used as the {\em cdr} of the last pair constructed.
\begin{scheme}
(list* 1 2 3) \ev (1 2 . 3)
(list* 1 2 3 '(4 5)) \ev (1 2 3 4 5)
\end{scheme}
\end{entry}
\begin{entry}{%
\proto{copy-tree}{ obj}{procedure}}
\saut
\ide{Copy-tree} recursively copies trees of pairs. If \ide{obj} is not
a pair, it is returned; otherwise the result is a new pair whose {\em
car} and {\em cdr} are obtained by calling \ide{copy-tree} on the
{\em car} and {\em cdr} of \ide{obj}, respectively.
\end{entry}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{Symbols}
\label{symbolsection}
The {\stk} reader can cope with symbols whose names contain special
characters or letters in the non standard case. When a symbol is
read, the parts enclosed in bars (``\verb+|+'') will be entered
verbatim into the symbol's name. The ``\verb+|+'' characters are not
part of the symbol; they only serve to delimit the sequence of
characters that must be entered ``as is''. In order to maintain
read-write invariance, symbols containing such sequences of special
characters will be written between a pair of ``\verb+|+''
\begin{scheme}
'|x| \ev x
(string->symbol "X") \ev |X|
(symbol->string '|X|) \ev "X"
'|a b| \ev |a b|
'a|B|c \ev |aBc|
(write '|FoO|) \ev writes the string "|FoO|"
(display '|FoO|) \ev writes the string "FoO"
\end{scheme}
\begin{note}
This notation has been introduced because {\rrrr} states that case
must not be significant in symbols whereas the Tk toolkit is case
significant (or more precisely thinks it runs over Tcl which is case
significant). %% axe:
However, symbols containing the character ``\verb+|+'' itself still
can't be read in.
\end{note}
\begin{entry}{%
\proto{symbol?}{ obj}{procedure}}
\saut
Returns \schtrue{} if \var{obj} is a symbol, otherwise returns {\schfalse}.
\begin{scheme}
(symbol? 'foo) \ev \schtrue
(symbol? (car '(a b))) \ev \schtrue
(symbol? "bar") \ev \schfalse
(symbol? 'nil) \ev \schtrue
(symbol? '()) \ev \schfalse
(symbol? \schfalse) \ev \schfalse
(symbol? :key) \ev \schfalse
\end{scheme}
\end{entry}
\begin{entry}{%
\proto{symbol->string}{ symbol}{procedure}
\proto{string->symbol}{ string}{procedure}}
\saut
\doc
\end{entry}
\begin{entry}{%
\proto{gensym}{}{procedure}
\proto{gensym}{ prefix}{procedure}}
\saut
\ide{Gensym} creates a new symbol. The print name of the generated symbol
consists of a prefix (which defaults to {\tt "G"}) followed by the decimal
representation of a number. If \var{prefix} is specified, it must be a
string.
\begin{scheme}
(gensym) \lev |G100|
(gensym "foo-") \lev foo-101
\end{scheme}
\end{entry}
\subsection {Numbers}
The only numbers recognized by {\stk} are integers (with arbitrary
precision) and reals (implemented as C {\tt double float}s).
\begin{entry}{%
\proto{number?}{ obj}{procedure}}
\saut
Returns {\schtrue} if \var{obj} is a number, otherwise returns {\schfalse}.
\end{entry}
\begin{entry}{%
\proto{complex?}{ obj}{procedure}}
\saut
Returns the same result as \var{number?}. Note that complex numbers
are not implemented.
\end{entry}
\begin{entry}{%
\proto{real?}{ obj}{procedure}}
\saut
Returns {\schtrue} if \var{obj} is a float number, otherwise returns
{\schfalse}.
\end{entry}
\begin{entry}{%
\proto{rational?}{ obj}{procedure}}
\saut
Returns the same result as \var{number?}. Note that rational numbers are not
implemented.
\end{entry}
\begin{entry}{%
\proto{integer?}{ obj}{procedure}}
\saut
Returns {\schtrue} if \var{obj} is an integer, otherwise returns {\schfalse}.
\begin{note}
The {\stk} interpreter distinguishes between integers which fit in a
C {\tt long int} (minus 8 bits) and integers of arbitrary length
(aka ``bignums''). This should be transparent to the user, though.
%% shouldn't it? :-) axe
\end{note}
\end{entry}
\begin{entry}{%
\proto{exact?}{ \vr{z}}{procedure}
\proto{inexact?}{ \vr{z}}{procedure}}
\saut
In this implementation, integers (C {\tt long int} or ``bignums'') are exact
numbers and floats are inexact.
\end{entry}
\begin{entry}{%
\proto{=}{ \vri{z} \vrii{z} \vriii{z} \dotsfoo}{procedure}
\proto{<}{ \vri{x} \vrii{x} \vriii{x} \dotsfoo}{procedure}
\proto{>}{ \vri{x} \vrii{x} \vriii{x} \dotsfoo}{procedure}
\proto{<=}{ \vri{x} \vrii{x} \vriii{x} \dotsfoo}{procedure}
\proto{>=}{ \vri{x} \vrii{x} \vriii{x} \dotsfoo}{procedure}
\proto{zero?} { z}{procedure}
\proto{positive?} { z}{procedure}
\proto{negative?} { z}{procedure}
\proto{odd?} { z}{procedure}
\proto{even?} { z}{procedure}
\proto{max}{ \vri{x} \vrii{x} \dotsfoo}{procedure}
\proto{min}{ \vri{x} \vrii{x} \dotsfoo}{procedure}
\proto{+}{ \vri{z} \dotsfoo}{procedure}
\proto{*}{ \vri{z} \dotsfoo}{procedure}
\proto{-}{ \vri{z} \vrii{z}}{procedure}
\proto{-}{ \vr{z}}{procedure}
\proto{-}{ \vri{z} \vrii{z} \dotsfoo}{procedure}
\proto{/}{ \vri{z} \vrii{z}}{procedure}
\proto{/}{ \vr{z}}{procedure}
\proto{/}{ \vri{z} \vrii{z} \dotsfoo}{procedure}
\proto{abs}{ x}{procedure}
\proto{quotient}{ \vri{n} \vrii{n}}{procedure}
\proto{remainder}{ \vri{n} \vrii{n}}{procedure}
\proto{modulo}{ \vri{n} \vrii{n}}{procedure}
\proto{gcd}{ \vri{n} \dotsfoo}{procedure}
\proto{lcm}{ \vri{n} \dotsfoo}{procedure}}
\saut
\doc
\end{entry}
\begin{entry}{%
\proto{numerator}{ \vr{q}}{procedure}
\proto{denominator}{ \vr{q}}{procedure}}
\saut
Not implemented.
\end{entry}
\begin{entry}{%
\proto{floor}{ x}{procedure}
\proto{ceiling}{ x}{procedure}
\proto{truncate}{ x}{procedure}
\proto{round}{ x}{procedure}}
\saut
\doc
\end{entry}
\begin{entry}{%
\proto{rationalize}{ x y}{procedure}}
\saut
not yet implemented.
\end{entry}
\begin{entry}{%
\proto{exp}{ \vr{z}}{procedure}
\proto{log}{ \vr{z}}{procedure}
\proto{sin}{ \vr{z}}{procedure}
\proto{cos}{ \vr{z}}{procedure}
\proto{tan}{ \vr{z}}{procedure}
\proto{asin}{ \vr{z}}{procedure}
\proto{acos}{ \vr{z}}{procedure}
\proto{atan}{ \vr{z}}{procedure}
\proto{atan}{ \vr{y} \vr{x}}{procedure}
\proto{sqrt}{ \vr{z}}{procedure}
\proto{expt}{ \vri{z} \vrii{z}}{procedure}}
\saut
\doc
\end{entry}
\begin{entry}{
\proto{make-rectangular}{ \vri{x} \vrii{x}}{procedure}
\proto{make-polar}{ \vri{x} \vrii{x}}{procedure}
\proto{real-part}{ \vr{z}}{procedure}
\proto{imag-part}{ \vr{z}}{procedure}
\proto{magnitude}{ \vr{z}}{procedure}
\proto{angle}{ \vr{z}}{procedure}}
\saut
These procedures are not implemented since complex numbers are not defined.
\end{entry}
\begin{entry}{%
\proto{exact->inexact}{ \vr{z}}{procedure}
\proto{inexact->exact}{ \vr{z}}{procedure}
\proto{number->string}{ number}{procedure}
\proto{number->string}{ number radix}{procedure}
\proto{string->number}{ string}{procedure}
\proto{string->number}{ string radix}{procedure}}
\saut
\doc
\end{entry}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{Characters}
\mainindex{characters}
Table 1 gives the list of allowed character names together with their ASCII
equivalent expressed in octal.
\begin{table}[t]
{\small
\begin{center}
% \begin{tabular}{|c|c|c|} \hline
% {\em name}&{\em value}&{\em alternate name} \\
% \hline
% nul &000 & null\\
% soh &001&\\
% stx &002&\\
% etx &003&\\
% eot &004&\\
% enq &005&\\
% ack &006&\\
% bel &007 & bell\\[2mm]
% bs &010 & backspace\\
% ht &011&\\
% tab &011&\\
% nl &012 & newline\\
% vt &013&\\
% np &014 & page\\
% cr &015 & return\\
% so &016&\\
% si &017&\\[2mm]
% dle &020&\\
% dc1 &021&\\
% dc2 &022&\\
% dc3 &023&\\
% dc4 &024&\\
% nak &025&\\
% syn &026&\\
% etb &027&\\[2mm]
% can &030&\\
% em &031&\\
% sub &032&\\
% esc &033 & escape\\
% fs &034&\\
% gs &035&\\
% rs &036&\\
% us &037&\\[2mm]
% sp &040 & space\\[2mm]
% del &177 & delete\\
\begin{tabular}{|c|c|c||c|c|c|} \hline
{\em name}&{\em value}&{\em alternate name}&{\em name}&{\em value}&{\em alternate name} \\
\hline
nul &000 & null & bs &010 & backspace\\
soh &001& & ht &011 & tab\\
stx &002& & nl &012 & newline\\
etx &003& & vt &013&\\
eot &004& & np &014 & page\\
enq &005& & cr &015 & return\\
ack &006& & so &016&\\
bel &007 & bell & si &017&\\[2mm]
%%%%%
dle &020& & can &030&\\
dc1 &021& & em &031&\\
dc2 &022& & sub &032&\\
dc3 &023& & esc &033 & escape\\
dc4 &024& & fs &034&\\
nak &025& & gs &035&\\
syn &026& & rs &036&\\
etb &027& & us &037&\\[2mm]
%%%%%
sp &040 & space&&&\\[2mm]
%%%%%
del &177 & delete&&&\\
\hline
\end{tabular}
\end{center}
}
\caption {Valid character names }
\end{table}
\begin{entry}{%
\proto{char?}{ obj}{procedure}
\proto{char=?}{ \vari{char} \varii{char}}{procedure}
\proto{char<?}{ \vari{char} \varii{char}}{procedure}
\proto{char>?}{ \vari{char} \varii{char}}{procedure}
\proto{char<=?}{ \vari{char} \varii{char}}{procedure}
\proto{char>=?}{ \vari{char} \varii{char}}{procedure}
\proto{char-ci=?}{ \vari{char} \varii{char}}{procedure}
\proto{char-ci<?}{ \vari{char} \varii{char}}{procedure}
\proto{char-ci>?}{ \vari{char} \varii{char}}{procedure}
\proto{char-ci<=?}{ \vari{char} \varii{char}}{procedure}
\proto{char-ci>=?}{ \vari{char} \varii{char}}{procedure}
\proto{char-alphabetic?}{ char}{procedure}
\proto{char-numeric?}{ char}{procedure}
\proto{char-whitespace?}{ char}{procedure}
\proto{char-upper-case?}{ letter}{procedure}
\proto{char-lower-case?}{ letter}{procedure}
\proto{char->integer}{ char}{procedure}
\proto{integer->char}{ \vr{n}}{procedure}
\proto{char-upcase}{ char}{procedure}
\proto{char-downcase}{ char}{procedure}}
\saut
\doc
\end{entry}
\subsection{Strings}
{\stk} string constants allow the insertion of arbitrary characters by
encoding them as escape sequences, introduced by a backslash
(\backwhack{}). The valid escape sequences are shown in Table 2. For
instance, the string
\begin{scheme}
"ab\backwhack{}040c\backwhack{}nd\backwhack{}
e"
\end{scheme}
is the string consisting of the characters \sharpsign\backwhack{a},
\sharpsign\backwhack{b},\sharpsign\backwhack{space}, \sharpsign\backwhack{c},
\sharpsign\backwhack{newline}, \sharpsign\backwhack{d} and \sharpsign\backwhack{e}.
\begin{table}[t]
{\small
\begin{center}
\begin{tabular}{|l|l|} \hline
\multicolumn{1}{|c|}{\em Sequence}&\multicolumn{1}{|c|}{\em Character inserted}\\
\hline
\backwhack{b}& Backspace \\
\backwhack{e}& Escape \\
\backwhack{n}& Newline \\
\backwhack{t}& Horizontal Tab \\
\backwhack{n}& Carriage Return \\
\backwhack{0abc}& ASCII character with octal value abc \\
\backwhack{\tt<newline>}& None (permits to enter a string on several lines)\\
\backwhack{\tt<other>}& {\tt<other>}\\
\hline
\end{tabular}
\end{center}
}
\caption {String escape sequences}
\end{table}
\begin{entry}{%
\proto{string?}{ obj}{procedure}
\proto{make-string}{ \vr{k}}{procedure}
\proto{make-string}{ \vr{k} char}{procedure}
\proto{string}{ char \dotsfoo}{procedure}
\proto{string-length}{ string}{procedure}
\proto{string-ref}{ string \vr{k}}{procedure}
\proto{string-set!}{ string k char}{procedure}
\proto{string=?}{ \vari{string} \varii{string}}{procedure}
\proto{string-ci=?}{ \vari{string} \varii{string}}{procedure}
\proto{string<?}{ \vari{string} \varii{string}}{procedure}
\proto{string>?}{ \vari{string} \varii{string}}{procedure}
\proto{string<=?}{ \vari{string} \varii{string}}{procedure}
\proto{string>=?}{ \vari{string} \varii{string}}{procedure}
\proto{string-ci<?}{ \vari{string} \varii{string}}{procedure}
\proto{string-ci>?}{ \vari{string} \varii{string}}{procedure}
\proto{string-ci<=?}{ \vari{string} \varii{string}}{procedure}
\proto{string-ci>=?}{ \vari{string} \varii{string}}{procedure}
\proto{substring}{ string start end}{procedure}
\proto{string-append}{ \var{string} \dotsfoo}{procedure}
\proto{string->list}{ string}{procedure}
\proto{list->string}{ chars}{procedure}
\proto{string-copy}{ string}{procedure}
\proto{string-fill!}{ string char}{procedure}}
\saut
\doc
\end{entry}
\begin{entry}{%
\proto{string-find?}{ \vari{string} \varii{string}}{procedure}}
\saut
Returns {\schtrue} if \vari{string} appears somewhere in
\varii{string}; otherwise returns {\schfalse}.
\end{entry}
\begin{entry}{%
\proto{string-index}{ \vari{string} \varii{string}}{procedure}}
\saut
Returns the index of where \vari{string} is a substring of
\varii{string} if it exists; returns {\schfalse} otherwise.
\begin{scheme}
(string-index "ca" "abracadabra") \lev 4
(string-index "ba" "abracadabra") \lev \schfalse
\end{scheme}
\end{entry}
\begin{entry}{%
\proto{split-string}{ string}{procedure}
\proto{split-string}{ string delimiters}{procedure}}
\saut
This function parses \vari{string} and returns a list of tokens ended by
a character of the \vari{delimiters} string. If \vari{delimiters} is omitted,
it defaults to a string containing a space, a tabulation and a newline
characters.
\begin{scheme}
(split-string "/usr/local/bin" "/") \ev ("usr" "local" "bin")
(split-string "once upon a time") \ev ("once" "upon" "a" "time")
\end{scheme}
\end{entry}
\begin{entry}{%
\proto{string-lower}{ string}{procedure}}
\saut
Returns a string in which all upper case letters of \ide{string} have been
replaced by their lower case equivalent.
\end{entry}
\begin{entry}{%
\proto{string-upper}{ string}{procedure}}
\saut
Returns a string in which all lower case letters of \ide{string} have been
replaced by their upper case equivalent.
\end{entry}
\subsection {Vectors}
\begin{entry}{%
\proto{vector?}{ obj}{procedure}
\proto{make-vector}{ k}{procedure}
\proto{make-vector}{ k fill}{procedure}
\proto{vector}{ obj \dotsfoo}{procedure}
\proto{vector-length}{ vector}{procedure}
\proto{vector-ref}{ vector k}{procedure}
\proto{vector-set!}{ vector k obj}{procedure}
\proto{vector->list}{ vector}{procedure}
\proto{list->vector}{ list}{procedure}
\proto{vector-fill!}{ vector fill}{procedure}}
\saut
\doc
\end{entry}
\begin{entry}{%
\proto{vector-copy}{ vector}{procedure}}
\saut
returns a copy of \var{vector}.
\end{entry}
\begin{entry}{%
\proto{vector-resize}{ vector size}{procedure}}
\saut
\var{vector-resize} physically changes the size of \var{vector}. If
\var{size} is greater than the old vector size, the contents of the
newly allocated cells are undefined.
\end{entry}
\subsection{Control features}
\begin{entry}{%
\proto{procedure?}{ obj}{procedure}
\proto{apply}{ proc args}{procedure}
\proto{apply}{ proc \vari{arg} $\ldots$ args}{procedure}
\proto{map}{ proc \vari{list} \varii{list} \dotsfoo}{procedure}
\proto{for-each}{ proc \vari{list} \varii{list} \dotsfoo}{procedure}
\proto{force}{ promise}{procedure}}
\saut
\doc
\end{entry}
\begin{entry}{%
\proto{call-with-current-continuation}{ proc}{procedure}
\proto{call/cc} { proc}{procedure}}
\saut
\ide{Call/cc} is a shorter name for \ide{call-with-current-continuation}.
\mainindex{continuation}
\end{entry}
\begin{entry}{%
\proto{closure?}{ obj}{procedure}}
\saut
returns {\schtrue} if \var{obj} is a procedure created by evaluating a
lambda expression, otherwise returns {\schfalse}.
\end{entry}
\begin{entry}{%
\proto{primitive?}{ obj}{procedure}}
\saut
returns {\schtrue} if \var{obj} is a procedure and is not a closure,
otherwise returns {\schfalse}.
\end{entry}
\begin{entry}{%
\proto{promise?} { obj}{procedure}}
\saut
returns {\schtrue} if \var{obj} is an object returned by the
application of \ide{delay}, otherwise returns {\schfalse}.
\end{entry}
\begin{entry}{%
\proto{continuation?} { obj} {procedure}}
\saut
\mainindex{continuation}
returns {\schtrue} if \var{obj} is a continuation obtained by
\ide{call/cc}, otherwise returns {\schfalse}.
\end{entry}
\begin{entry}{%
\proto{dynamic-wind}{ \hyperi{thunk} \hyperii{thunk} \hyperiii{thunk}} {procedure}}
\saut
\hyperi{Thunk}, \hyperii{thunk} and \hyperiii{thunk} are called in
order. The result of \ide{dynamic-wind} is the value returned by
\hyperii{thunk}. If \hyperii{thunk} escapes from its continuation
during evaluation (by calling a continuation obtained by \ide{call/cc}
or on error), \hyperiii{thunk} is called. If \hyperii{thunk} is later
reentered, \hyperi{thunk} is called.
\end{entry}
\begin{entry}{%
\proto{catch} { \hyperi{expression} \hyperii{expression} \dotsfoo} {\exprtype}}
\saut
The \hyper{expression}s are evaluated from left to right. If an error
occurs, evaluation of the \hyper{expression}s is aborted, and {\schtrue}
is returned to \ide{catch}'s caller. If evaluation finishes without
an error, \ide{catch} returns {\schfalse}.
%% axe: why isn't this a procedure taking a thunk?
\begin {scheme}
(let* ((x 0)
(y (catch
(set! x 1)
(/ 0) ; causes a "division by 0" error
(set! x 2))))
(cons x y)) \lev (1 . {\schtrue})
\end{scheme}
\end{entry}
\begin{entry}{%
\proto{procedure-body}{ \hyper{procedure}} {procedure}}
\saut
returns the body of \hyper{procedure}. If \hyper{procedure} is not a closure,
\ide{procedure-body} returns {\schfalse}.
\begin{scheme}
(define (f a b)
(+ a (* b 2)))
(procedure-body f) \ev (lambda (a b)
(+ a (* b 2)))
(procedure-body car) \ev \schfalse
\end{scheme}
\end{entry}
\subsection{Input and output}
\label{inputoutput}
The {\rrrr} states that ports represent input and output devices.
However, it defines only ports which are attached to files. In
{\stk}, ports can also be attached to strings or to a external command
input or output. String ports are similar to file ports, except that
characters are read from (or written to) a string rather than a file.
External command input or output ports are implemented with Unix pipes
and are called pipe ports. A pipe port is created by specifying the
command to execute prefixed with the string {\tt "|~"}. Specification
of a pipe port can occur everywhere a file name is needed.
\begin{entry}{%
\proto{call-with-input-file}{ string proc}{procedure}
\proto{call-with-output-file}{ string proc}{procedure}}
\saut
\begin{note}
if {\var string} starts with the two characters {\tt "| "}, these procedures
return a pipe port. Consequently, it is not possible to open a file
whose name starts with those two characters.
\end{note}
\end{entry}
\begin{entry}{%
\proto{call-with-input-string}{ string proc}{procedure}}
\saut
behaves exactly as \ide{call-with-input-file} except that the port passed to
\var{proc} is the string port obtained from \var{string}.
\begin{scheme}
(call-with-input-string "123 456" (lambda (x) (read x))) \lev 123
\end{scheme}
\end{entry}
\begin{entry}{%
\proto{call-with-output-string}{ proc}{procedure}}
\saut
\var{Proc} should be a procedure of one argument.
\ide{Call-with-output-string} calls \var{proc} with a freshly opened
output string port. The result of this procedure is a string
containing all the text that has been written on the string port.
\begin{scheme}
(call-with-output-string
(lambda (x) (write 123 x) (display "Hello" x))) \lev "123Hello"
\end{scheme}
\end{entry}
\begin{entry}{%
\proto{input-port?}{ obj}{procedure}
\proto{output-port?}{ obj}{procedure}}
\saut
\doc
\end{entry}
\begin{entry}{%
\proto{input-string-port?}{ obj}{procedure}
\proto{output-string-port?}{ obj}{procedure}}
\saut
Returns \schtrue{} if \var{obj} is either an input or an output string port,
otherwise returns {\schfalse}.
\end{entry}
\begin{entry}{%
\proto{current-input-port}{}{procedure}
\proto{current-output-port}{}{procedure}}
\saut
\doc
\end{entry}
\begin{entry}{%
\proto{current-error-port}{}{procedure}}
\saut
Returns the current default error port.
\end{entry}
\begin{entry}{%
\proto{with-input-from-file}{ string thunk}{procedure}
\proto{with-output-to-file}{ string thunk}{procedure}}
\saut
\doc
The following example uses a pipe port opened for reading. It permits
to read all the lines produced by an external {\tt ls} command
(i.e. the ouput of the {\tt ls} command is {\em redirected} to the
Scheme pipe port).
\begin{scheme}
(with-input-from-file "\verb+|+ ls -ls"
(lambda ()
(do ((l (read-line) (read-line)))
((eof-object? l))
(display l)
(newline))))
\end{scheme}
Hereafter is another example of Unix command redirection. This time,
it is the standard input of the Unix command which is redirected.
\begin{scheme}
(with-output-to-file "| mail root"
(lambda()
(format {\schtrue} "A simple mail sent from STk\verb+\+n")))
\end{scheme}
\end{entry}
\begin{entry}{%
\proto{with-input-from-string}{ string thunk}{procedure}}
\saut
A string port is opened for input from \var{string}. \ide{Current-input-port}
is set to the port and \var{thunk} is called. When \var{thunk} returns,
the previous default input port is restored.
\ide{With-input-from-string} returns the value yielded by \var{thunk}.
\begin{scheme}
(with-input-from-string "123 456" (lambda () (read))) \lev 123
\end{scheme}
\end{entry}
\begin{entry}{%
\proto{with-output-to-string}{ thunk}{procedure}}
\saut
A string port is opened for output. \ide{Current-output-port}
is set to it and \var{thunk} is called. When the \var{thunk} returns,
the previous default output port is restored. \ide{With-output-to-string}
returns the string containing all the text written on the string port.
\begin{scheme}
(with-output-to-string (lambda () (write 123) (write "Hello"))) \lev "123Hello"
\end{scheme}
\end{entry}
\begin{entry}{%
\proto{open-input-file}{ filename}{procedure}
\proto{open-output-file}{ filename}{procedure}}
\saut
\doc
\begin{note}
if {\var filename} starts with the string {\tt "| "}, these procedure
return a pipe port. Consequently, it is not possible to open a file
whose name starts with those two characters.
\end{note}
\end{entry}
\begin{entry}{%
\proto{open-input-string}{ string}{procedure}}
\saut
Returns an input string port capable of delivering characters from
\var{string}.
\end{entry}
\begin{entry}{%
\proto{open-output-string}{}{procedure}}
\saut
Returns an output string port capable of receiving and collecting characters.
\end{entry}
\begin{entry}{%
\proto{get-output-string}{ port}{procedure}}
\saut
Returns a string containing all the text that has been written on the
output string \var{port}.
\begin{scheme}
(let ((p (open-output-string)))
(display "Hello, world" p)
(get-output-string p)) \lev "Hello, world"
\end{scheme}
\end{entry}
\begin{entry}{%
\proto{close-input-port}{ port}{procedure}
\proto{close-output-port}{ port}{procedure}}
\saut
\doc
\end{entry}
\begin{entry}{%
\proto{read}{}{procedure}
\proto{read}{ port}{procedure}
\proto{read-char}{}{procedure}
\proto{read-char}{ port}{procedure}
\proto{peek-char}{}{procedure}
\proto{peek-char}{ port}{procedure}
\proto{char-ready?}{}{procedure}
\proto{char-ready?}{ port}{procedure}}
\saut
\doc
\end{entry}
%% axe: the question of `new line or not new line?' was left open
\begin{entry}{%
\proto{read-line}{}{procedure}
\proto{read-line}{ port}{procedure}}
\saut
Reads the next line available from the input port \var{port} and
returns it as a string. The terminating newline is not included in the
string. If no more characters are available, an end of file object is
returned. \var{Port} may be omitted, in which case it defaults to the
value returned by \ide{current-input-port}.
\end{entry}
\begin{entry}{%
\proto{write}{ obj}{procedure}
\proto{write}{ obj port}{procedure}
\proto{display}{ obj}{procedure}
\proto{display}{ obj port}{procedure}
\proto{newline}{}{procedure}
\proto{newline}{ port}{procedure}
\proto{write-char}{ char}{procedure}
\proto{write-char}{ char port}{procedure}}
\saut
\doc
\end{entry}
\begin{entry}{%
\proto{format}{ port string \vri{obj} \vrii{obj} \dotsfoo}{procedure}}
\saut
\label{format}
Writes the \var{obj}s to the given \var{port}, according to the format
string \var{string}. \var{String} is written literally, except for
the following sequences:
%
\begin{itemize}
\item \tilda{}a or \tilda{}A is replaced by the printed representation of the
next \var{obj}.
\item \tilda{}s or \tilda{}S is replaced by the ``slashified'' printed
representation of the next \var{obj}.
\item \tilda{}\tilda{} is replaced by a single tilde.
\item \tilda{}\% is replaced by a newline
\end{itemize}
\var{Port} can be a boolean, a port or a string port. If \var{port}
is {\schtrue}, output goes to the current output port; if \var{port}
is {\schfalse}, the output is returned as a string. Otherwise, the output is
printed on the specified port.
%
\begin{scheme}
(format {\schfalse} "A test.") \lev "A test."
(format {\schfalse} "A \tilda{}a." "test") \lev "A test."
(format {\schfalse} "A \tilda{}s." "test") \lev "A \backwhack{}"test\backwhack{}"."
\end{scheme}
\end{entry}
\begin{entry}{%
\proto{get-output-string}{ port}{procedure}}
\saut
Returns the string associated with the output string \var{port}.
\begin{scheme}
(let ((p (open-output-string)))
(display "Hello, world" p)
(get-output-string p)) \lev "Hello, world"
\end{scheme}
\end{entry}
\begin{entry}{%
\proto{flush}{}{procedure}
\proto{flush}{ port}{procedure}}
\saut
Flushes the buffer associated with the given \var{port}. The
\var{port} argument may be omitted, in which case it defaults to the value
returned by \ide{current-output-port}.
\end{entry}
\begin{entry}{%
\proto{when-port-readable}{ port handler}{procedure}
\proto{when-port-readable}{ port}{procedure}}
\saut
When \var{port} is ready for reading, \var{handler}, which must be a
thunk, is called leaving the current evaluation suspended. When
\var{handler} execution is terminated, normal evaluation is resumed at
its suspension point. If the special value \schfalse{} is provided as
\var{handler}, the current handler for \var{port} is deleted. If a
handler is provided, the value returned by \ide{when-port-readable} is
undefined. Otherwise, it returns the handler currently associated to
\var{port}.
The example below shows a simple usage of the \ide{when-port-readable} procedure:
the command \var{cmd} is run with its output redirected in a pipe associated to the
\var{p} Scheme port.
\begin{scheme}
(define p (open-input-file "| cmd"))
(when-port-readable p
(lambda()
(let (( l (read-line p)))
(if (eof-object? l)
(begin
;; delete handler
(when-port-readable p \schfalse)
;; and close port
(close-input-port p))
(format \schtrue{} "Line read: \tilda{}A\verb+\+n" l)))))
\end{scheme}
\end{entry}
\begin{entry}{%
\proto{when-port-writable}{ port handler}{procedure}
\proto{when-port-writable}{ port}{procedure}}
\saut
When \var{port} is ready for writing, \var{handler}, which must be a
thunk, is called leaving the current evaluation suspended. When
\var{handler} execution is terminated, normal evaluation is resumed at
its suspension point. If the special value \schfalse{} is provided as
\var{handler}, the current handler for \var{port} is deleted. If a
handler is provided, the value returned by \ide{when-port-writable} is
undefined. Otherwise, it returns the handler currently associated to
\var{port}.
\end{entry}
\begin{entry}{%
\proto{load}{ filename}{procedure}
\proto{load}{ filename module}{procedure}}
\saut
The first form is identical to \rrrr{}. The second one loads the
content of \var{filename} in the given \var{module} environment.
\begin{note}
The \var{load} primitive has been extended to allow loading of
object files, though this is not implemented on all systems.
This extension uses dynamic loading on systems which support it
\footnote{Current version (\stkversion) allows dynamic loading
only on some platforms: SunOs~4.1.x, SunOs~5.x, NetBSD~1.0,
Linux~2.0, HPUX, Irix 5.3}. See~\cite{STkExtension} for more details.
\end{note}
\end{entry}
\begin{entry}{%
\proto{try-load}{ filename}{procedure}
\proto{try-load}{ filename module}{procedure}}
\saut
Tries to load the file named \var{filename}. If \var{filename} exists and is
readable, it is loaded, and \ide{try-load} returns {\schtrue}.
Otherwise, the result of the call is {\schfalse}.
The second form of \var{try-load} tries to load the content of \var{filename}
in the given \var{module} environment.
\end{entry}
\begin{entry}{%
\proto{autoload}{ filename \hyperi{symbol} \hyperii{symbol} \dotsfoo}{\exprtype}}
\saut
Defines \hyper{symbol}s as autoload symbols associated to file
\var{filename}.
First evaluation of an autoload symbol will cause the loading of its
associated file in the module environment in which the autoload was done.
\var{Filename} must provide a definition for the symbol which
lead to its loading, otherwise an error is signaled.
\end{entry}
\begin{entry}{%
\proto{autoload?}{ symbol module}{procedure}}
\saut
Returns {\schtrue} if \var{symbol} is an autoload symbol in \var{module}
environment ; returns {\schfalse} otherwise.
\end{entry}
\begin{entry}{%
\proto{require}{ string}{procedure}
\proto{provide}{ string}{procedure}
\proto{provided?}{ string}{procedure}}
\saut
\ide{Require} loads the file whose name is \var{string} if it was not
previously ``provided''.\ide{Provide} permits to store \var{string} in
the list of already provided files. Providing a file permits to avoid
subsequent loads of this file. \ide{Provided?} returns {\schtrue} if
\var{string} was already provided; it returns {\schfalse} otherwise.
\end{entry}
\begin{entry}{%
\proto{transcript-on}{ filename}{procedure}\nopagebreak{}
\proto{transcript-off}{}{procedure}}
\saut
Not implemented.
\end{entry}
\begin{entry}{%
\proto{open-file}{ filename mode}{procedure}}
\saut
Opens the file whose name is \var{filename} with the specified
\var{mode}. \var{Mode} must be ``r'' to open for reading or ``w''
to open for writing. If the file can be opened, \var{open-file}
returns the port associated with the given file, otherwise it returns
{\schfalse}. Here again, the ``magic'' string {\tt "|~``} permit to
open a pipe port.
\end{entry}
\begin{entry}{%
\proto{close-port}{ port}{procedure}}
\saut
Closes \var{port}. If \var{port} denotes a string port, further
reading or writing on this port is disallowed.
\end{entry}
\begin{entry}{%
\proto{transcript-on}{ filename}{procedure}\nopagebreak{}
\proto{transcript-off}{}{procedure}}
\saut
Not implemented.
\end{entry}
\begin{entry}{%
\proto{port->string}{ port}{procedure}
\proto{port->list}{ reader port}{procedure}
\proto{port->string-list}{ port}{procedure}
\proto{port->sexp-list}{ port}{procedure}}
\saut
Those procedures are utility for generally parsing input streams. Their
specification has been stolen from {\tt scsh}.
\ide{Port->string} reads the input port until eof, then returns the
accumulated string.
\begin{scheme}
(port->string (open-input-file "\verb+|+ (echo AAA; echo BBB)"))
\ev "AAA\verb+\+nBBB\verb+\+n"
(define exec
(lambda (command)
(call-with-input-file
(string-append "\verb+|+ " command) port->string)))
(exec "ls -l") \ev a string which contains the result of "ls -l"
\end{scheme}
\ide{Port->list} uses the \var{reader} function to repeatedly read
objects from \var{port}. Thes objects are accumulated in a list which
is returned upon eof.
\begin{scheme}
(port->list read-line (open-input-file "\verb+|+ (echo AAA; echo BBB)"))
\ev ("AAA" "BBB")
\end{scheme}
\ide{Port->string-list} reads the input port line by line until eof,
then returns the accumulated list of lines. This procedure is defined as
\begin{scheme}
(define port->string-list (lambda (p)(port->list read-line p)))
\end{scheme}
\ide{Port->sexp-list} repeatedly reads data from the port until eof,
then returns the accumulated list of items. This procedure is defined as
\begin{scheme}
(define port->sexp-list (lambda (p) (port->list read p)))
\end{scheme}
For instance, the following expression gives the list of users currently
connected on the machine running the {\stk} interpreter.
\begin{scheme}
(port->sexp-list (open-input-file "| users"))
\end{scheme}
\end{entry}
%%% Local Variables:
%%% mode: latex
%%% TeX-master: "manual"
%%% End: