1 Classes and Objects
class-or-interface/ c
object/ c
class/ c
mixin/ c
ensure-interface
send+
send-each
2 Functions
identity
constant
curry*
curryr*
thunk
call
conjoin
disjoin
lambda/ parameter
3 Imperative Queues
make-queue
enqueue!
dequeue!
queue-empty?
queue?
queue/ c
nonempty-queue/ c
4 Syntax Objects
syntax-datum/ c
syntax-listof/ c
syntax-list/ c
syntax-map
to-syntax
to-datum
current-syntax
syntax-error
with-syntax*
5 Text Representations
text/ c
text?
string-literal?
bytes-literal?
keyword-literal?
text->string
text->bytes
text->symbol
text->keyword
text->string-literal
text->bytes-literal
text->identifier
text->keyword-literal
text-append
text=?
text>?
text<?
6 Multiple Values
values->list
map2
map/ values
foldr/ values
foldl/ values
Version: 4.1

Scheme Utilities in (planet cce/scheme:1:2)

This is my personal library of PLT Scheme programming utilities. Feel free to use it, copy my code, or ask me questions.

    1 Classes and Objects

    2 Functions

    3 Imperative Queues

    4 Syntax Objects

    5 Text Representations

    6 Multiple Values

 (require (planet cce/scheme:1:2))

The default module provides all the bindings described below under the individual modules.

1 Classes and Objects

 (require (planet cce/scheme:1:2/class))

This module provides tools for classes, objects, and mixins.

class-or-interface/c : flat-contract?

Recognizes classes and interfaces.

(object/c spec ...)  flat-contract?

  spec : class-or-interface/c

Recognizes objects which are instances of all the given classes and interfaces.

(class/c spec ...)  flat-contract?

  spec : class-or-interface/c

Recognizes classes which are subclasses (not strictly) and implementations, respectively, of all the given classes and interfaces.

(mixin/c [super-expr ...] [arg-expr ...] [sub-expr ...])

Function contract for a mixin whose first argument is the parent class c% matching (class/c super-expr ...), whose remaining arguments match arg-expr ..., and whose result matches (class/c c% sub-expr ...).

(ensure-interface i<%> mx c%)  (class/c c% i<%>)

  i<%> : interface?

  mx : (mixin/c [] [] [i<%>])

  c% : class?

Returns c% if it implements i<%>; otherwise, returns (mx c%).

(send+ obj [message arg ...] ...)

Sends each message (with arguments) to obj, then returns obj.

Examples:

  (define c%

    (class object%

      (super-new)

      (define/public (say msg) (printf "~a!\n" msg))))

  > (send+ (new c%) [say 'Hello] [say 'Good-bye])

  Hello!

  Good-bye!

  #(struct:object:c%)

(send-each objs message arg ...)

Sends the message to each object in the list objs, returning (void).

