Description

Provides miscellaneous useful stuff.

Author

Kon Lovett

Download

misc-extn.egg

Documentation

Record Types

Usage

(require-extension misc-extn-record)
macro: (define-record-type/unsafe-inline-unchecked T CTOR PRED [SLOT ...])

SRFI-9 '(define-record-type T CTOR PRED [SLOT ...])', except no checks are made for correct record type before slot access, the record type symbol is not defined, procedures are inline, and unsafe system procedures are used.

For use when slot access is attempted only after determining the correct record type explicitly.

macro: (define-inline-unchecked-record-type T CTOR PRED [SLOT ...])

SRFI-9 '(define-record-type T CTOR PRED [SLOT ...])', except no checks are made for correct record type before slot access, the record type symbol is not defined, and procedures are inline.

For use when slot access is attempted only after determining the correct record type explicitly.

Control Forms

Usage

(require-extension misc-extn-control)
macro: (typecase EXPRESSION [(TYPE-TEST BODY ...) ...])

Expands into a cond form where every case test is a type test.

A TYPE-TEST is either a symbol, which must be the base symbol of a type predicate, a non-null list, which must be a list of the base symbols of type predicates, or the symbol else. An example of a base symbol of a type predicate is symbol and the procedure (symbol? OBJECT) is used for the test.

The BODY is not processed. It must be legal as the body of a cond case.

macro: (typecase* EXPRESSION [(TYPE-TEST BODY ...) ...])

Like typecase but binds local variable it to the value of EXPRESSION.

macro: (whennot TEST [BODY ...])

Synonym for unless.

macro: (swap-set! VAR1 VAR2)

Swap settings of VAR1 & VAR2.

macro: (fluid-set! VAR VAL ...)

Set each variable VAR to the value VAL in parallel.

macro: (stiff-set! VAR VAL ...)

Set each variable VAR to the value VAL in series.

macro: (hash-let (([VAR | (VAR KEY)] ...) HASH-TABLE) BODY ...)

Decompose HASH-TABLE entries into variable bindings. Should the KEY not be symbol, or the desired variable name VAR should not be the key, the '(VAR KEY)' form can be used. The BODY ... is evaluated with the specified bindings.

macro: (set!/op VAR OP ARG ...)

Sets VAR to the value of (OP ARG ...), where the first occurrence of <> in ARG ... is replaced with VAR.

When there is no occurrence of <> in ARG ...the template (OP <> ARG ...) is used.

procedure: (assure EXPRESSION [ERROR-ARGUMENT ...])

When EXPRESSION yields #f invoke (error ERROR-ARGUMENT ...), otherwise return value.

procedure: (identify-error [CALLER] MSG ARGS ...)

Prints a message like (error ...) to (current-error-port) but does not throw an exception.

procedure: (errorf [ID] [FORMAT-STRING ARGS ...])

Same as '(error [ID] (sprintf FORMAT-STRING ARGS ...))'.

The actual argument for the returned procedure is to be a procedure which will be applied with the evaluated expressions as the actual argument list.

Lists

Usage

(require-extension misc-extn-list)

The following macros are also availabe as procedures.

macro: (length=0? LIST)

List of length zero?

macro: (length=1? LIST)

List of length one?

macro: (length=2? LIST)

List of length two?

macro: (length>1? LIST)

List of length greater than one?

macro: (shift!/set VARIABLE [WHEN-EMPTY])

Like shift! in the utils unit but assigns the VARIABLE '() after shifting from a list of length 1.

WHEN-EMPTY, which defaults to #f is returned when the list bound to VARIABLE is empty.

macro: (ensure-list OBJECT)

Returns a list, either the list OBJECT or (list OBJECT).

macro: (not-null? LIST)

Returns #f if the given LIST is empty, and LIST otherwise.

Association Lists

Usage

(require-extension misc-extn-list)
procedure: (alist-inverse-ref VALUE ALIST [TEST? [NOT-FOUND]])

Returns the first key associated with VALUE in the ALIST using the TEST? predicate, else NOT-FOUND.

