Extra SRFI Libraries
32 SRFI-202 Pattern-matching Variant of the and-let* Form that Supports Multiple Values |
While Racket comes with a number of SRFI libraries, it’s missing quite a lot of useful ones. This collection adds some.
A note on licensings: Most of the included SRFIs are the reference implementations adapted to Racket, and retain the original licenses.
Typical changes to the reference versions include adding contracts and removing now-redundant type checking, avoiding things Scheme allows that Racket doesn’t like if missing an else clause, reorganization of source files, etc.
Modules that are noted as providing an unsafe option have a submodule named unsafe that exports functions without contracts and potentially other run time checks. Passing those functions invalid or out of range arguments can have unpredictable results. Use with caution.
1 SRFI-1 List Library
1.1 Typed Racket
(require typed/srfi/1) | package: extra-srfi-libs |
(require typed/srfi/lists) | package: extra-srfi-libs |
Imports SRFI-1 functions into a Shallow Typed Racket module. Circular and dotted lists aren’t always accepted where the documentation says they should be; I still need to work out if it’s even possible to represent a circular list in TR.
The linear update procedures ending with a ! are just aliases for the normal ones, thanks to Racket’s immutable cons cells. This behavior is allowed by the SRFI.
1.2 Mutable lists
(require srfi/1m) | package: extra-srfi-libs |
(require srfi/mlists) | package: extra-srfi-libs |
SRFI-1 for mutable lists. Procedures have the same name with an m prepended, except ones with list or pair in the name, which turns into mlist or mpair. So, for example, make-mlist, not-mpair? and mxcons.
Also available in an unsafe module with (require (submod srfi/1m unsafe)).
1.2.1 Extra functions
procedure
lst : list?
procedure
(mlist->list mlst) → list?
mlst : proper-mlist?
2 SRFI-13 String Libraries
(require typed/srfi/13) | package: extra-srfi-libs |
(require typed/srfi/strings) | package: extra-srfi-libs |
Notes: While Racket comes with a SRFI-13 implementation, it’s only for normal Racket, not Typed Racket. This module can be used instead of having to "require/typed" specific functions from it that you might need in Typed Racket.
3 SRFI-27 Sources of Random Bits
(require typed/srfi/27) | package: extra-srfi-libs |
(require typed/srfi/random-bits) | package: extra-srfi-libs |
Notes: While Racket comes with a SRFI-27 implementation, it’s only for normal Racket, not Typed Racket. This module can be used instead of having to "require/typed" specific functions from it that you might need in Typed Racket.
4 SRFI-74 Octet-Addressed Binary Blocks
(require srfi/74x) | package: extra-srfi-libs |
(require srfi/blobs) | package: extra-srfi-libs |
(require typed/srfi/74) | package: extra-srfi-libs |
(require typed/srfi/blobs) | package: extra-srfi-libs |
Notes: The version of this module in srfi-lib is just the reference implementation and has, as of Racket 8.15, a serious bug in that the "native" endianness is always big-endian. This, besides being having a version written in Typed Racket, fixes that, and uses a more Racket-specific implementation. You should probably use always use this one, at least until the bug is fixed.
5 SRFI-87 => in case clauses
(require srfi/87x) | package: extra-srfi-libs |
While Racket comes with a SRFI-87 implementation in srfi-lib, trying to use it causes syntax errors. This version actually works, and it follows the Racket convention of using equal? instead of eqv? to test values in case.
6 SRFI-111 Boxes
(require srfi/111) | package: extra-srfi-libs |
Racket natively supports SRFI-111 single-valued boxes, but this module re-exports SRFI-195 versions of functions to comply with that document.
7 SRFI-112 Environment Inquiry
(require srfi/112) | package: extra-srfi-libs |
Notes: (os-version) always returns #f, but the other functions are all implemented.
8 SRFI-117 Queues based on (mutable) lists
(require srfi/117) | package: extra-srfi-libs |
(require srfi/list-queues) | package: extra-srfi-libs |
The SRFI uses normal lists, which are immutable in Racket. Therefore, this implemention uses mutable lists of mcons pairs. The single argument form of make-list-queue and two argument form of list-queue-set-list! can be passed normal lists, though. list-queue-list returns a mutable list.
Also available in an unsafe module with (require (submod srfi/117 unsafe)).
procedure
(in-list-queue lq) → sequence?
lq : list-queue?
9 SRFI-127 Lazy Sequences
(require srfi/127) | package: extra-srfi-libs |
(require srfi/lazy-sequences) | package: extra-srfi-libs |
Notes: The lazy sequences described in the SRFI are built on normal, mutable Scheme cons cells. Racket cons cells are in theory immutable, so this implementation instead uses mcons cells; lists of which aren’t compatible with list functions. There’s a few extra functions to help make that easier to work with, as well as the srfi/1m module.
procedure
lst : list?
procedure
val : any/c
procedure
(in-lseq lseq) → sequence?
lseq : lseq?
10 SRFI-128 Comparators (reduced)
(require srfi/128) | package: extra-srfi-libs |
(require srfi/comparators) | package: extra-srfi-libs |
Reference documentation. Also includes SRFI-162 Comparators sublibrary and SRFI-228 Composing Comparators routines and variables.
The make-eq-comparator, make-eqv-comparator, make-equal-comparator and make-equal-always functions return comparators using the standard Racket eq-hash-code etc. hash functions instead of default-hash.
make-comparator takes an optional keyword argument, "#:secondary-hash", whose value has the same signature as the "hash" one - either (-> any/c exact-integer?) or #f. This is used for better compability with Racket’s custom hash tables, which take two hash functions. Hash functions can also return negative numbers, contrary to the SRFI spec.
Comparators can be used as flat contracts (And thus predicates) that test their argument against their type test predicate.
10.1 Additional definitions
procedure
→ (-> any/c exact-integer?) cmp : comparator?
procedure
(comparator-secondary-hash cmp obj) → exact-integer?
cmp : comparator? obj : any/c
11 SRFI-132 Sort Libraries
(require srfi/132) | package: extra-srfi-libs |
(require srfi/sorting) | package: extra-srfi-libs |
vector-sort and vector-sort! conflict with the ones in racket/vector - the order of the vector and ordering predicate is reversed.
The side-effect-enabled list functions list-merge! and list-delete-neighbor-dups! currently use unsafe-immutable-set-cdr! to modify the lists in place. The test cases pass, but if this becomes an issue in practice (The function has lots of warnings attached), I’ll switch them to just being aliases for the non-side-effect versions.
Available as an unsafe module via (require (submod srfi/132 unsafe)).
12 SRFI-133 Vector Library (R7RS-compatible)
(require srfi/133) | package: extra-srfi-libs |
(require srfi/vectors) | package: extra-srfi-libs |
(require typed/srfi/133) | package: extra-srfi-libs |
(require typed/srfi/vectors) | package: extra-srfi-libs |
See also SRFI-43 included with Racket. Notable differences are functions that take callbacks not passing the current index like they do in 43.
Also available in a Typed Racket version and an unsafe version as (require (submod srfi/133 unsafe)).
13 SRFI-134 Immutable Deques
(require srfi/134) | package: extra-srfi-libs |
Notes:
Deques are equal? if they are the same length and all corresponding elements are equal?.
Deques are streams and sequences.
As of Racket 8.13, implemented with treelists instead of the banker’s deque reference implementation.
Extra functions:
procedure
(in-ideque dq) → sequence?
dq : ideque?
procedure
(in-ideque-backwards dq) → sequence?
dq : ideque?
14 SRFI-140 Immutable Strings
(require srfi/140) | package: extra-srfi-libs |
Notes:
This module is equivalent to the R7RS (srfi 140 istrings) library. The other variations laid out in the SRFI are not present. The mutable string functions string-append! and string-replace!, which require resizable strings, are not provided.
Extra functions:
Stuff used by the UTF-16 conversion routines that might be more broadly useful.
procedure
(string-utf-16-length s [start end]) → exact-nonnegative-integer?
s : string? start : exact-nonnegative-integer? = 0 end : exact-nonnegative-integer? = (string-length s)
procedure
(bytes-utf-16-length b [ start end #:big-endian? big-endian?]) → exact-nonnegative-integer? b : bytes? start : exact-nonnegative-integer? = 0 end : exact-nonnegative-integer? = (bytes-length b) big-endian? : (or/c boolean? 'check-bom) = 'check-bom
If big-endian? is 'check-bom and there is no BOM present, the native system endianness is used.
procedure
(bytes-utf-16-endianness b [start end]) →
boolean? boolean? b : bytes? start : exact-nonnegative-integer? = 0 end : exact-nonnegative-integer? = (bytes-length b)
15 SRFI-141 Integer division
(require srfi/141) | package: extra-srfi-libs |
(require srfi/integer-division) | package: extra-srfi-libs |
(require typed/srfi/141) | package: extra-srfi-libs |
(require typed/srfi/integer-division) | |
package: extra-srfi-libs |
Notes:
The functions in the typed version are constrained to only take and return exact integers. The regular package’s will accept inexact integers. The typed module also has Fixnum versions with a "fx" prefix - fxfloor/, for example.
16 SRFI-143 Fixnums
(require srfi/143) | package: extra-srfi-libs |
(require srfi/fixnums) | package: extra-srfi-libs |
(require typed/srfi/143) | package: extra-srfi-libs |
(require typed/srfi/fixnums) | package: extra-srfi-libs |
17 SRFI-145 Assumptions
(require srfi/145) | package: extra-srfi-libs |
(require srfi/assume) | package: extra-srfi-libs |
struct
(struct exn:fail:contract:assume exn:fail:contract () #:extra-constructor-name make-exn:fail:contract:assume #:transparent)
18 SRFI-146 Mappings
(require srfi/146) | package: extra-srfi-libs |
mapping? objects are also ordered-dict?s and many functions in this module can be used with other ordered dicts or even unordered-ones for operations where order doens’t matter. The mapping implementation uses scapegoat trees.
The current make-mapping-comparator and mapping-comparator do not provide ordering.
The linear update versions of functions with names ending in !, if passed an external dict object that supports side effect operations, will update it in place and return it. If passed an immutable dict, they will just return a new object like the non-linear versions. Basically, as long as you follow the guideline of never using a particular dict object again after passing it to a linear update function, everything will Just Work no matter what.
Additional functions:
procedure
(in-ordered-dict od [starting-pos]) → sequence?
od : ordered-dict? starting-pos : any/c = (dict-iterate-least od)
procedure
(in-ordered-dict-keys od [starting-pos]) → sequence?
od : ordered-dict? starting-pos : any/c = (dict-iterate-least od)
procedure
(in-ordered-dict-values od [starting-pos]) → sequence?
od : ordered-dict? starting-pos : any/c = (dict-iterate-least od)
(require srfi/146/hash) | package: extra-srfi-libs |
hashmap? objects are also dict?s and many functions in this module can be used with other types of dicts. The hashmap implementation uses Racket’s immutable hash tables, but also support mutable side-effect functionality.
19 SRFI-151 Bitwise Operations
(require srfi/151) | package: extra-srfi-libs |
(require srfi/bitwise-operations) | package: extra-srfi-libs |
Notes:
Written in Typed Racket. Hopefully the type signatures should be obvious and intuitive. If performance matters, code that uses these routines should also be written in Typed Racket.
20 SRFI-158 Generators and Accumulators
(require srfi/158) | package: extra-srfi-libs |
Reference documentation. Also includes SRFI-221 Generator/accumulator sub-library routines.
These generators are not compatible with the ones in "racket/generator". There is an adaptor function provided to wrap Racket generators in SRFI-158 ones, but beware of conflicting generator identifiers in the two modules.
Available as an unsafe module via (require (submod srfi/158 unsafe)).
procedure
(generator? obj) → boolean?
obj : any/c
procedure
g : generator?
procedure
(sequence->generator s) → (-> any/c)
s : sequence?
21 SRFI-160 Homogenous numeric vector libraries
Reference documentation. In addition to all the numeric types in the SRFI, functions for flvector and fxvector vectors are also provided, with a "fl" and "fx" prefix respectively. If Racket CS ever gains support for 80-bit extflonum? numbers on x86, I’ll add support for extflvector? and f80vector? vectors too (And might adjust the f32vector? contracts to explicitly work with single-flonum? values if CS ever gets them).
All these modules have an unsafe submodule.
(require srfi/160/base) | package: extra-srfi-libs |
Additional functions for converting between flvectors and SRFI-4 vectors:
procedure
(flvector->f32vector fl [start end]) → f32vector?
fl : flvector? start : exact-nonnegative-integer? = 0 end : exact-nonnegative-integer? = (flvector-length fv)
procedure
(flvector->f64vector fl [start end]) → f64vector?
fl : flvector? start : exact-nonnegative-integer? = 0 end : exact-nonnegative-integer? = (flvector-length fv)
procedure
(f32vector->flvector f32 [start end]) → flvector?
f32 : f32vector? start : exact-nonnegative-integer? = 0 end : exact-nonnegative-integer? = (f32vector-length f32)
procedure
(f64vector->flvector f64 [start end]) → flvector?
f64 : f64vector? start : exact-nonnegative-integer? = 0 end : exact-nonnegative-integer? = (f64vector-length f64)
(require srfi/160/u8) | package: extra-srfi-libs |
(require srfi/160/s8) | package: extra-srfi-libs |
(require srfi/160/u16) | package: extra-srfi-libs |
(require srfi/160/s16) | package: extra-srfi-libs |
(require srfi/160/u32) | package: extra-srfi-libs |
(require srfi/160/s32) | package: extra-srfi-libs |
(require srfi/160/u64) | package: extra-srfi-libs |
(require srfi/160/s64) | package: extra-srfi-libs |
(require srfi/160/f32) | package: extra-srfi-libs |
(require srfi/160/f64) | package: extra-srfi-libs |
(require srfi/160/c64) | package: extra-srfi-libs |
(require srfi/160/c128) | package: extra-srfi-libs |
(require srfi/160/fl) | package: extra-srfi-libs |
(require srfi/160/fx) | package: extra-srfi-libs |
Additional functions:
procedure
(in-@vector vec [start end]) → sequence?
vec : @vector? start : exact-nonnegative-integer? = 0 end : exact-nonnegative-integer? = (@vector-length vec)
22 SRFI-171 Transducers
(require srfi/171) | package: extra-srfi-libs |
(require srfi/171/meta) | package: extra-srfi-libs |
Notes: The bytevector-u8-* functions have been renamed bytes-* to better match Racket conventions, though the original names are still available as aliases.
Additional functions:
procedure
(set-transduce xform f set) → any/c
xform : procedure? f : procedure? set : set? (set-transduce xform f identity set) → any/c xform : procedure? f : procedure? identity : any/c set : set?
procedure
(treelist-transduce xform f tl) → any/c
xform : procedure? f : procedure? tl : treelist? (treelist-transduce xform f identity tl) → any/c xform : procedure? f : procedure? identity : any/c tl : treelist?
23 SRFI-173 Hooks
(require srfi/173) | package: extra-srfi-libs |
Notes: A hook object is callable as a procedure; (hook-obj args ...) is the same as (hook-run hook-obj args ...).
24 SRFI-174 POSIX Timespecs
(require srfi/174) | package: extra-srfi-libs |
Notes:
Implemented as a distinct type (A transparent structure), with the range of the seconds values the same as the range of Racket integers.
timespec-hash uses equal-hash-code and might return negative values contrary to the SRFI description of the function.
25 SRFI-175 ASCII character library
(require srfi/175) | package: extra-srfi-libs |
(require srfi/ascii) | package: extra-srfi-libs |
What the SRFI documentation calls a bytevector is what Racket calls a byte string.
Available as an unsafe module via (require (submod srfi/175 unsafe)).
26 SRFI-180 JSON
(require srfi/180) | package: extra-srfi-libs |
You can never have too many JSON parsers available for a language.
27 SRFI-190 Coroutine Generators
(require srfi/190) | package: extra-srfi-libs |
Notes: The yield syntax conflicts with "racket/generator".
28 SRFI-193 Command line
(require srfi/193) | package: extra-srfi-libs |
Notes:
The heuristics for telling if a command or script or neither is being executed could probably stand to be improved.
The command-line procedure conflicts with the one in "racket/cmdline".
29 SRFI-194 Random data generators
(require srfi/194) | package: extra-srfi-libs |
Notes:
Written in Typed Racket.
make-ellipsoid-generator, make-ball-generator and make-sphere-generator have variants flmake-ellipsoid-generator, flmake-ball-generator and flmake-sphere-generator that return flvectors. The ellipsoid generator functions can take a flvector or a vector of reals. The ball generator functions can take a flvector, vector of reals, or an integer.
30 SRFI-195 Multiple-value Boxes
(require srfi/195) | package: extra-srfi-libs |
Notes:
Native Racket single-valued boxes are accepted by these functions, and multiple-valued boxes of arity 1 created by this SRFI’s box use them.
Multiple-valued boxes can be compared and hashed with equal?. The usual caveats about modifying a box used as a key in a hash table apply.
30.1 Additional procedures and forms
syntax
A match expander to use multiple-valued boxes in match clauses.
(match (box 1 2 3) [(mvbox a b c) (list a b c)]) ; '(1 2 3)
procedure
(box-immutable arg ...) → box?
arg : any/c
31 SRFI-196 Range Objects
(require srfi/196) | package: extra-srfi-libs |
Notes: The "range" function from this module conflicts with the one from "racket/list".
31.1 Additional functions
procedure
(range-empty? r) → boolean?
r : range?
procedure
(in-range-object r) → sequence?
r : range?
32 SRFI-202 Pattern-matching Variant of the and-let* Form that Supports Multiple Values
(require srfi/202) | package: extra-srfi-libs |
Notes:
The reference implementations for this SRFI include one for Racket, but this one is original, using syntax-parse macros. It’s also a lot simpler, which makes me wonder, but it passes all the test cases...
Uses match style pattern matching.
33 SRFI-207 String-notated bytevectors
(require srfi/207) | package: extra-srfi-libs |
(require srfi/bytestrings) | package: extra-srfi-libs |
The u8"..." reader syntax and I/O functions are not supported.
Available in an unsafe version as (require (submod srfi/207 unsafe)).
34 SRFI-208 NaN Procedures
(require srfi/208) | package: extra-srfi-libs |
(require typed/srfi/208) | package: extra-srfi-libs |
Notes:
Currently only works with double-precision flonums, though the SRFI allows for other floating point types. While Racket BC supports single precision flonums, Racket CS doesn’t, and I don’t have a version of CS installed that supports extflonums (maybe it doesn’t support them at all either?). If either condition changes I might go back and add support for those types.
The main difference between the untyped and typed versions are that the former includes NaN checking of arguments in the contracts; the typed one has an explicit check to raise an error if passed a non-NaN number. I might remove that check in the future and just say it’s undefined what happens when they’re passed a non-NaN.
35 SRFI-210 Procedures and Syntax for Multiple Values
(require srfi/210) | package: extra-srfi-libs |
Notes:
apply/mv, call/mv, and with-values have been extended to work with Racket’s keyword arguments by taking optional keyword+value arguments after the last documented ones that are passed to the consumer procedure. For example,
(apply/mv ~a #\a (values #\b #\c) #:separator ", ")
The forms and functions that take/return boxes use SRFI-195 multiple-value ones.
35.1 Additional functions
procedure
(bind/vector vec transducer ...) → any
vec : vector? transducer : procedure?
36 SRFI-214 Flexvectors
(require srfi/214) | package: extra-srfi-libs |
Notes: The impelmentation is built on "data/gvector" and flexvectors are also gvectors.
36.1 Additional functions
procedure
len : exact-nonnegative-integer? proc : (-> exact-nonnegative-integer? any/c)
procedure
(flexvector->bytes fv [start end]) → bytes?
fv : (flexvectorof byte?) start : exact-integer? = 0 end : exact-integer? = (flexvector-length fv)
procedure
(bytes->flexvector bs [start end]) → (flexvectorof byte?)
bs : bytes? start : exact-integer? = 0 end : exact-integer? = (bytes-length bs)
procedure
(flexvector-bisect-left fv val less? [lo hi]) → integer?
fv : flexvector? val : any/c less? : (-> any/c? any/c? any/c) lo : integer? = 0 hi : integer? = (flexvector-length fv)
procedure
(flexvector-bisect-right fv val less? [lo hi]) → integer?
fv : flexvector? val : any/c less? : (-> any/c? any/c? any/c) lo : integer? = 0 hi : integer? = (flexvector-length fv)
procedure
(in-flexvector fv) → sequence?
fv : flexvector?
37 SRFI-217 Integer Sets
(require srfi/217) | package: extra-srfi-libs |
"iset" objects also support the Racket gen:set interface and can be used with "racket/set" functions. The set-theory functions like set-union only work when all sets are isets (The same restriction applies to other types of sets).
They also support equal? and are hashable so they can be used as keys in hash tables and sets. The usual warnings about mutating such sets apply.
The reference implementation, using Patricia trees, is currently being used. I’m considering replacing it with one that can more compactly store ranges of numbers.
Available as an unsafe module via (require (submod srfi/217 unsafe)).
38 SRFI-223 Generalized binary search procedures
(require srfi/223) | package: extra-srfi-libs |
(require srfi/bisect) | package: extra-srfi-libs |
Reference documentation. This and the following modules are written in Typed Racket.
(require srfi/223/bytes) | package: extra-srfi-libs |
SRFI-223 procedures specialized for byte strings.
procedure
(bytes-bisect-left bs val less? [lo hi]) → integer?
bs : bytes? val : byte? less? : (-> byte? byte? any/c) lo : integer? = 0 hi : integer? = (bytes-length bs)
procedure
(bytes-bisect-right bs val less? [lo hi]) → integer?
bs : bytes? val : byte? less? : (-> byte? byte? any/c) lo : integer? = 0 hi : integer? = (bytes-length bs)
(require srfi/223/flvector) | package: extra-srfi-libs |
SRFI-223 procedures specialized for flvectors.
procedure
(flvector-bisect-left fv val less? [lo hi]) → integer?
fv : flvector? val : flonum? less? : (-> flonum? flonum? any/c) lo : integer? = 0 hi : integer? = (flvector-length fv)
procedure
(flvector-bisect-right fv val less? [lo hi]) → integer?
fv : flvector? val : flonum? less? : (-> flonum? flonum? any/c) lo : integer? = 0 hi : integer? = (flvector-length fv)
(require srfi/223/fxvector) | package: extra-srfi-libs |
SRFI-223 procedures specialized for fxvectors.
procedure
(fxvector-bisect-left fv val less? [lo hi]) → integer?
fv : fxvector? val : fixnum? less? : (-> fixnum? fixnum? any/c) lo : integer? = 0 hi : integer? = (fxvector-length fv)
procedure
(fxvector-bisect-right fv val less? [lo hi]) → integer?
fv : fxvector? val : fixnum? less? : (-> fixnum? fixnum? any/c) lo : integer? = 0 hi : integer? = (fxvector-length fv)
39 SRFI-224 Integer Mappings
(require srfi/224) | package: extra-srfi-libs |
"fxmapping" objects support the gen:dict interface and can thus be used with "racket/dict" functions. They also support equal? and are hashable so they can be used as keys in hash tables and sets. The usual warnings about mutating values stored in such mappings apply.
Available as an unsafe module via (require (submod srfi/224 unsafe)).
40 SRFI-232 Flexible curried procedures
(require srfi/232) | package: extra-srfi-libs |
41 SRFI-235 Combinators
(require srfi/235) | package: extra-srfi-libs |
Notes:
The conjoin and disjoin functions conflict with the ones in "racket/function" and group-by with the one in "racket/list".
case-procedure uses equal? to compare values instead of eqv? to match Racket’s case.
Procedures that take or return procedures that take arbitary arguments will work with keyword arguments for the most part.
42 SRFI-238 Codesets
(require srfi/238) | package: extra-srfi-libs |
(require srfi/codesets) | package: extra-srfi-libs |
The only predefined codeset is 'errno with POSIX errno values.
42.1 Additional functions
procedure
(register-codeset! name data) → void?
name : symbol? data : (listof (list/c (or/c symbol? #f) (or/c exact-integer? #f) (or/c string? #f)))
43 SRFI-239 Destructuring Lists
(require srfi/239) | package: extra-srfi-libs |
(require srfi/list-case) | package: extra-srfi-libs |
Normally you’d use match in Racket, but this is a lightweight alternative when just dealing with lists.