Examples:

  (define c%

    (class object%

      (super-new)

      (init-field msg)

      (define/public (say to) (printf "~a, ~a!\n" msg to))))

  > (send-each

     (list (new c% [msg 'Hello])

           (new c% [msg 'Good-bye]))

     say 'World)

  Hello, World!

  Good-bye, World!

2 Functions

 (require (planet cce/scheme:1:2/function))

This module provides tools for higher-order programming and creating functions.

(identity v)  (one-of/c v)

  v : any/c

This function returns its argument.

(constant v)  (unconstrained-> (one-of/c v))

  v : any/c

Produces a function that returns v regardless of input.

Examples:

  (define f (constant (gensym)))

  > (f)

  g368

  > (f '(4 5 6))

  g368

  > (f #:x 7 #:y 8 #:z 9)

  g368

((curry* f #:i a ... x ...) #:j b ... y ...)  any/c

  f : procedure?

  a : any/c

  x : any/c

  b : any/c

  y : any/c

((curryr* f #:i a ... x ...) #:j b ... y ...)  any/c

  f : procedure?

  a : any/c

  x : any/c

  b : any/c

  y : any/c

Partial applications of a function; curry* provides the left arguments first, while curryr* provides the right arguments first.

  ((curry* f x ...) y ...) = (f x ... y ...)

  ((curryr* f x ...) y ...) = (f y ... x ...)

Examples:

  (define (f a [b 0] #:x x #:y [y 0]) (list a b x y))

  > ((curry* f 1) #:x 2)

  (1 0 2 0)

  > ((curry* f 1 #:x 3) 2 #:y 4)

  (1 2 3 4)

  > ((curryr* f 1) #:x 2)

  (1 0 2 0)

  > ((curryr* f 1 #:x 3) 2 #:y 4)

  (2 1 3 4)

(thunk body ...)

Creates a function that ignores its inputs and evaluates the given body. Useful for creating event handlers with no (or irrelevant) arguments.

Examples:

  (define f (thunk (define x 1) (printf "~a\n" x)))

  > (f)

  1

  > (f 'x)

  1

  > (f #:y 'z)

  1

(call f arg ...)  B

  f : (-> A ... B)

  arg : A

Calls its first argument, passing on any remaining arguments. Useful for invoking thunks in a higher-order context (for instance, as an argument to map or for-each).

Examples:

  (define (say [msg "Hello"] #:to [to "World"])

    (printf "~a, ~a!\n" msg to))

  > (call say)

  Hello, World!

  > (call say "Good night" #:to "Moon")

  Good night, Moon!

((conjoin f ...) arg ...)  boolean?

  f : (-> A ... boolean?)

  arg : A

Combines calls to each function with and.

Examples:

  (define f (conjoin exact? integer?))

  > (f 1)

  #t

  > (f 1.0)

  #f

  > (f 1/2)

  #f

  > (f 0.5)

  #f

((disjoin f ...) arg ...)  boolean?

  f : (-> A ... boolean?)

  arg : A

Combines calls to each function with or.

Examples:

  (define f (disjoin exact? integer?))

  > (f 1)

  #t

  > (f 1.0)

  #t

  > (f 1/2)

  #t

  > (f 0.5)

  #f

(lambda/parameter (param-arg ...) body ...)

 

param-arg

 

=

 

param-arg-spec

 

 

|

 

keyword param-spec

 

 

 

 

 

param-arg-spec

 

=

 

id

 

 

|

 

[id default-expr]

 

 

|

 

[id #:param param-expr]

Constructs a function much like lambda, except that some optional arguments correspond to the value of a parameter. For each clause [id #:param param-expr] in which param-expr evalutes to a value param satisfying parameter?, the default value of id is (param); conversely, when id is provided, param is bound to id via parameterize during the function call.

Examples:

  (define p (open-output-string))

  (define hello-world

    (lambda/parameter ([port #:param current-output-port])

      (display "Hello, World!")

      (newline port)))

  > (hello-world p)

  > (get-output-string p)

  "Hello, World!\n"

3 Imperative Queues

 (require (planet cce/scheme:1:2/queue))

This module provides a mutable queue representation.

(make-queue)  queue/c

Produces an empty queue.

(enqueue! q v)  void?

  q : queue/c

  v : any/c

Adds an element to the back of a queue.

(dequeue! q)  any/c

  q : nonempty-queue/c

Removes an element from the front of a nonempty queue, and returns that element.

Examples:

  (define q (make-queue))

  > (enqueue! q 1)

  > (dequeue! q)

  1

  > (dequeue! q)

  top-level broke the contract (-> "nonempty-queue" any/c) on

  dequeue!; expected <nonempty-queue>, given: #<queue>

  > (enqueue! q 2)

  > (enqueue! q 3)

  > (dequeue! q)

  2

  > (dequeue! q)

  3

  > (dequeue! q)

  top-level broke the contract (-> "nonempty-queue" any/c) on

  dequeue!; expected <nonempty-queue>, given: #<queue>

(queue-empty? q)  boolean?

  q : queue/c

Recognizes whether a queue is empty or not.

Examples:

  (define q (make-queue))

  > (queue-empty? q)

  #t

  > (enqueue! q 1)

  > (queue-empty? q)

  #f

  > (dequeue! q)

  1

  > (queue-empty? q)

  #t

(queue? v)  boolean?

  v : any/c

This predicate recognizes queues.

Examples:

  > (queue? (make-queue))

  #t

  > (queue? 'not-a-queue)

  #f

queue/c : flat-contract?

nonempty-queue/c : flat-contract?

These contracts recognize queues; the latter requires the queue to contain at least one value.

4 Syntax Objects

 (require (planet cce/scheme:1:2/syntax))

This module provides tools for macro transformers.

(syntax-datum/c datum/c)  flat-contract?

  datum/c : flat-contract/predicate?

Recognizes syntax objects stx such that (syntax->datum stx) satisfies datum/c.

(syntax-listof/c elem/c)  flat-contract?

  elem/c : flat-contract/predicate?

Recognizes syntax objects stx such that (syntax->list stx) satisfies (listof elem/c).

(syntax-list/c elem/c ...)  flat-contract?

  elem/c : flat-contract/predicate?

Recognizes syntax objects stx such that (syntax->list stx) satisfies (list/c elem/c ...).

(syntax-map f stx)  (listof A)

  f : (-> syntax? A)

  stx : syntax?

Performs (map f (syntax->list stx)).

Examples:

  > (syntax-map syntax-e #'(a (b c) d))

  (a (#<syntax:1:0> #<syntax:1:0>) d)

(to-syntax

 

datum

 

 

 

 

 

 [

#:stx stx

 

 

 

 

 

 

#:src src

 

 

 

 

 

 

#:ctxt ctxt

 

 

 

 

 

 

#:prop prop

 

 

 

 

 

 

#:cert cert])

 

 

syntax?

  datum : any/c

  stx : (or/c false/c syntax?) = #f

  src : (or/c false/c syntax?) = #f

  ctxt : (or/c false/c syntax?) = #f

  prop : (or/c false/c syntax?) = #f

  cert : (or/c false/c syntax?) = #f

A wrapper for datum->syntax with keyword arguments for the syntax properties. Users may leave them all off for unadorned syntax objects, or use the "master" keyword #:stx to set all properties from one syntax object, or use the other keywords for individual kinds of properties, or some combination thereof.

Examples:

  (define blank-stx (to-syntax 'car))

  > blank-stx

  #<syntax>

  > (syntax-e blank-stx)

  car

  > (free-identifier=? blank-stx #'car)

  #f

  (define full-stx (to-syntax 'car #:stx #'here))

  > full-stx

  #<syntax:13:0>

  > (syntax-e full-stx)

  car

  > (free-identifier=? full-stx #'car)

  #t

  (define partial-stx (to-syntax 'car #:ctxt #'here))

  > partial-stx

  #<syntax>

  > (syntax-e partial-stx)

  car

  > (free-identifier=? partial-stx #'car)

  #t

(to-datum v)  (not/c syntax?)

  v : any/c

A deeply-traversing version of syntax->datum; this copies v, descending into pairs, vectors, and prefab structures, converting syntax objects to the data they contain along the way.

Examples:

  > (to-datum '(a b c d))

  (a b c d)

  > (to-datum #'(a b c d))

  (a b c d)

  > (to-datum (list 'a #'(b c) 'd))

  (a (b c) d)

current-syntax : (parameter/c (or/c syntax? false/c))

A parameter that may be used to store the current syntax object being transformed. It is not used by the expander; you have to assign to it yourself. This parameter is used by syntax-error, below. It defaults to #f.

(syntax-error stx fmt arg ...)  none/c

  stx : syntax?

  fmt : string?

  arg : any/c

Raises a syntax error based on the locations of (current-syntax) and stx, with (format fmt arg ...) as its message.

Examples:

  (define stx #'(a b c))

  > (parameterize ([current-syntax #f])

      (syntax-error stx "~s location" 'general))

  eval:1:0: a: general location in: (a b c)

  > (parameterize ([current-syntax stx])

      (syntax-error (car (syntax-e stx)) "~s location" 'specific))

  eval:1:0: a: specific location at: a in: (a b c)

(with-syntax* ([pattern expr] ...) body ...+)

Like with-syntax, but with nested scope.

Examples:

  > (with-syntax* ([a #'id] [b #'a]) (syntax-e #'b))

  id

5 Text Representations

 (require (planet cce/scheme:1:2/text))

This module provides tools for manipulating and converting textual data.

text/c : flat-contract?

(text? v)  boolean?

  v : any/c

This contract and predicate recognize text values: strings, byte strings, symbols, and keywords, as well as syntax objects containing them.

Examples:

  > (text? "text")

  #t

  > (text? #"text")

  #t

  > (text? 'text)

  #t

  > (text? '#:text)

  #t

  > (text? #'"text")

  #t

  > (text? #'#"text")

  #t

  > (text? #'text)

  #t

  > (text? #'#:text)

  #t

  > (text? '(not text))

  #f

(string-literal? v)  boolean?

  v : any/c

(bytes-literal? v)  boolean?

  v : any/c

(keyword-literal? v)  boolean?

  v : any/c

These predicates recognize specific text types stored in syntax objects.

Examples:

  > (string-literal? #'"literal")

  #t

  > (string-literal? "not literal")

  #f

  > (bytes-literal? #'#"literal")

  #t

  > (bytes-literal? #"not literal")

  #f

  > (keyword-literal? #'#:literal)

  #t

  > (keyword-literal? '#:not-literal)

  #f

(text->string text ...)  string?

  text : text/c

(text->bytes text ...)  bytes?

  text : text/c

(text->symbol text ...)  symbol?

  text : text/c

(text->keyword text ...)  keyword?

  text : text/c

These functions convert text values to specific types, retaining their textual content and concatenating text when necessary.

Examples:

  > (text->string #"concat" #'enate)

  "concatenate"

  > (text->bytes 'concat #'#:enate)

  #"concatenate"

  > (text->symbol '#:concat #'"enate")

  concatenate

  > (text->keyword "concat" #'#"enate")

  #:concatenate

(text->string-literal text ... [#:stx stx])  string-literal?

  text : text/c

  stx : (or/c syntax? false/c) = #f

(text->bytes-literal text ... [#:stx stx])  bytes-literal?

  text : text/c

  stx : (or/c syntax? false/c) = #f

(text->identifier text ... [#:stx stx])  identifier?

  text : text/c

  stx : (or/c syntax? false/c) = #f

(text->keyword-literal text ... [#:stx stx])  keyword-literal?

  text : text/c

  stx : (or/c syntax? false/c) = #f

These functions convert text values to specific syntax object types, retaining their textual value, concatenating text when necessary, and deriving syntax object properties from the stx argument.

Examples:

  (define (show stx) (values stx (syntax-e stx)))

  > (show (text->string-literal #"concat" #'enate))

  #<syntax>

  "concatenate"

  > (show (text->bytes-literal 'concat #'#:enate))

  #<syntax>

  #"concatenate"

  > (show (text->identifier '#:concatenate #:stx #'props))

  #<syntax:10:0>

  concatenate

  > (show (text->keyword-literal "concatenate" #:stx #'props))

  #<syntax:13:0>

  #:concatenate

(text-append text ...)  text/c

  text : text/c

This function appends multiple text values, producing a text value of arbitrary type with the concatenated content.

Examples:

  > (text-append "a" #'"b" #"c" #'#"d" 'e #'f '#:g #'#:h)

  "abcdefgh"

(text=? one two)  boolean?

  one : text/c

  two : text/c

Compares the character content of two text values.

Examples:

  > (text=? 'a "b")

  #f

  > (text=? #'x (datum->syntax #f 'x))

  #t

  > (text=? '#:z #"y")

  #f

(text>? one two)  boolean?

  one : text/c

  two : text/c

Compares the character content of two text values.

Examples:

  > (text>? 'a "b")

  #f

  > (text>? #'x (datum->syntax #f 'x))

  #f

  > (text>? '#:z #"y")

  #t

(text<? one two)  boolean?

  one : text/c

  two : text/c

Compares the character content of two text values.

Examples:

  > (text<? 'a "b")

  #t

  > (text<? #'x (datum->syntax #f 'x))

  #f

  > (text<? '#:z #"y")

  #f

6 Multiple Values

 (require (planet cce/scheme:1:2/values))

This module provides tools for functions producing multiple values.

(values->list expr)

Produces a list of the values returned by expr.

Examples:

  > (values->list (values 1 2 3))

  (1 2 3)

(map2 f lst ...)

 

 

(listof B)

 

(listof C)

  f : (-> A ... (values B C))

  lst : (listof A)

Produces a pair of lists of the respective values of f applied to the elements in lst ... sequentially.

Examples:

  > (map2 (lambda (x) (values (+ x 1) (- x 1))) (list 1 2 3))

  (2 3 4)

  (0 1 2)

(map/values n f lst ...)

 

 

(listof B_1)

 

...

 

(listof B_n)

  n : natural-number/c

  f : (-> A ... (values B_1 ... B_n))

  lst : (listof A)

Produces lists of the respective values of f applied to the elements in lst ... sequentially.

Examples:

  > (map/values

     3

     (lambda (x)

       (values (+ x 1) x (- x 1)))

     (list 1 2 3))

  (2 3 4)

  (1 2 3)

  (0 1 2)

(foldr/values f vs lst ...)

 

 

B

 

...

  f : (-> A ... B ... (values B ...))

  vs : (list/c B ...)

  lst : (listof A)

(foldl/values f vs lst ...)

 

 

B

 

...

  f : (-> A ... B ... (values B ...))

  vs : (list/c B ...)

  lst : (listof A)

These functions combine the values in the lists lst ... using the multiple-valued function f; foldr/values traverses the lists right to left and foldl/values traverses left to right.

Examples:

  (define (add/cons a b c d)

    (values (+ a c) (cons b d)))

  > (foldr/values add/cons (list 0 null)

                  (list 1 2 3 4) (list 5 6 7 8))

  10

  (5 6 7 8)

  > (foldl/values add/cons (list 0 null)

                  (list 1 2 3 4) (list 5 6 7 8))

  10

  (8 7 6 5)