TEST? is eqv? and NOT-FOUND is #f.

procedure: (alist-delete/count KEY ALIST [TEST? [COUNT]])

Deletes the first (tt COUNT) associations from alist ALISTwith the given key KEY, using key-comparison procedure TEST?. The dynamic order in which the various applications of equality are made is from the alist head to the tail.

Returns a new alist. The alist is not disordered - elements that appear in the result alist occur in the same order as they occur in the argument alist.

The equality procedure is used to compare the element keys, 'key[i: 0 <= i < (length ALIST)]', of the alist's entries to the key parameter in this way: '(TEST? KEY key[i])'.

COUNT defaults to essentially, infinity, and EQUALITY? defaults to eqv?.

procedure: (alist-delete!/count KEY ALIST [TEST? [COUNT]])

Destructive version of alist-delete/count.

alist-delete-first and alist-delete-first! are also available as procedures.

macro: (alist-delete-first KEY ALIST [TEST?])

Returns (alist-delete/count KEY ALIST 1 [TEST?]).

macro: (alist-delete-first! KEY ALIST [TEST?])

Destructive version of alist-delete-first.

procedure: (unzip-alist ALIST)

Returns 2 values, a list of the keys & a list of the values from the ALIST.

procedure: (zip-alist KEYS VALUES)

Returns an association list with elements from the corresponding items of KEYS and VALUES.

Error signaling versions of the standard association lookup functions. When the KEY is not found and a NOT-FOUND value is not supplied an error is invoked.

macro: (assoc-def KEY ALIST [TEST] [NOT-FOUND])

The assoc procedure with an optional test and default value.

macro: (assv-def KEY ALIST [NOT-FOUND])

The assv procedure with a default value.

macro: (assq-def KEY ALIST [NOT-FOUND])

The assq procedure with a default value.

DSSSL Extended Lambda List

Usage

(require-extension misc-extn-dsssl)
procedure: (fixup-extended-lambda-list-rest LIST-OF-KEYWORD REST-LIST)

Returns a list from REST-LIST with all key'ed pairs from LIST-OF-KEYWORD removed.

procedure: (fixup-extended-lambda-list-optional LIST-OF-KEYWORD OPTIONAL ...)

Returns N+1 values from OPTIONAL ..., where N is the number of optionals, with all key'ed pairs from LIST-OF-KEYWORD removed. The first return value is the 'skip?' flag, the remaining are the "fixed" optional values.

OPTIONAL is a list of the form (VALUE DEFAULT).

The optionals run left-to-right, and the key/value pairs are assumed to bind left-to-right.

procedure: (fixup-extended-lambda-list LIST-OF-KEYWORD REST-LIST [OPTIONAL ...])

Returns N+1 values where the 1st value is the "fixed" REST-LIST and the remaining values are the "fixed" OPTIONAL ....

macro: (dsssl-fixup LIST-OF-KEYWORD LIST-OF-OPTIONAL REST-VARIABLE BODY ...)

Expands the BODY ... in a new lexical scope with the optional and rest variables bound to the "fixed" values.

LIST-OF-OPTIONAL is a list of elements of the form (VARIABLE DEFAULT) where VARIABLE is the optional variable name and DEFAULT is the optional variable default value.

Arithmetic

Usage

(require-extension misc-extn-numeric)
macro: (inc VAL)

Read-only increment.

macro: (dec VAL)

Read-only decrement.

macro: (++ VAL)

Read-only increment.

macro: (-- VAL)

Read-only decrement.

macro: (fx++ VAL)

Read-only fixnum increment.

macro: (fx-- VAL)

Read-only fixnum decrement.

macro: (fp++ VAL)

Read-only flonum increment.

macro: (fp-- VAL)

Read-only flonum decrement.

macro: (++! VAR)

Mutable increment.

macro: (--! VAR)

Mutable decrement.

macro: (fx++! VAR)

Mutable fixnum increment.

macro: (fx--! VAR)

Mutable fixnum decrement.

macro: (fp++! VAR)

Mutable flonum increment.

macro: (fp--! VAR)

Mutable flonum decrement.

Directories

Usage

(require-extension misc-extn-directory)
procedure: (push-directory DIRECTORY)

Push the current directory and change to the DIRECTORY.

procedure: (pop-directory)

Pop the last directory and change to it.

procedure: (pop-toplevel-directory)

Pop the earliest directory and change to it.

procedure: (create-directory/parents DIRECTORY)

Ensures the directory pathname DIRECTORY exists.

Like the *NIX `"mkdir -p DIRECTORY" command.

procedure: (create-pathname-directory PATHNAME)

Ensures the directory component of PATHNAME exist.

Like the *NIX `"mkdir -p `dirname PATHNAME`" command.

procedure: (make-program-filename COMMAND)

Returns the platform specific form of an executable command filename.

On Windows the exe extension is added unless an extension is already present. Does nothing on other platforms.

procedure: (make-shell-filename COMMAND)

Returns the platform specific form of a shell command filename.

On Windows the bat extension is added unless an extension is already present. On *NIX platforms adds .sh.

procedure: (file-exists/directory? FILENAME [DIRECTORY | DIRECTORY-LIST])

Returns the pathname when FILENAME exists in the DIRECTORY, otherwise #f.

DIRECTORY-LIST is as for make-pathname.

When only the FILENAME parameter supplied then the same as file-exists?.

procedure: (find-file-pathnames FILENAME [DIRECTORY | DIRECTORY-LIST] ...)

Returns a list of all pathnames found for FILENAME in the supplied directory/directories, or #f when not found.

The list of pathnames is in the same relative order as that of the directory parameter(s).

procedure: (find-program-pathnames COMMAND-NAME [DIRECTORY | DIRECTORY-LIST] ...)

Returns a list of all pathnames found for COMMAND-NAME in the supplied directory/directories, or #f when not found.

Uses make-program-filename to make a filename.

On Windows also uses make-shell-filename to make a filename.

Does not ensure that the file is executable!

procedure: (which-command-pathnames COMMAND-NAME [ENVIRONMENT-VARIABLE])

Returns the pathnames of COMMAND-NAME in the ENVIRONMENT-VARIABLE where the file exists, or #f when nothing found.

The default ENVIRONMENT-VARIABLE is "PATH".

Uses the platform specific "PATH" environment variable element separator - a ';' for Windows, & a ':' otherwise.

procedure: (which-command-pathname COMMAND-NAME [ENVIRONMENT-VARIABLE])

Same as which-command-pathnames but returns the first pathname only.

Like the *NIX "which COMMAND-NAME" command.

procedure: (remove-dotfiles FILES)

Remove dot files from a directory list. Useful with glob.

Posix

Usage

(require-extension misc-extn-posix)
File Descriptors
procedure: (replace-fileno NEW-FILENO KNOWN-FILENO)

Replaces the meaning of KNOWN-FILENO with NEW-FILENO. I/O Redirection.

Scheduling Priority

Parameter Descriptions

priority/process Process WHICH - WHO is 0 for current process or a process identifier.
priority/process-group Process Group WHICH - WHO is 0 for current process group or a process group identifier.
priority/user User WHICH - WHO is 0 for current user or a user identifier.
PRIORITY An integer [-20 20].

procedure: (scheduling-priority WHICH WHO)

Returns the priority of WHO of kind WHICH.

procedure: (set-scheduling-priority! WHICH WHO PRIORITY)

Sets the priority of WHO of kind WHICH to PRIORITY.

Pseudo-TTY

Currently a thin wrapper around the C interface. Scheme bindings for the necessary C constants are not provided.

procedure: (alloc-winsize)

Returns the pointer to a new C struct winsize.

procedure: (free-winsize (nonnull-pointer WINSIZE))

Releases a C struct winsize.

Accessors for a struct winsize

winsize-col Returns ws_col
winsize-col-set! Sets ws_col
winsize-row Returns ws_row
winsize-row-set! Sets ws_row
winsize-xpixel Returns ws_xpixel
winsize-xpixel-set! Sets ws_xpixel
winsize-ypixel Returns ws_ypixel
winsize-ypixel-set! Sets ws_ypixel

procedure: (alloc-termios)

Returns the pointer to a new C struct termios.

procedure: (free-termios (nonnull-pointer TERMIOS))

Releases a C struct termios.

Accessors for a struct termios

termios-cc Returns c_cc[idx]
termios-cc-set! Sets c_cc[idx]
termios-cflag Returns c_cflag
termios-cflag-set! Sets c_cflag
termios-iflag Returns c_iflag
termios-iflag-set! Sets c_iflag
termios-lflag Returns c_lflag
termios-lflag-set! Sets c_lflag
termios-oflag Returns c_oflag
termios-oflag-set! Sets c_oflag
termios-ispeed Returns c_ispeed
termios-ispeed-set! Sets c_ispeed
termios-ospeed Returns c_ospeed
termios-ospeed-set! Sets c_ospeed

procedure: (login-tty SLAVE-FILENO)

The C procedure.

procedure: (open-pty (nonnull-pointer MASTER-FILENO) (nonnull-pointer SLAVE-FILENO) (c-string NAME) (pointer WINSIZE) (pointer TERMIOS))

The C procedure.

Symbol

Usage

(require-extension misc-extn-symbol)
macro: (unbound-value)

Returns the value representing "unbound".

macro: (unbound-value? OBJECT)

Is the OBJECT the unbound value?

macro: (unbound? SYMBOL)

Is the SYMBOL unbound?

SYMBOL is not treated as a literal, be sure to quote if a literal desired.

