Title

Environment Inquiry

Author

John Cowan

Status

This SRFI is currently in ``final'' status. To see an explanation of each status that a SRFI can hold, see here. To provide input on this SRFI, please mail to <srfi minus 112 at srfi dot schemers dot org>. See instructions here to subscribe to the list. You can access previous messages via the archive of the mailing list. You can access post-finalization messages via the archive of the mailing list.

Abstract

This is a proposal for environment inquiry, providing human-readable information at run time about the hardware and software configuration on which a Scheme program is being executed. They are mostly based on Common Lisp, with additions from the Posix uname() system call.

Issues

None for this draft.

Rationale

The feature symbols of the R7RS-small cond-expand syntax provide the ability to conditionally compile code based on particular properties of an implementation that it sees fit to publish. The features procedure, which returns the list of feature symbols of the implementation, provides run-time access to the same set of properties. Assuming that Rhinoceros Scheme provides the feature symbol rhinoceros but not diplodocus and Diplodocus Scheme does the opposite, programs can portably ask "Is this Rhinoceros Scheme or Diplodocus Scheme?" and behave differently at run time based on the answer. Similarly, a program can ask "Does this implementation have exact complex numbers?" by checking for the presence of the exact-complex feature symbol in the result of calling features.

However, a program using just the features procedure cannot report to its user "I am executing on X Scheme" for every value of X, because it does not know which symbol in the feature list represents the implementation name, nor does it have a comprehensive list of implementation names. Similarly, there are other properties that the feature list may allow testing for but not reporting on, such as the underlying OS and the CPU architecture. For the sake of logging and debugging, it is necessary or at least extremely useful to provide a standard way for Scheme applications, as well as Scheme users at the REPL, to report these things. In the Common Lisp world, bugs are often reported in a REPL transcript beginning with a call to lisp-implementation-version.

Specification

The following procedures take no arguments and return either a string, or #f if the implementation cannot provide an appropriate and relevant result. It is an error to mutate the returned string. The procedures in this proposal are in the (srfi 112) library (or (srfi :112) on R6RS).

Because users are expected to use the values of these procedures for reporting rather than testing, no attempt is made to standardize the string values they return.

Procedures are provided rather than strings against the possibility that a Scheme process might migrate from machine to machine. This need not happen only in a distributed environment; consider, for example, dumping a core image file containing a compiler and then shipping it to another site.

Posix and Common Lisp equivalents or near-equivalents are provided. On Windows, some of this information is available using the GetSystemInfo and GetComputerName APIs.

(implementation-name)

Returns the name of the Scheme implementation. This procedure corresponds roughly to Common Lisp's lisp-implementation-type function.

(implementation-version)

Returns the version of the Scheme implementation. This procedure corresponds roughly to Common Lisp's lisp-implementation-version function.

(cpu-architecture)

Returns the CPU architecture, real or virtual, on which this implementation is executing. This procedure corresponds roughly to Common Lisp's machine-type function. On Posix systems, the result may be derived from the machine field of the utsname structure.

(machine-name)

Returns a name for the particular machine on which the implementation is running. Possible values are the DNS or WINS host name, the DNS full name, an IP address in string form associated with the system, or a MAC address in string form associated with the system. This procedure corresponds roughly to Common Lisp's machine-instance function. On Posix systems, the result may be derived from the nodename field of the utsname structure.

(os-name)

Returns a name for the operating system, platform, or equivalent on which the implementation is running. This procedure corresponds roughly to Common Lisp's software-type function. On Posix systems, the result may be derived from the sysname field of the utsname structure.

(os-version)

Returns the version of the operating system, platform, or equivalent on which the implementation is running. This procedure corresponds roughly to Common Lisp's software-version function. On Posix systems, the result may be derived from the release and/or version fields of the utsname structure.

Note: Analogues to the Common Lisp machine-version, short-site-name, and long-site-name are not provided. They are inconsistently implemented and of doubtful utility.

Implementation

The implementation of this SRFI is inherently system-dependent. The version shown below is for an imaginary Scheme implementation, and is in R5RS style. Trivial wrappers will convert it to an R6RS or R7RS library.

Some of the information can be derived from the uname() system call, which is provided by the Posix standard. (Some of the same information is available on Win32 using GetSystemInfo and GetComputerNameA.) The exact Scheme interface to uname is highly system-dependent. In Chicken, the system-information procedure returns a list of five strings representing the five components of the Posix utsname structure. In Gauche, the same procedure is called sys-uname. In Guile and Sizzle, it is called uname, and returns a vector rather than a list; Sizzle places it in the module (core posix). In Scheme48, there are five separate procedures in the posix structure named os-name, os-node-name, os-release-name, os-version-name, and machine-name. In scsh, the uname procedure returns a record whose fields have the same names as the Scheme48 procedures; their accessors are named uname:os-name, etc. The version below uses the Guile convention.

    (define (implementation-name) "Fantastic Scheme")
    
    (define (implementation-version) "1.0")
    
    (define (cpu-architecture) (vector-ref (uname) 4)) ; Posix machine field
    
    (define (machine-name) (vector-ref (uname) 1)) ; Posix nodename field
    
    (define (os-type) (vector-ref (uname) 0)) ; Posix sysname field
    
    (define (os-version)
      (string-append
        (vector-ref (uname) 2) ; Posix version field
        " "
        (vector-ref (uname) 3))) ; Posix release field
    

Copyright

Copyright (C) John Cowan 2013. All Rights Reserved.

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.


Editor: Mike Sperber
Last modified: Sun Nov 23 17:54:46 MET 2014