This page lists SRFIs someone thought to be useful at some point. Please use the official SRFI process as soon as you think you have a good idea, since that will record the discussion and rationale for each decision together with the SRFI itself. Use this page only if you can't submit a SRFI, or are actively looking for a basic starting idea.

CLOS-like Object System

Tiny-CLOS and Meroon? are used out there, maybe others. Standarizing one of the CLOS-like object-systems would be useful (though a variant of Meroon? was submitted and later withdrawn as SRFI:20). Of course, read object-oriented-programming and maybe split this up in several SRFIs.


A POSIX interface would be nice (of course, with semi-POSIX stuff like sockets included). You absolutely should read O.Shivers: Automatic management of operating-system resources (Note this link is dead, please replace with a new link to this resource) before you start out on this. Look at scsh for many similar ideas.


SREs are Symbolic Regular Expressions. They are implemented in SCSH. Other ideas can be gleamed from the `rx' macro in Emacs.

added comment: The scsh documentation seems to be specific to strings, if the SRFI is going to be specific to strings, lets identify it that way, maybe SSSRE's, (String Specific Symbolic Regular Expressions) as compared to the generalized case of doing regular expressions on symbols via equals? rather than just checking if charactors are equal in a string. The latter would be a special case by (string->list x) (but obviously less efficient). The former is a generalization of patern matching

Matrix Library

A library for manipulating mathematical matrices would be wonderful, especially if the reference implementation could be fast :-)

Look at slib for some ideas (but not on the speed)...


The current SRFIs which treat formatting (SRFI:28 and SRFI:48) are using strings for formatting. A library which uses lists instead would be a good idea. Look at SRFI:54 for a sample on how to do some kind of formatting in such a formatting proposal.

Am I alone in being *completely* lost in the maze of astonishing overcomplexity that is SRFI 54?

This could basically be combined with SRFI:54 in that it just defines the quite common procedures (probably with better names).

 (define (print . args) 
   (for-each display args)) 
 (define (println . args) 
   (for-each display args) 

Riastradh has also constructed an informal proposal for a macro-based formatter, riastradh-format.

Consideration: efficiency

It's quite inefficient to construct a lot of strings by appending etc., it's much more efficient to keep a structure and walk this when outputting. riastradh-format addresses this by providing a formatting mini-language. Another common approach is to have a procedure which displays a tree of values, so you can construct the tree and the procedure just walks it:

 (define (display-tree arg) 
    ((pair? arg) 
     (display-tree (car arg)) 
     (display-tree (cdr arg))) 
    ((not (null? arg)) 
     (display arg)))) 
 (define (display-trees . args) 
   (for-each display-tree args)) 

Formatting procedures such as padding can just return a list:

 (define (pad-left len str . charl) 
   (let ((pad-char (if (null? charl) 
                       (car charl)))) 
     (list (make-string (- len (string-length str)) 

This is not as efficient as the minilanguage approach (it still needs to construct the pad string), but it's a close approximation.

Output Combinators

Output combinators have several advantages:

 (define (c-line . contents) 
   (line (c-indentation) (list-sequence contents))) 
 (define (c-block . body) 
   (sequence (c-line "{") 
             (with-c-indentation 2 (list-sequence body)) 
             (c-line "}"))) 
 (define (c-label name) 
   (with-c-indentation -1 (c-line name ":"))) 

Here is a simple implementation of some output combinators. Note that there is no framework imposed by the device; output procedures are simply unary procedures that accept ports and write output to them, and output combinators are simply procedures that return output procedures. We need no format dispatch table or mini-language compiler or anything like that. This code makes trivial use of SRFI:1 as well as some Scheme48-specific features such as fresh-line, which is like newline but on some ports where it is supported does not create a new line if it is on an empty line, and char-sink->output-port, whose name and usage are self-explanatory.

 ;;; -*- Mode: Scheme -*- 
 ;;;; Output by Combinators 
 ;;; This code is written by Taylor Campbell and placed in the Public 
 ;;; Domain.  All warranties are disclaimed. 
 (define (item->output-procedure item) 
   (cond ((string? item) 
          (lambda (port) 
            (write-string item port))) 
         ((char? item) 
          (lambda (port) 
            (write-char item port))) 
         ((procedure? item) 
          ;++ Default to DISPLAY or something? 
          (error "invalid item for output procedure" item)))) 
 (define (sequence . elements) 
   (list-sequence elements)) 
 (define (list-sequence list) 
   (reduce-right binary-sequence (empty-sequence) 
                 (map item->output-procedure list))) 
 (define (binary-sequence first second) 
   (lambda (port) 
     (first port) 
     (second port))) 
 (define (empty-sequence) 
   (lambda (port) 
 (define (decorated-list-sequence prefix infix suffix list) 
   (sequence prefix 
              (fold-right (lambda (element tail) 
                            (cons element 
                                  (if (null? tail) 
                                      (cons infix tail)))) 
 (define (line . contents) 
   (let ((write-contents (list-sequence contents))) 
     (lambda (port) 
       (fresh-line port) 
       (write-contents port) 
       (fresh-line port)))) 
 (define (stringify item) 
   (sequence #\" 
             (let ((write-item (item->output-procedure item))) 
               (lambda (port) 
                 (write-item (char-sink->output-port 
                              (let ((previous #f)) 
                                (lambda (char) 
                                  (if (or (char=? char #\") 
                                          (char=? char #\\)) 
                                      (write-char #\\ port)) 
                                  (write-char char port))))))) 
 (define (writer obj) 
   (lambda (port) 
     (write obj port))) 
 (define (displayer obj) 
   (lambda (port) 
     (display obj port))) 
 (define (pad-right width char require-padding? item) 
   (let ((write-item (item->output-procedure item))) 
     (lambda (port) 
       (let ((chars 0)) 
         (write-item (char-sink->output-port 
                      (lambda (char) 
                        (set! chars (+ chars 1)) 
                        (write-char char port)))) 
         (cond ((< chars width) 
                (write-string (make-string (- width chars) char) 
               ((and require-padding? 
                     (= chars width)) 
                (write-char char port))))))) 

Incidentally, this output combinator device is also a monad, if we take this definition of the extend operator (also known in Haskell circles as bind or >>=) and the unit operator (also known as eta and return):

 (define (extend item procedure) 
   (let ((write-item (item->output-procedure item))) 
     (lambda (port) 
       ((procedure (write-item port)) 
 (define (unit datum) 
   (lambda (port) 
     port           ; ignored