macro: (symbol-value SYMBOL [NOT-FOUND #f])

Returns the SYMBOL binding when bound, otherwise the NOT-FOUND.

SYMBOL is not treated as a literal, be sure to quote if a literal desired.

macro: (undefined-value)

Returns the value representing "undefined".

macro: (undefined-value? OBJECT)

Is the OBJECT the undefined value?

macro: (undefined? OBJECT)

Is the OBJECT the undefined value?

procedure: (make-qualified-symbol NAMESPACE SYMBOL)

Returns the Chicken namespace qualified SYMBOL for the NAMESPACE.

An exception is generated when the NAMESPACE length exceeds the system limit.

procedure: (make-qualified-uninterned-symbol NAMESPACE SYMBOL)

Returns the Chicken namespace qualified SYMBOL for the NAMESPACE.

procedure: (qualified-symbol? SYMBOL)

Is the SYMBOL a Chicken namespace qualified symbol.

procedure: (symbol->qualified-string SYMBOL)

Returns the printname of a Chicken namespace qualified SYMBOL.

procedure: (interned-symbol? SYMBOL)

Is the SYMBOL interned?

Conditions

Usage

(require-extension misc-extn-condition)

The build condition API macros are currently unavailable when using hygienic macros.

macro: (build-condition-naming-api FORM ...)

Expands into one or more macros that expand into a condition specification form, suitable for use with build-property-condition-api and build-composite-condition-api.

Example: (build-condition-naming (exn location message arguments) foo (bar rope))

Creates the following:

  • (define-macro (exn-condition) '(exn location message arguments))
  • (define-macro (foo-condition) 'foo)
  • (define-macro (bar-condition) '(bar rope))
macro: (build-property-condition-api FORM ...)

Expands into a suite of procedures to construct and test SRFI-12 property condition objects.

When only one FORM is supplied a single property condition API is built. When more than one FORM are supplied then all the property condition APIs are built.

When FORM is a symbol it is a condition KIND-KEY and identifies a condition without properties. When FORM is a list the first element is the condition KIND-KEY and the following elements are property keys.

A condition constructor is named as make-KIND-KEY-condition and has 0 or more formal parameters, which are the property keys.

A condition predicate is named as KIND-KEY-condition? and has 1 formal parameter, the object to test.

Property condition constructors without properties always return the same condition object!

Example: (build-property-condition-api (exn location message arguments) foo (bar rope))

Creates the following:

  • (make-exn-condition location message arguments)
  • (exn-condition? object)
  • (make-foo-condition)
  • (foo-condition? object)
  • (make-bar-condition rope)
  • (bar-condition? object)
macro: (build-composite-condition-api FORM ...)

Expands into a suite of procedures to construct and test SRFI-12 a composite condition object.

FORM is the same as FORM in the build-property-condition-api definition.

When zero or one FORM are supplied nothing is built. When more than one FORM are supplied then a composite API is built.

A composite condition constructor is like a property condition constructor, except that the KIND-KEY is a concatenation of every condition KEY, interspersed with a hyphen.

A composite condition predicate is like a property condition predicate, except that the KIND-KEY is a concatenation of every condition KEY, interspersed with a hyphen.

Example: (build-composite-condition-api (exn location message arguments) foo (bar rope))

Creates the following:

  • (make-exn-foo-bar-condition location message arguments rope)
  • (exn-foo-bar-condition? object)
procedure: (handle-condition THUNK [HANDLER identity])

Simplified with-exception-handler where the HANDLER result is always returned to the caller.

HANDLER is (-> condition object).

procedure: (composite-condition? OBJECT [KIND-KEY ...])

Is the OBJECT a SRFI-12 composite condition?

When one or more KIND-KEY are supplied then the composite condition must compose at least those kind keys.

procedure: (condition-kind-keys CONDITION)

Returns a list of the kind-keys of the SRFI-12 CONDITION.

procedure: (condition-property-keys CONDITION [KIND-KEY])

Returns a list of the property-keys for KIND-KEY of the SRFI-12 CONDITION, or #f when no property keys or the CONDITION is not of the kind KIND-KEY.

When KIND-KEY is missing some kind-key of the CONDITION is used.

procedure: (condition-properties CONDITION [KIND-KEY])

Returns an association list of the property keys & values for KIND-KEY of the SRFI-12 CONDITION, or #f when no property keys or the CONDITION is not of the kind KIND-KEY.

When KIND-KEY is missing some kind-key of the CONDITION is used.

procedure: (condition-explode CONDITION)

Returns an association list of every kind-key of the SRFI-12 CONDITION. The value of each entry is the result of (condition-properties CONDITION KIND-KEY for that KIND-KEY.

procedure: (make-property-condition/list KIND-LIST PROPERTY-LIST)

Returns a new condition.

KIND-LIST is a list of kind-key.

PROPERTY-LIST is a property list, where the key element is a pair, (<kind-key> . <property-key>).

Input/Output

Usage

(require-extension misc-extn-io)
procedure: (cout EXPR ...)

Like cout << arguments << args where argument can be any Scheme object. If it's a procedure (without args) it's executed rather than printed (like newline).

procedure: (cerr EXPR ...)

Like cerr << arguments << args where argument can be any Scheme object. If it's a procedure (without args) it's executed rather than printed (like newline).

constant: nl

String form of the newline character.

Contributions

William Annis - hash-let.

Oleg Kiselyov's Standard Scheme "Prelude" - ++, ...

Examples

(use misc-extn-control misc-extn-dsssl)

(hash-let ([name (foo "wow")] some-hashtable)
  (print name " " foo #\newline))

(stiff-set! x 1 y 2)  ; x = 1 y = 2
(fluid-set! x y y x)  ; x = 2 y = 1
(swap-set! x y)       ; x = 1 y = 2

; Silly example
(typecase* (foo bar)
  [(procedure macro) #f]
  [symbol #t]
  [(vector list) #f]
  [else
    (error "not what I want" it)])

;
(define (a1 a2 #!optional o1 o2 #!rest rest #!key k1 k2)
  (dsssl-fixup '(#:k1 #:k2) ((o1 'x) (o2 'y)) rest
    (list o1 o2 rest) ) )
; expands into something similar to
#;
(define (a1 a2 #!optional o1 o2 #!rest rest #!key k1 k2)
  (let-values ([(rest o1 o2)
                (fixup-extended-lambda-list '(#:k1 #:k2) rest (list o1 'x) (list o2 'y))])
    (list o1 o2 rest) ) )

Version

License

"Copyright (c) 2006-2007, Kon Lovett.  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 ASIS, 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.