stk/Doc/Reference/Reference3.tex

852 lines
29 KiB
TeX

%
% STk Reference manual (Part 3)
%
% Author: Erick Gallesio [eg@unice.fr]
% Creation date: 16-Dec-1997 14:00
% Last file update: 17-May-1999 00:07
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%
%%%% Section 6.22: Sockets
%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{Sockets}
\label{socket-type}
{\stk} defines sockets, on systems which support them, as first class
objects. Sockets permits processes to communicate even if they are on
different machines. Sockets are useful for creating client-server
applications.
\begin{entry}{
\proto{make-client-socket}{ hostname port-number}{procedure}}
\saut
\ide{make-client-socket} returns a new socket object. This socket
establishes a link between the running application listening on port
\var{port-number} of \var{hostname}.
\end{entry}
\begin{entry}{
\proto{socket?}{ socket}{procedure}}
\saut
Returns \schtrue{} if \var{socket} is a socket, otherwise returns
{\schfalse}.
\end{entry}
\begin{entry}{
\proto{socket-host-name}{ socket}{procedure}}
\saut
Returns a string which contains the name of the distant host attached to
\var{socket}. If \var{socket} has been created with \ide{make-client-socket}
this procedure returns the official name of the distant machine used for
connection. If \var{socket} has been created with \ide{make-server-socket},
this function returns the official name of the client connected to the socket.
If no client has used yet the socket, this function returns \schfalse.
\end{entry}
\begin{entry}{
\proto{socket-host-address}{ socket}{procedure}}
\saut
Returns a string which contains the IP\mainindex{IP number} number of
the distant host attached to \var{socket}. If \var{socket} has been
created with \ide{make-client-socket} this procedure returns the
IP number of the distant machine used for connection. If
\var{socket} has been created with \ide{make-server-socket}, this
function returns the address of the client connected to the
socket. If no client has used yet the socket, this function returns
\schfalse.
\end{entry}
\begin{entry}{
\proto{socket-local-address}{ socket}{procedure}}
\saut
Returns a string which contains the IP\mainindex{IP number} number of
the local host attached to \var{socket}.
\end{entry}
\begin{entry}{
\proto{socket-port-number}{ socket}{procedure}}
\saut
Returns the integer number of the port used for \var{socket}.
\end{entry}
\begin{entry}{
\proto{socket-input} { socket}{procedure}
\proto{socket-output}{ socket}{procedure}}
\saut
Returns the file port associated for reading or writing with the program
connected with \var{socket}. If no connection has already been established,
these functions return \schfalse.
The following example shows how to make a client socket. Here we create a
socket on port 13 of the machine ``{\tt kaolin.unice.fr}''\footnote{Port 13
is generally used for testing: making a connection to it permits to know
the distant system's idea of the time of day.}:
\begin{scheme}
(let ((s (make-client-socket "kaolin.unice.fr" 13)))
(format {\schtrue} "Time is: {\tilda}A\verb+\+n" (read-line (socket-input s)))
(socket-shutdown s))
\end{scheme}
\end{entry}
\begin{entry}{
\proto{make-server-socket}{}{procedure}
\proto{make-server-socket}{ port-number}{procedure}}
\saut
\ide{make-server-socket} returns a new socket object. If \var{port-number}
is specified, the socket is listening on the specified port; otherwise, the
communication port is chosen by the system.
\end{entry}
\begin{entry}{
\proto{socket-accept-connection}{ socket}{procedure}}
\saut
\ide{socket-accept-connection} waits for a client connection on the given
\var{socket}. If no client is already waiting for a connection, this
procedure blocks its caller; otherwise, the first connection request on the
queue of pending connections is connected to \var{socket}.
This procedure must be called on a server socket created
with \ide{make-server-socket}. The result of \ide{socket-accept-connection}
is undefined.
The following example is a simple server which waits for a connection
on the port 1234\footnote{Under Unix, you can simply connect to
listening socket with the {\tt telnet} command. With the given
example, this can be
achieved by typing the following command in a window shell:\\
{\tt \$ telnet localhost 1234}}. Once the connection with the
distant program is established, we read a line on the input port
associated to the socket and we write the length of this line on its
output port.
\begin{scheme}
(let ((s (make-server-socket 1234)))
(socket-accept-connection s)
(let ((l (read-line (socket-input s))))
(format (socket-output s) "Length is: {\tilda}A\verb+\+n" (string-length l))
(flush (socket-output s)))
(socket-shutdown s))
\end{scheme}
\end{entry}
\begin{entry}{
\proto{socket-shutdown}{ socket}{procedure}
\proto{socket-shutdown}{ socket close}{procedure}}
\saut
\ide{Socket-shutdown} shutdowns the connection associated to \var{socket}.
\var{Close} is a boolean; it indicates if the socket must be closed or not, when
the connection is destroyed. Closing the socket forbids further connections on
the same port with the \ide{socket-accept-connection} procedure.
Omitting a value for \var{close} implies the closing of socket.
The result of \ide{socket-shutdown} is undefined.
The following example shows a simple server: when there is a new connection
on the port number 1234, the server displays the first line sent to it by the
client, discards the others and go back waiting for further client connections.
\begin{scheme}
(let ((s (make-server-socket 1234)))
(let loop ()
(socket-accept-connection s)
(format {\schtrue} "I've read: {\tilda}A\verb+\+n" (read-line (socket-input s)))
(socket-shutdown s \schfalse)
(loop)))
\end{scheme}
\end{entry}
\begin{entry}{
\proto{socket-down?}{ socket}{procedure}}
\saut
Returns {\schtrue} if \var{socket} has been previously closed
with \ide{socket-shutdown}. It returns {\schfalse} otherwise.
\end{entry}
\begin{entry}{
\proto{socket-dup}{ socket}{procedure}}
\saut
Returns a copy of \var{socket}. The original and the copy socket can be used
interchangeably. However, if a new connection is accepted on one socket,
the characters exchanged on this socket are not visible on the other socket.
Duplicating a socket is useful when a server must accept multiple simultaneous
connections.
The following example creates a server listening on port 1234. This server is
duplicated and, once two clients are present, a message is sent on both
connections.
\begin{scheme}
(define s1 (make-server-socket 1234))
(define s2 (socket-dup s1))
(socket-accept-connection s1)
(socket-accept-connection s2)
;; blocks until two clients are present
(display "Hello,\verb+\+n" (socket-output s1))
(display "world\verb+\+n" (socket-output s2))
(flush (socket-output s1))
(flush (socket-output s2))
\end{scheme}
\end{entry}
\begin{entry}{
\proto{when-socket-ready}{ socket handler}{procedure}
\proto{when-socket-ready}{ socket}{procedure}}
\saut
Defines a handler for \var{socket}. The handler is a thunk which is
executed when a connection is available on \var{socket}. If the special value
\schfalse{} is provided as \var{handler}, the current handler for \var{socket}
is deleted. If a handler is provided, the value returned by
\ide{when-socket-ready} is undefined. Otherwise, it
returns the handler currently associated to \var{socket}.
This procedure, in conjunction with \ide{socket-dup} permits to build
multiple-clients servers which work asynchronously. Such a server is
shown below.
\begin{scheme}
(define p (make-server-socket 1234))
(when-socket-ready p
(let ((count 0))
(lambda ()
(set! count (+ count 1))
(register-connection (socket-dup p) count))))
(define register-connection
(let ((sockets '()))
(lambda (s cnt)
;; Accept connection
(socket-accept-connection s)
;; Save socket somewhere to avoid GC problems
(set! sockets (cons s sockets))
;; Create a handler for reading inputs from this new connection
(let ((in (socket-input s))
(out (socket-output s)))
(when-port-readable in
(lambda ()
(let ((l (read-line in)))
(if (eof-object? l)
;; delete current handler
(when-port-readable in \schfalse)
;; Just write the line read on the socket
(begin
(format out "On {\sharpsign}{\tilda}A --> {\tilda}A\verb+\+n" cnt l)
(flush out))))))))))
\end{scheme}
\end{entry}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%
%%%% Section 6.23: FFI
%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{Foreign Function Interface}
The {\stk} Foreign Function Interface (FFI for short) has been defined
to allow an easy access to functions written in C without needing to
build C-wrappers and, consequently, without any need to write C code.
Note that the FFI is very machine dependent and that it works only on
a limited set of architectures\footnote{In release \stkversion, FFI is
known to work on the following architectures : ix86 (but not yet
MS Windows), Sun Sparc, HP 9000, SGI.}. Moreover, since FFI
allows very low level access, it is easy to crash the interpreter when
using an external C function.
The definition of an external function is done with the syntax
\ide{define-external}. This form takes as arguments a typed list of
parameters and accepts several options to define the name of the
function in the C world, the library which defines this
function,~\ldots{} The type of the function result and the types of
its arguments are defined in Table~\ref{FfiTypes}. This table lists the various
keywords reserved for denoting types and their equivalence between the
C and the Scheme worlds.
\begin{table}[t]
\begin{center}
\begin{tabular}{|p{3cm}|p{5cm}|p{5cm}|}
\hline
\textbf{Name}&\textbf{Corresponding C type}&\textbf{Corresponding Scheme Type }\\
\hline
\hline
\texttt{:void}&\texttt{void}&\emph{None}\\
\hline
\texttt{:char}&\texttt{char}&Scheme character or Scheme integer\\
\hline
\texttt{:short}&\texttt{short~int}&Scheme integer\\
\hline
\texttt{:ushort}&\texttt{unsigned~short~int}&Scheme integer\\
\hline
\texttt{:int}&\texttt{int}&Scheme integer\\
\hline
\texttt{:uint}&\texttt{unsigned~integer}&Scheme integer\\
\hline
\texttt{:long}&\texttt{long~integer}&Scheme integer\\
\hline
\texttt{:ulong}&\texttt{unsigned~long~integer}&Scheme integer\\
\hline
\texttt{:float}&\texttt{float}&Scheme Real\\
\hline
\texttt{:double}&\texttt{double}&Scheme Real\\
\hline
\texttt{:static-ptr}&pointer on a static area&Scheme C-pointer object or Scheme String\\
\hline
\texttt{:dynamic-ptr}~\emph{or} \texttt{(:void~{*})}&pointer on a dynamic area (\texttt{malloc}ated) &
Scheme C-pointer object or Scheme String\\
\hline
\texttt{:string}~\emph{or} \texttt{(:char~{*})}&\texttt{char~{*}}~(pointer on a dynamic string)&Scheme C-pointer object or Scheme String\\
\hline
\texttt{:boolean}&\texttt{int}&Scheme boolean\\
\hline
\end{tabular}
\caption{FFI predefined types}
\label{FfiTypes}
\end{center}
\end{table}
\begin{entry}{
\proto{define-external}{ \hyper{name} \hyper{parameters} \hyper{options}}{\exprtype}}
\saut
The form \ide{define-external} binds a new procedure to \hyper{name}.
The arity of this new procedure is defined by the typed list of
parameters given by \hyper{parameters}. This parameters list is a list
of couples whose first element is the name of the parameter, and the
second one is is a keyword representing its type (see table for
equivalence). All the types defined in Table~\ref{FfiTypes}, except
\texttt{:void}, are allowed for the parameters of a foreign function.
\ide{Define-external} accepts several options:
\begin{itemize}
\item \texttt{:return-type} is used to define the type of the value returned
by the foreign function. The type returned must be chosen in the types specified
in the table. For instance:
\begin{scheme}
(define-external maximum((a :int) (b :int))
:return-type :int)
\end{scheme}
defines the foreign function maximum which takes two C integers and
returns an integer result. Omitting this option default to a result
type equal to \texttt{:void} (i.e. the returned value is
\emph{undefined}).
\item \texttt{:entry-name} is used to specify the name of the foreign
function in the C world. If this option is omitted, the entry-name is
supposed to be \hyper{name}. For instance:
\begin{scheme}
(define-external minimum((a :int) (b :int))
:return-type :int
:entry-name "min")
\end{scheme}
defines the Scheme function \texttt{minimum} whose application
executes the C function called \texttt{min}.
\item \texttt{:library-name} is used to specify the library which contains the
foreign-function. If necessary, the library is loaded before calling the
C function. So,
\begin{scheme}
(define-external minimum((a :int) (b :int))
:return-type :int
:entry-name "min"
:library-name "libminmax")
\end{scheme}
defines a function which will execute the function \texttt{min}
located in the library \texttt{libminmax.xx} (where \texttt{xx} is
the suffix used for shared libraries on the running system (generally \texttt{so}
or \texttt{sl}).
\end{itemize}
Hereafter, there are some commented definitions of external functions:
\begin{scheme}
(define-external isatty ((fd :int))
:return-type :boolean)
(define-external system ((cmd (:char *))) \emph{;; or ((cmd :string))}
:return-type :int)
(define-external malloc ((size :ulong))
:return-type (void *))
(define-external free ( (p (:void *) )) )
\end{scheme}
All these functions are defined in the C standard library, hence it is not
necessary to specify the \texttt{:library-name} option.
\begin{itemize}
\item \texttt{istty} is declared here as a function which takes an
integer and returns a boolean (in fact, the value returned by the C
function \texttt{isatty} is an \texttt{int}, but we ask here to the
FFI system to translate this result as a boolean value in the Scheme
world).
\item \texttt{system} is a function which takes a string as parameter
and returns an \texttt{int}. Note that the type of the parameter,
can be specified as a \texttt{(:char~*)} or \texttt{:string}, as
indicated in Table~\ref{FfiTypes}.
\item \texttt{malloc} is a function which takes one parameter (an
\texttt{unsigned long int} and which returns a \texttt{(:void~*)} (or
\texttt{:dynamic-ptr}). Specifying that the result is a dynamic
pointer (instead of a static one) means that we want that the Garbage
Collector \mainindex{Garbage Collector} takes into account the area
allocated by the C function \texttt{malloc} (i.e. if this area
becomes no more accessible, the GC disposes it with the
\texttt{free} function\footnote{Pointers defined with
\texttt{:dynamic-ptr} are always unallocated with \texttt{free}.
Consequently, areas allocated with another allocator than the
standard one must be declared as \texttt{:static-ptr} and freed
by hand}.
\item \texttt{free} is a function which takes a dynamic pointer and
deallocates the area it points. Since the definition of this function
specifies no result type, it is supposed to be \texttt{:void}\footnote{
Usage of malloc and free are for illustration purpose here. Their usage
in a program must be avoided, if possible, because it can have
interact badly with the way the interpreter manages memory or it
can conduct to \emph{crashing} programs if you don't take care.}.
\end{itemize}
External functions can also have a variable number of parameters by using
the standard Scheme \emph{dot} notation. For instance,
\begin{scheme}
(define-external printf ((format :string) . l)
:return-type :int)
\end{scheme}
defines a Scheme function with one or more parameters (the first one
being a string). Of course, the parameters which constitute the
variable parameters list must have a type which appears in the third
column of Table~\ref{FfiTypes}. Some examples using the \texttt{printf} function:
\begin{scheme}
(printf "This is a \verb+%+s test" "good")
\lev \emph{displays}~~~This is a good test
(printf \verb+"char: '%c' Dec: '%04d' Hex '%04x'" #\space +100 100)
\lev \emph{displays}~~~char: ' ' Dec: '0100' Hex '0064'
\end{scheme}
\begin{note}
The types \texttt{:dynamic-ptr}, \texttt{:static-ptr} and
\texttt{:string} are compatible when used for foreign function
parameter. This gives a semantic which is similar to the one of C,
where \texttt{void~*} is a compatible with all other pointer types.
However, differenciating those types is useful for converting
the function return value to a proper Scheme type.
\end{note}
\par{}
\vspace{2mm}
\begin{note}
When a function has a \texttt{:return-type} which is
\texttt{:string}, \texttt{:dynamic-ptr} or \texttt{:static-ptr}, and
the return value is the C \texttt{NULL} pointer, the Scheme value
returned by the function is, by convention, equal to \schfalse. For
instance, the GNU \texttt{readline} function allows line editing
\emph{\`a la} Emacs returns \texttt{NULL} when the user has typed an
end of file. The following lines show how to make a simple shell-like
toplevel using FFIs.
\begin{scheme}
(define-external system ((var (:char *)))
:return-type :int)
(define-external readline ((prompt :string))
:library-name "libreadline"
:return-type :string)
\textbf{;; A Shell-like toplevel}
(do ((l (readline "?> ") (readline "?> ")))
((not l))
(system l))
\end{scheme}
\end{note}
\begin{note}
The same convention also applies for parameters of type
\texttt{:string}, \texttt{:dynamic-ptr} or \texttt{:static-ptr}: they accept
the special value \schfalse{} as a synonym of the C \texttt{NULL} pointer.
\end{note}
\end{entry}
\begin{entry}{
\proto{external-exists?}{ entry} {procedure}
\proto{external-exists?}{ entry library} {procedure}}
\saut
Returns \schtrue{} if \var{entry} is defined as an external symbol in
\var{library}. If \var{library} is not provided the symbol is searched
in the \stk{} interpreter or in libraries that it uses.
This function can be useful to define external functions conditionally:
\begin{scheme}
(when (external-exists? "dup2")
(define-external dup2 ((oldfd :int) (newfd :int))
:return-type :int))
\end{scheme}
\end{entry}
\begin{entry}{
\proto{c-string->string}{ str} {procedure}}
\saut
STk strings are more general than C strings since they accept null
character. \ide{c-string->string} takes an area of characters built
by a call to a foreign function (typically the result of a function
returning a \texttt{:static-ptr}, \texttt{:dynamic-ptr} or
\texttt{:string}) and convert it to a proper Scheme string.
\begin{scheme}
(define-external sprintf ((str :string) (format :string) . l)
:return-type :int)
\verb+(let ((str (make-string 5 #\?)))+
\verb+ (sprintf str "%x" 100)+
\verb+ (cons str (C-string->string str)))+
\lev \verb+("64\0??" . "64")+
\end{scheme}
\end{entry}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%
%%%% Section 6.24: Misc
%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{Miscellaneous}
This section lists the primitives defined in {\stk} that did not fit
anywhere else.
\begin{entry}{
\proto{eval}{ \hyper{expr}}{syntax}
\proto{eval}{ \hyper{expr} \hyper{environment}}{syntax}}
\saut
Evaluates \hyper{expr} in the given environment. \hyper{Environment} may be
omitted, in which case it defaults to the global environment.
\begin{scheme}
(define foo (let ((a 1)) (lambda () a)))
(foo) \ev 1
(eval '(set! a 2) (procedure-environment foo))
(foo) \ev 2
\end{scheme}
\end{entry}
\begin{entry}{
\proto{version}{} {procedure}}
\saut
returns a string identifying the current version of {\stk}.
\end{entry}
\begin{entry}{
\proto{machine-type}{} {procedure}}
\saut
returns a string identifying the kind of machine which is running the
interpreter. The form of the result is {\tt [os-name]-[os-version]-[processor-type]}.
\end{entry}
\begin{entry}{
\proto{random}{ n} {procedure}}
\saut
returns an integer in the range 0, $\var{n}-1$ inclusive.
\end{entry}
\begin{entry}{%
\proto{set-random-seed!} { seed} {procedure}}
\saut
Set the random seed to the specified \var{seed}. {\tt Seed} must be an integer
which fits in a C {\tt long int}.
\end{entry}
\begin{entry}{
\proto{eval-string}{ string environment} {procedure}}
\saut
Evaluates the contents of the given \var{string} in the given
\var{environment} and returns its result.
If \var{environment} is omitted it defaults to the global
environment. If evaluation leads to an error, the result of \ide{eval-string}
is undefined.
\begin{scheme}
(define x 1)
(eval-string "(+ x 1)") \lev 2
(eval-string "x" (let ((x 2)) (the-environment))) \lev 2
\end{scheme}
\end{entry}
\begin{entry}{
\proto{read-from-string}{ \hyper{string}} {procedure}}
\saut
Performs a read from the given \var{string}. If \var{string} is the empty
string, an end of file object is returned. If an error occurs during string
reading, the result of \ide{read-from-string} is undefined.
\begin{scheme}
(read-from-string "123 456") \lev 123
(read-from-string "") \lev an eof object
\end{scheme}
\end{entry}
\begin{entry}{
\proto{dump}{ string} {procedure}}
\saut
\ide{Dump} grabs the current continuation
\mainindex{continuation} and creates an image of the current {\stk}
interpreter in the file whose name is \var{string}{\footnote{
Image creation is not yet implemented on all systems. The current version
(\stkversion) allows image dumping only on some platforms:
SunOs~4.1.x, Linux~1, FreeBsd}}.
This image can be used later to restart the interpreter from the saved
state. See the {\stk} man page about the {\tt -image} option for more details.
\begin{note}
Image creation cannot be done if Tk is initialized.
\end{note}
\end{entry}
\begin{entry}{
\proto{trace-var}{ symbol thunk} {procedure}}
\saut
\ide{Trace-var} call the given \var{thunk} when the value
of the variable denoted by \var{symbol} is changed.
\begin{scheme}
(define x 1)
(define y 0)
(trace-var 'x (lambda () (set! y 1)))
(set! x 2)
(cons x y) \lev (2 . 1)
\end{scheme}
\begin{note}
Several traces can be associated with a single symbol. They are executed in
reverse order to their definition. For instance, the execution of
\begin{scheme}
(begin
(trace-var 'z (lambda () (display "One")))
(trace-var 'z (lambda () (display "Two")))
(set! z 10))
\end{scheme}
will display the string {\tt"Two"} before the string {\tt"One"} on the
current output port.
\end{note}
\end{entry}
\begin{entry}{
\proto{untrace-var}{ symbol} {procedure}}
\saut
Deletes all the traces associated to the variable denoted by \var{symbol}.
\end{entry}
\begin{entry}{
\proto{error}{ string \vri{string} \vrii{obj} \dotsfoo}{procedure}}
\saut
\ide{error} prints the \var{obj}s according to the specification given in
\var{string} on the current error port (or in an error window if Tk is
initialized\index{Tk toolkit}\index{toolkit}). The specification string
follows the ``tilde conventions'' of \ide{format}(see \ref{format}). Once the
message is printed, execution returns to toplevel.
\end{entry}
\begin{entry}{
\proto{gc}{}{procedure}}
\saut
Runs the garbage collector. See \ref{GCSTART} for the signals associated to
garbage collection.
\end{entry}
\begin{entry}{
\proto{gc-stats}{}{procedure}}
\saut %
Provides some statistics about current memory usage. This procedure is
primarily for debugging the {\stk} interpreter, hence its weird
printing format.
\end{entry}
\begin{entry}{
\proto{expand-heap}{ n}{procedure}}
\saut %
Expand the heap so that it will contains at least \var{n}
cells. Normally, the heap automatically grows when more memory is needed.
However, using only automatic heap growing is sometimes very penalizing.
This is particularly true for programs which uses a lot of temporary data
(which are not pointed by any a variable) and a small amount of global
data. In this case, the garbage collector will be often called and the heap
will not be automatically expanded (since most of the consumed heap will be
reclaimed by the GC). This could be annoying specially for program where
response time is critical. Using \ide{expand-heap} permits to enlarge
the heap size (which is set to 20000 cells by default), to avoid those
continual calls to the GC.
\end{entry}
\begin{entry}{
\proto{get-internal-info}{}{procedure}}
\saut %
Returns a 7-length vector which contains the following informations:
\begin{enumerate}
\item[0] total cpu used in milli-seconds
\item[1] number of cells currently in use.
\item[2] total number of allocated cells
\item[3] number of cells used since the last call to \ide{get-internal-info}
\item[4] number of gc runs
\item[5] total time used in the gc
\item[6] a boolean indicating if Tk is initialized
\end{enumerate}
\end{entry}
\begin{entry}{
\proto{sort}{ obj predicate}{procedure}}
\saut
\var{Obj} must be a list or a vector. \ide{Sort} returns a copy of \var{obj} sorted
according to \var{predicate}. \var{Predicate} must be a procedure which takes
two arguments and returns a true value if the first argument is strictly ``before''
the second.
\begin{scheme}
(sort '(1 2 -4 12 9 -1 2 3) <)
\ev (-4 -1 1 2 2 3 9 12)
(sort \sharpsign("one" "two" "three" "four")
(lambda (x y) (> (string-length x) (string-length y))))
\ev \sharpsign("three" "four" "one" "two")
\end{scheme}
\end{entry}
\begin{entry}{
\label{uncode}
\proto{uncode}{ form}{procedure}}
\saut %
When {\stk} evaluates an expression it encodes it so that further
evaluations of this expression will be more efficient. Since encoded
forms are generally difficult to read, \ide{uncode} can be used to
(re-)obtain the original form.
\begin{scheme}
(define (foo a b)
(let ((x a) (y (+ b 1))) (cons x y)))
(procedure-body foo)
\ev (lambda (a b)
(let ((x a) (y (+ b 1))) (cons x y)))
(foo 1 2) \ev (1 . 3)
(procedure-body foo)
\ev (lambda (a b)
({\sharpsign}let (x y)
({\sharpsign}<local a @0,0)>
({\sharpsign}<global +> {\sharpsign}<local b @0,1)> 1))
({\sharpsign}<global cons> {\sharpsign}<local x @0,0)>
{\sharpsign}<local y @0,1)>)))
(uncode (procedure-body foo))
\ev (lambda (a b)
(let ((x a) (y (+ b 1))) (cons x y)))
\end{scheme}
\begin{note}
When a macro has been directly expanded into the macro call code, it is not
possible to retrieve the original macro call. Set \ide{*debug*} to
{\schtrue} to avoid macro expansion in-lining.
\end{note}
\end{entry}
\begin{entry}{
\proto{time} { \hyper{expr}}{macro}}
\saut
Evaluates the expression \hyper{expr} in the current environment. Prints the
elapsed CPU time and the number of conses used before returning the result of
this evaluation.
\end{entry}
\begin{entry}{%
\proto{apropos}{ symbol}{ procedure}}
\saut
\ide{Apropos} returns a list of symbol whose print name contains the characters
of \var{symbol}. Symbols are searched for in the current environment.
\begin{scheme}
(apropos 'cadd) \lev (caddar caddr cadddr)
\end{scheme}
\end{entry}
\begin{entry}{%
\proto{inspect}{ obj}{ procedure}}
\saut %
\ide{Inspect} permits to graphically inspect an object. The first call
of this procedure creates a top level window containing the object to
inspect and its current value. If the inspector window is already on
screen, \var{obj} will be appended to the list of inspected objects.
The inspector window contains menus which permit to call the viewer or
detailer on each inspected object. See the on-line documentation for
further details. A view of the general inspector is given in figure~1.
\begin{note}
Tk must be initialized to use \ide{inspect}.
\end{note}
\begin{figure}
\centerline{\psfig{figure={Inspector.ps}}}
\caption{A view of the Inspector}
\end{figure}
\end{entry}
\begin{entry}{%
\proto{view}{ obj}{ procedure}}
\saut %
\ide{View} permits to obtain a graphical representation of an {\stk}
object. The type of representation depends on the type of the viewed
object. Here again, menus are provided to switch to the inspector or
to the detailer. See the on-line documentation for more details. A
snapshot of the viewer is given in figure~2.
\begin{note}
Tk must be initialized to use \ide{view}.
\end{note}
\begin{figure}
\centerline{\psfig{figure={View.ps}}}
\caption{A view of the Viewer}
\end{figure}
\end{entry}
\begin{entry}{%
\proto{detail}{ obj}{ procedure}}
\saut %
\ide{detail} permits to display the fields of a composite Scheme
object. The type of detailer depends on the type of the composite
object detailed. Here again, menus are provided to go to the inspector
or to the viewer. See the on-line documentation for more details.
Figure~3 shows the detailer examining a {\em tk-command}.
\begin{note}
Tk must be initialized to use \ide{detail}.
\end{note}
\begin{figure}
\centerline{\psfig{figure={Detail.ps}}}
\caption{A view of the Detailer}
\end{figure}
\end{entry}
\begin{entry}{%
\proto{quit}{ retcode} {procedure}
\proto{quit}{} {procedure}
\proto{exit}{ retcode} {procedure}
\proto{exit}{} {procedure}
\proto{bye}{ retcode} {procedure}
\proto{bye}{} {procedure}}
\saut
Exits the {\stk} interpreter with the specified integer return code. If
omitted, the interpreter terminates with a return code of 0.
\end{entry}
%%% Local Variables:
%%% mode: latex
%%% TeX-master: "manual"
%%% End: