This SRFI is currently in final status. Here is an explanation of each status that a SRFI can hold. To provide input on this SRFI, please send email to srfi-96@nospamsrfi.schemers.org
. To subscribe to the list, follow these instructions. You can access previous messages via the mailing list archive.
This SRFI provides the uniform interface which SLIB code calls in order to execute its library system. Parameters and capabilities of the hosting implementation are also captured.
Procedures for certain operations beyond the capabilities of R5RS are defined by this SRFI. Those procedures simply return `#f' if they are not supported by the hosting implementation, allowing the calling program to detect and take appropriate action.
SLIB was first released in 1992. Common-Lisp, then as now, incorporates many practical facilities in a straightforward and consistent fashion, which the Scheme reports do not. Given that ANSI-X3.226 Common-Lisp is widely adopted and in the same family of languages as Scheme, it makes sense to incorporate many of Common-Lisp's constructs for these facilities.
software-type
is inherited from Common-Lisp. In SLIB it
is used primarily for dealing with the file system and commands
executed by the system
call.
Operating-System Names
It would be good to have a definitive set of operating-system names forsoftware-type
. RFC-3232 says that the operating-system list which originated in RFC-952 and ended with RFC-1700 is no longer defined by a RFC:Since 1994, this sequence of RFCs have been replaced by an online database accessible through a web page (currently, www.iana.org). The purpose of the present RFC is to note this fact and to officially obsolete RFC 1700, whose status changes to Historic. RFC 1700 is obsolete, and its values are incomplete and in some cases may be wrong.That was in January 2002. The revival has not occurred. The web page seems to be http://www.iana.org/assignments/operating-system-names. Last updated 2002-04-29, it is six years out-of-date at this writing. Even for the operating-systems it does address, it isn't consistent. Some operating-systems appear without version; some appear only with versions; some appear both ways.We expect this series to be revived in the future by the new IANA organization.
MSDOS
appears without a hyphen or version while the entries for SunOS areSUN-OS-3.5
,SUN-OS-4.0
, andSUN
. For MicroSoft Windows there are 12 varieties (none with MS or Microsoft), all with versions separated by hypens and a lone version-lessWIN32
.
scheme-implementation-home-page
is informational; it is
useful for finding documentation and filing bug reports.
scheme-file-suffix
is needed because `.' is
not the suffix separator on some file-systems (eg. NOSVE).
scheme-file-suffix
would have been more appropriately
named slib-source-file-suffix
. It is not advertised to
SLIB users and used only for loading SLIB files.
slib:features
was originally *features*
(a
la Common-Lisp); it was changed to avoid conflict with Guile, probably
a bad decision.
If a Scheme implementation has a feature close to SLIB's, perhaps
differing only in names or argument order, it is good practice to put
wrapper functions making them compatible in the SRFI-96 file and add
the feature to slib:features
.
most-positive-fixnum
is a hybrid of
most-positive-fixnum
and
array-dimension-limit
from Common-Lisp.
char-code-limit
is also from Common-Lisp.
with-load-pathname
is an extension to
SRFI 59: Vicinity
affecting program-vicinity
.
program-vicinity
, in combination with the
"slib:
" loaders, enables code within a file to load or
access other files in the same directory irrespective of the current
working directory, and without needing absolute pathnames. Thus the
code for a module can be split among several files as exemplified by
slib/macwork.scm, which contains:
(slib:load (in-vicinity (program-vicinity) "mwexpand")) ... (slib:load (in-vicinity (program-vicinity) "mwdenote")) (slib:load (in-vicinity (program-vicinity) "mwsynrul"))
A file's vicinity can also be captured during loading for use while running:
(define jacal-vicinity (program-vicinity)) ... (define (terms) (paginate-file (in-vicinity jacal-vicinity "COPYING"))) (define (help) (paginate-file (in-vicinity jacal-vicinity "HELP")))
tmpnam
is similar to the POSIX function of the same name.
It is essential in some scripting situations (calling other programs
using the system
procedure) on a multi-user file-system.
The Linux manual page for tmpnam
deprecates its use; but
its recommendation to instead use mkstemp
belies the
manual-page author's understanding of scripting.
file-exists?
and delete-file
are the obvious
procedures designated by their names. Although they can always return
`#f', there are modules in SLIB which will not work
correctly in that case. Full implementation of
file-exists?
and delete-file
are strongly
encouraged.
open-file
, close-port
, port?
,
and call-with-open-ports
support both binary and
non-binary files without doubling the number of file-related
procedures (open-binary-input-file, open-binary-output-file, ...).
call-with-open-ports
gives the functionality of
call-with-input-file
and
call-with-output-file
for arbitray numbers of mixed input
and output files by passing in open ports rather than filenames.
current-error-port
is the diagnostic output port called
stderr
in C parlance. If the system doesn't support it,
then current-error-port
can just be set to
current-output-port
.
force-output
is inherited from Common-Lisp. If the
system doesn't support it, then it can just do nothing.
file-position
is inherited from Common-Lisp. It is
active (versus stubbed to return #f) for 7 of SLIB's 20
implementations.
output-port-width
and output-port-height
are
metrics for glass-teletype style output.
defmacro
, gentemp
, and
macroexpand
are inherited from Common-Lisp.
macroexpand
as specified by this SRFI is free to expand
macros or other syntax which was not defined by defmacro
.
SLIB uses defmacro:load
to load module source files which
use defmacro
. defmacro:eval
can be passed
as the argument to the repl:top-level
procedure in the
repl
package to create a read-eval-print loop which understands
defmacro
, even when the underlying implementation does
not.
macro
feature is provided, then the procedures
macro:expand
, macro:eval
, and
macro:load
must be defined.
Of these, only macro:load
is used (for loading packages)
by SLIB code.
macro:eval
would typically be used with the
repl:top-level
procedure in the
repl
package to create a macro-enabled read-eval-print loop.
macro:expand
is indispensable for debugging R5RS Macros;
but implementations are not required to make it functional, in which
case macro:expand
will always return #f
.
with-load-pathname
, SLIB-specific
varieties of load
are required:
slib:load-source
, slib:load-compiled
, and
slib:load
.
slib:eval
is the single-argument eval
from
Common-Lisp. slib:eval-load
is used to create loaders
with a given eval argument.
slib:warn
and slib:error
print out their
arguments, preferably to current-error-port
.
slib:exit
returns if it doesn't work.
Web browsers have become so ubiquitous that programming languagues
should support a simple uniform interface to them.
If an implementation can't invoke a browser, then
browse-url
returns `#f'.
slib:tab
and
slib:form-feed
are needed for formatted output.
When passing functions for mapping, the identity function,
(lambda (obj) obj)
, often arises.
identity
is defined to be that function.
Mutual exclusion primitives such as the
Dijkstra semaphore
and the mutex of
SRFI-18 and
SRFI-21
combine an atomic operation with a wait mechanism.
Wait mechanisms such as calling a scheduler continuation can be
expressed in Scheme; only the atomic operation is novel. So this SRFI
introduces make-exchanger
, returning a procedure which
performs an atomic swap between its argument and an internal location.
t
, nil
, and last-pair
are from
older Scheme-Reports. Too few for their own module, SLIB's defining
them could provoke redefinition warnings; so they are part of SRFI-96.
These constants and procedures describe characteristics of the Scheme and host operating system.
unix
, vms
, macos
,
amiga
, or ms-dos
. The
software-type
of Linux is unix
.
The software-type
of MS-Windows and Vista is
ms-dos
.
#f
or a string containing the URI of the Scheme
implementation's home page.
library-vicinity
on this system; typially it is
".scm".
If the `srfi-0' feature is provided, then
slib/require.scm will add any SRFIs from 0 to 150
discovered using `cond-expand'
.
slib/require.scm will also test for and provide (if
appropriate) the features `inexact',
`rational', `real', `complex',
and `bignum'.
There are features which can't be provided by portable Scheme source
code. They can be made members of `slib:features'
initially or supplied after initialization using
(provide 'feature)
.
feature | description |
---|---|
source | can load Scheme source files
(slib:load-source filebase)
|
compiled | can load compiled files
(slib:load-compiled filebase)
|
char-ready? | has R4RS, R5RS char-ready?
|
object-hash | has R2RS object-hash and object-unhash
|
full-continuation | can return multiple times |
ieee-floating-point | inexact numbers conform to IEEE Standard 754-1985 IEEE Standard for Binary Floating-Point Arithmetic |
sicp | this implementation runs code from Structure and Interpretation of Computer Programs by Abelson and Sussman. |
ed | text editor is invoked by
(ed) or (ed filename)
|
system | posix (system string)
|
getenv | posix (getenv string)
|
program-arguments | (program-arguments) returns
a list of the program name followed by the command-line argument
strings
|
current-time | (current-time)
returns the time in seconds since 1/1/1970
|
If a feature is provided whose name is the same as an SLIB module, then it will provide the procedures and syntax as documented for that SLIB module.
If the feature `r5rs' is provided, then the following features should also be provided:
eval | R5RS two-argument eval
|
values | R5RS values and call-with-values
|
dynamic-wind | R5RS dynamic-wind
|
macro | (R5RS syntax-rules macros) has
define-syntax ,
let-syntax ,
letrec-syntax ,
syntax-rules ,
macro:expand ,
macro:eval , and
macro:load
|
delay | has delay and force
|
multiarg-apply | apply can take more than 2 args
|
char-ready? | has char-ready? procedure
|
rev4-optional-procedures | has list-tail , string-copy , string-fill! , and vector-fill!
|
In implementations which do not support integers of practically unlimited size, most-positive-fixnum is the largest exact integer that may result from computing the length of a list, vector, or string.
char->integer
.
with-load-pathname
must be supported.
with-load-pathname
evaluates thunk in a dynamic scope
where an internal variable is bound to path; the internal
variable is used for messages and program-vicinity
.
with-load-pathname
returns the value returned by thunk.
(tmpnam)
will return
distinct pathnames.
#t
if the specified file exists. Otherwise, returns
#f
. If the underlying implementation does not support this
feature then #f
is always returned.
#f
is returned. Otherwise, #t
is
returned.
open-file
returns a port depending on the symbol modes:
If an implementation does not distinguish between binary and non-binary files, then it must treat rb as r and wb as w.
If the file cannot be opened, either #f is returned or an error is signalled. For output, if a file with the given name already exists, the effect is unspecified.
close-file
has no effect if the file has already been closed.
The value returned is unspecified.
call-with-open-ports
.
call-with-open-ports
calls proc with ports ....
If proc returns, then the ports are closed automatically and the
value yielded by the proc is returned. If proc does not
return, then the ports will not be closed automatically unless it is
possible to prove that the ports will never again be used for a read or
write operation.
(current-output-port)
. If the implementation
does not support it, then force-output
has no effect.
file-position
returns the
current position of the character in port which will next be
read or written. If the implementation does not support
file-position, then #f
is returned.
file-position
sets the
current position in port which will next be read or written. If
successful, #f
is returned; otherwise file-position
returns #f
.
An implementation not supporting file-position
can define
it thus:
(define (file-position port . k) #f)
Returns the width of port, which defaults to
(current-output-port)
if absent. If the width cannot be
determined 79 is returned.
Returns the height of port, which defaults to
(current-output-port)
if absent. If the height cannot be
determined 24 is returned.
defmacro:eval
, defmacro:macroexpand*
,
or defmacro:load
defines a new macro which will henceforth be
expanded when encountered by defmacro:eval
,
defmacro:macroexpand*
, or defmacro:load
.
(gentemp) => scm:G0 (gentemp) => scm:G1
defmacro:load
procedure reads Scheme source code expressions
and definitions from the file and evaluates them sequentially. These
source code expressions and definitions may contain defmacro
definitions.
The defmacro:load
procedure does not affect the values
returned by current-input-port
,
current-error-port
, and current-output-port
.
macroexpand
will
repeatedly expand the form until it is no longer a defmacro
call. A form is considered to be a defmacro call if it is
a cons whose car
is a symbol for which a
defmacro
has been defined.
macroexpand
expands all defmacros, not just the one at
top-level, then the implementation should provide the feature:
defmacroexpand
and:
(define defmacro:expand* defmacroexpand)
defmacro:expand*
is specified thus:
macro
feature is provided, then the procedures
macro:expand
, macro:eval
, and
macro:load
will be defined.
macro:expand
, then #f
is returned.
macro:load
procedure reads Scheme source code expressions and
definitions from the file and evaluates them sequentially. These source
code expressions and definitions may contain macro definitions. The
macro:load
procedure does not affect the values returned by
current-input-port
, current-error-port
, and
current-output-port
.
(slib:load-source "foo")
will load from file
`foo.scm'.
If an implementation does not support compiled code then
slib:load
will be identical to slib:load-source
.
slib:eval
returns the value of obj evaluated in the current top
level environment.
slib:eval-load
procedure does not affect the values returned by
current-input-port
, current-error-port
, and
current-output-port
.
current-error-port
) a warning
message containing its arguments.
current-error-port
) an error
message containing its arguments, aborts evaluation of the current
form, and responds in a system dependent way to the error. Typical
responses are to abort the program or to enter a read-eval-print loop.
#t
, a success
status is returned to the system (if possible). If n is
#f
a failure is returned to the system (if possible). If
n is an integer, then n is returned to the
system (if possible). If the Scheme session cannot exit, then an
unspecified value is returned from slib:exit
.
browse-url
causes the browser to
display the page specified by string url and returns
`#t'.
If the browser is not running, browse-url
starts a
browser displaying the argument url. If the browser starts
as a background job, browse-url
returns `#t'
immediately; if the browser starts as a foreground job, then
browse-url
returns `#t' when the browser
exits; otherwise (if no browser) it returns `#f'.
If (provided? 'getenv)
:
#f
is returned.
If (provided? 'system)
:
If (provided? 'program-arguments)
:
Example:
(identity 3) => 3 (identity '(foo bar)) => (foo bar) (map identity lst) == (copy-list lst)
An exchanger is a procedure of one argument regulating mutually exclusive access to a resource. When a exchanger is called, its current content is returned, while being replaced by its argument in an atomic operation.
Returns a new exchanger with the argument obj as its initial content.
The following code implements Dijkstra semaphores in terms of
make-exchanger
. If run-other-process
does
nothing, then P!
and V!
implement
spin-locks. Normally, run-other-process
would
be a scheduler which would capture its continuation using
call-with-current-continuation
and run pending process
continuations, eventually running this captured continuation.
;;; Init(Semaphore s, Integer v) ;;; { ;;; s := v; ;;; } (define (make-semaphore v) (make-exchanger v)) ;;; P(Semaphore s) ;;; { ;;; wait until s > 0, then s := s-1; ;;; /* must be atomic once s > 0 is detected */ ;;; } (define (P! s) (let loop () (define val (s #f)) (cond ((and val (positive? val)) (s (- val 1))) (else (and val (s val)) (run-other-process) (loop))))) ;;; V(Semaphore s) ;;; { ;;; s := s+1; /* must be atomic */ ;;; } (define (V! s) (let loop () (define val (s #f)) (cond (val (s (+ val 1))) (else (run-other-process) (loop)))))
The following defines were present in Scheme until R4RS (see section `Language changes' in Revised(4) Scheme).
#t
.
#f
.
(last-pair (cons 1 2)) => (1 . 2) (last-pair '(1 2)) => (2) == (cons 2 '())
`require'
module implements the procedure-based
library system whose modules are contained within these files. At the
end of the SRFI-96 files this `require'
module is loaded,
initializing SLIB:
(slib:load (in-vicinity (library-vicinity) "require"))
Scheme implementation | scheme-implementation-type
| SRFI-59 & SRFI-96 implementation |
---|---|---|
Implementation Template | slib/Template.scm | |
Bigloo | Bigloo
| slib/bigloo.init |
Chez | chez
| slib/chez.init |
ELK 3.0 | Elk
| slib/elk.init |
Gambit | gambit
| slib/gambit.init |
Guile | guile
| slib/guile.init |
JScheme | JScheme
| slib/jscheme.init |
Kawa | kawa
| slib/kawa.init |
Larceny | larceny
| larceny/lib/SRFI/srfi-59.sch & larceny/lib/SRFI/srfi-96.sch |
MacScheme | MacScheme
| slib/macscheme.init |
MIT/GNU Scheme | MITScheme
| slib/mitscheme.init |
PLT Scheme | |MzScheme|
| slib/mzscheme.init |
Pocket Scheme | Pocket-Scheme
| slib/pscheme.init |
RScheme | RScheme
| slib/RScheme.init |
Scheme->C | Scheme->C
| slib/scheme2c.init |
Scheme48 | Scheme48
| slib/scheme48.init |
SCM | scm
| slib/scm.init (scm/Init***.scm) |
SCM Mac | scm
| slib/scm.init (scm/Init***.scm) |
scsh | Scsh
| slib/scsh.init |
sisc | sisc
| slib/sisc.init |
STk | |STk|
| slib/STk.init |
T3.1 | T
| slib/t3.init |
umb-scheme | umb-scheme
| slib/umbscheme.init |
VSCM | Vscm
| slib/vscm.init |
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.