1 Language Model
2 Syntactic Forms
3 Datatypes
4 Structures
5 Classes and Objects
6 Units
7 Contracts
8 Pattern Matching
9 Control Flow
10 Concurrency
11 Macros
12 Input and Output
13 Reflection and Security
14 Operating System
15 Memory Management
16 Running PLT Scheme
Bibliography
Index
On this page:
procedure?
apply
compose
3.16.1 Keywords and Arity
keyword-apply
procedure-arity
procedure-arity?
procedure-arity-includes?
procedure-reduce-arity
procedure-keywords
make-keyword-procedure
procedure-reduce-keyword-arity
arity-at-least
prop: procedure
procedure-struct-type?
procedure-extract-target
prop: arity-string
3.16.2 Reflecting on Primitives
primitive?
primitive-closure?
primitive-result-arity
3.16.3 Additional Procedure Functions
negate
curry
curryr
Version: 4.0.2

 

3.16 Procedures

(procedure? v)  boolean

  v : any/c

Returns #t if v is a procedure, #f otherwise.

(apply proc v ... lst #:<kw> kw-arg ...)  any

  proc : procedure?

  v : any/c

  lst : list?

  kw-arg : any/c

The apply Function in Guide: PLT Scheme introduces apply.

Applies proc using the content of (list* v ... lst) as the (by-position) arguments. The #:<kw> kw-arg sequence is also supplied as keyword arguments to proc, where #:<kw> stands for any keyword.

The given proc must accept as many arguments as the number of vs plus length of lst, it must accept the supplied keyword arguments, and it must not require any other keyword arguments; otherwise, the exn:fail:contract exception is raised. The given proc is called in tail position with respect to the apply call.

Examples:

  > (apply + '(1 2 3))

  6

  > (apply + 1 2 '(3))

  6

  > (apply + '())

  0

  > (apply sort (list (list '(2) '(1)) <) #:key car)

  ((1) (2))

(compose proc ...)  procedure?

  proc : procedure?

Returns a procedure that composes the given functions, applying the last proc first and the first proc last. The composed functions can consume and produce any number of values, as long as each function produces as many values as the preceding function consumes.

Examples:

  > ((compose - sqrt) 10)

  -3.1622776601683795

  > ((compose sqrt -) 10)

  0+3.1622776601683795i

  > ((compose list split-path) (bytes->path #"/a" 'unix))

  (#<path:/> #<path:a> #f)

3.16.1 Keywords and Arity

(keyword-apply

 

proc

 

 

 

 

 

 

kw-lst

 

 

 

 

 

 

kw-val-lst

 

 

 

 

 

 

v ...

 

 

 

 

 

 

lst

 

 

 

 

 

 

#:<kw> kw-arg ...)

 

 

any

  proc : procedure?

  kw-lst : (listof keyword?)

  kw-val-lst : list?

  v : any/c

  lst : list?

  kw-arg : any/c

The apply Function in Guide: PLT Scheme introduces keyword-apply.

Like apply, but kw-lst and kw-val-lst supply by-keyword arguments in addition to the by-position arguments of the vs and lst, and in addition to the directly supplied keyword arguments in the #:<kw> kw-arg sequence, where #:<kw> stands for any keyword.

The given kw-lst must be sorted using keyword<?. No keyword can appear twice in kw-lst or in both kw-list and as a #:<kw>, otherwise, the exn:fail:contract exception is raised. The given kw-val-lst must have the same length as kw-lst, otherwise, the exn:fail:contract exception is raised. The given proc must accept all of the keywords in kw-lst plus the #:<kw>s, it must not require any other keywords, and it must accept as many by-position arguments as supplied via the vs and lst; otherwise, the exn:fail:contract exception is raised.

Examples:

  (define (f x #:y y #:z [z 10])

    (list x y z))

  > (keyword-apply f '(#:y) '(2) '(1))

  (1 2 10)

  > (keyword-apply f '(#:y #:z) '(2 3) '(1))

  (1 2 3)

  > (keyword-apply f #:z 7 '(#:y) '(2) '(1))

  (1 2 7)

(procedure-arity proc)  procedure-arity?

  proc : procedure?

Returns information about the number of by-position arguments accepted by proc. See also procedure-arity?.

(procedure-arity? v)  boolean?

  v : any/c

A valid arity a is one of the following:

Examples:

  > (procedure-arity cons)

  2

  > (procedure-arity list)

  #(struct:arity-at-least 0)

  > (arity-at-least? (procedure-arity list))

  #t

  > (arity-at-least-value (procedure-arity list))

  0

  > (arity-at-least-value (procedure-arity (lambda (x . y) x)))

  1

  > (procedure-arity (case-lambda [(x) 0] [(x y) 1]))

  (1 2)

(procedure-arity-includes? proc k)  boolean?

  proc : procedure?

  k : exact-nonnegative-integer?

Returns #t if the procedure can accept k arguments when no keyword arguments are supplied, #f otherwise.

Examples:

  > (procedure-arity-includes? cons 2)

  #t

  > (procedure-arity-includes? display 3)

  #f

(procedure-reduce-arity proc arity)  procedure?

  proc : procedure?

  arity : procedure-arity?

Returns a procedure that is the same as proc (including the same name returned by object-name), but that accepts only arguments consistent with arity. In particular, when procedure-arity is applied to the generated procedure, it returns a value that is equal? to arity.

If the arity specification allows arguments that are not in (procedure-arity proc), the exn:fail:contract exception is raised.

Examples:

  > (define my+ (procedure-reduce-arity + 2))

  > (my+ 1 2)

  3

  > (my+ 1 2 3)

  +: expects 2 arguments, given 3: 1 2 3

(procedure-keywords proc)

 

 

(listof keyword?)

(or/c (listof keyword?)

      false/c)

  proc : procedure?

Returns information about the keyword arguments required and accepted by a procedure. The first result is a list of keywords (sorted by keyword<?) that are required when applying proc. The second result is a list of accepted keywords (sorted by keyword<?), or #f to mean that any keyword is accepted. When the second result is a list, every element in the first list is also in the second list.

Examples:

  > (procedure-keywords +)

  ()

  ()

  > (procedure-keywords (lambda (#:tag t #:mode m) t))

  (#:mode #:tag)

  (#:mode #:tag)

  > (procedure-keywords (lambda (#:tag t #:mode [m #f]) t))

  (#:tag)

  (#:mode #:tag)

(make-keyword-procedure proc [plain-proc])  procedure?

  proc : (((listof keyword?) list?) () #:rest list? . ->* . any)

  

plain-proc

 

:

 

procedure?

 

 

 

=

 

(lambda args (keyword-apply proc null null args))

Returns a procedure that accepts all keyword arguments (without requiring any keyword arguments). See also procedure-reduce-keyword-arity.

When the result is called with keyword arguments, then proc is called; the first argument is a list of keywords sorted by keyword<?, the second argument is a parallel list containing a value for each keyword, and the remaining arguments are the by-position arguments.

When the result is called without keyword arguments, then plain-proc is called. Furthermore, procedure-arity obtains its result from plain-proc.

Examples:

  (define show

    (make-keyword-procedure (lambda (kws kw-args . rest)

                              (list kws kw-args rest))))

  > (show 1)

  (() () (1))

  > (show #:init 0 1 2 3 #:extra 4)

  ((#:extra #:init) (4 0) (1 2 3))

(procedure-reduce-keyword-arity

 

proc

 

 

 

 

 

 

arity

 

 

 

 

 

 

required-kws

 

 

 

 

 

 

allowed-kws)

 

 

procedure?

  proc : procedure?

  arity : procedure-arity?

  required-kws : (listof keyword?)

  

allowed-kws

 

:

 

(or/c (listof keyword?)

      false/c)

Like procedure-reduce-arity, but constrains the keyword arguments according to required-kws and allowed-kws, which must be sorted using keyword<?. If allowed-kws is #f, then the resulting procedure still accepts any keyword, otherwise the keywords in required-kws must be a subset of those in allowed-kws. The original proc must require no more keywords than the ones listed din required-kws, and it must allow at least the keywors in allowed-kws (or it must allow all keywords if allowed-kws is #f).

Examples:

  (define orig-show

    (make-keyword-procedure (lambda (kws kw-args . rest)

                              (list kws kw-args rest))))

  (define show (procedure-reduce-keyword-arity

                orig-show 3 '(#:init) '(#:extra #:init)))

  > (show #:init 0 1 2 3 #:extra 4)

  ((#:extra #:init) (4 0) (1 2 3))

  > (show 1)

  procedure ...me/private/kw.ss:124:25: expects 3 arguments

  plus an argument with keyword #:init plus an optional

  argument with keyword #:extra, given 1: 1

  > (show #:init 0 1 2 3 #:extra 4 #:more 7)

  procedure application: procedure:

  #<procedure:...me/private/kw.ss:124:25>; does not expect an

  argument with keyword #:more; arguments were: 1 2 3 #:extra

  4 #:init 0 #:more 7

(struct

 

arity-at-least

 

(value))

  value : nonnegative-exact-integer?

This structure type is used for the result of procedure-arity. See also procedure-arity?.

prop:procedure : struct-type-property?

A structure type property to indentify structure types whose instances can be applied as procedures. In particular, when procedure? is applied to the instance, the result will be #t, and when an instance is used in the function position of an application expression, a procedure is extracted from the instance and used to complete the procedure call.

If the prop:procedure property value is an integer, it designates a field within the structure that should contain a procedure. The integer must be between 0 (inclusive) and the number of non-automatic fields in the structure type (exclusive, not counting supertype fields). The designated field must also be specified as immutable, so that after an instance of the structure is created, its procedure cannot be changed. (Otherwise, the arity and name of the instance could change, and such mutations are generally not allowed for procedures.) When the instance is used as the procedure in an application expression, the value of the designated field in the instance is used to complete the procedure call. (This procedure can be another structure that acts as a procedure; the immutability of procedure fields disallows cycles in the procedure graph, so that the procedure call will eventually continue with a non-structure procedure.) That procedure receives all of the arguments from the application expression. The procedure’s name (see object-name) and arity (see procedure-arity) are also used for the name and arity of the structure. If the value in the designated field is not a procedure, then the instance behaves like (case-lambda) (i.e., a procedure which does not accept any number of arguments). See also procedure-extract-target.

Providing an integer proc-spec argument to make-struct-type is the same as both supplying the value with the prop:procedure property and designating the field as immutable (so that a property binding or immutable designation is redundant and disallowed).

Examples:

  > (define-struct annotated-proc (base note)

                   #:property prop:procedure

                              (struct-field-index base))

  > (define plus1 (make-annotated-proc

                    (lambda (x) (+ x 1))

                    "adds 1 to its argument"))

  > (procedure? plus1)

  #t

  > (annotated-proc? plus1)

  #t

  > (plus1 10)

  11

  > (annotated-proc-note plus1)

  "adds 1 to its argument"

When the prop:procedure value is a procedure, it should accept at least one argument. When an instance of the structure is used in an application expression, the property-value procedure is called with the instance as the first argument. The remaining arguments to the property-value procedure are the arguments from the application expression. Thus, if the application expression contained five arguments, the property-value procedure is called with six arguments. The name of the instance (see object-name) is unaffected by the property-value procedure, but the instance’s arity is determined by subtracting one from every possible argument count of the property-value procedure. If the property-value procedure cannot accept at least one argument, then the instance behaves like (case-lambda).

Providing a procedure proc-spec argument to make-struct-type is the same as supplying the value with the prop:procedure property (so that a specific property binding is disallowed).

Examples:

  > (define-struct fish (weight color)

                   #:mutable

                   #:property

                   prop:procedure

                   (lambda (f n)

                     (let ([w (fish-weight f)])

                      (set-fish-weight! f (+ n w)))))

  > (define wanda (make-fish 12 'red))

  > (fish? wanda)

  #t

  > (procedure? wanda)

  #t

  > (fish-weight wanda)

  12

  > (for-each wanda '(1 2 3))

  > (fish-weight wanda)

  18

If a structure type generates procedure instances, then subtypes of the type also generate procedure instances. The instances behave the same as instances of the original type. When a prop:procedure property or non-#f proc-spec is supplied to make-struct-type with a supertype that already behaves as a procedure, the exn:fail:contract exception is raised.

(procedure-struct-type? type)  boolean?

  type : struct-type?

Returns #t if instances of the structure type represented by type are procedures (according to procedure?), #f otherwise.

(procedure-extract-target proc)  (or/c false/c procedure?)

  proc : procedure?

If proc is an instance of a structure type with property prop:procedure, and if the property value indicates a field of the structure, and if the field value is a procedure, then procedure-extract-target returns the field value. Otherwise, the result if #f.

prop:arity-string : struct-type-property?

This property is used for reporting arity-mismatch errors when a structure type with the prop:procedure property is applied to the wrong number of arguments. The value of the prop:arity-string property must be a procedure that takes a single argument, which is the misapplied structure, and returns a string. The result string is used after the word “expects,” and it is followed in the error message by the number of actual arguments.

Arity-mismatch reporting automatically uses procedure-extract-target when the prop:arity-string property is not associated with a procedure structure type.

Examples:

  > (define-struct evens (proc)

      #:property prop:procedure (struct-field-index proc)

      #:property prop:arity-string

      (lambda (p)

        "an even number of arguments"))

  > (define pairs

      (make-evens

       (case-lambda

        [() null]

        [(a b . more)

         (cons (cons a b)

               (apply pairs more))])))

  > (pairs 1 2 3 4)

  ((1 . 2) (3 . 4))

  > (pairs 5)

  #<procedure>: expects an even number of arguments, given 1:

  5

3.16.2 Reflecting on Primitives

A primitive procedure is a built-in procedure that is implemented in low-level language. Not all procedures of scheme/base are primitives, but many are. The distinction is mainly useful to other low-level code.

(primitive? v)  boolean?

  v : any/c

Returns #t if v is a primitive procedure, #f otherwise.

(primitive-closure? v)  boolean

  v : any/c

Returns #t if v is internally implemented as a primitive closure rather than a simple primitive procedure, #f otherwise.

(primitive-result-arity prim)  procedure-arity?

  prim : primitive?

Returns the arity of the result of the primitive procedure prim (as opposed to the procedure’s input arity as returned by arity). For most primitives, this procedure returns 1, since most primitives return a single value when applied.

3.16.3 Additional Procedure Functions

 (require scheme/function)

The bindings documented in this section are provided by the scheme/function and scheme libraries, but not scheme/base.

(negate proc)  procedure?

  proc : procedure?

Returns a procedure that is just like proc, except that it returns the not of proc’s result.

Examples:

  > (filter (negate symbol?) '(1 a 2 b 3 c))

  (1 2 3)

  > (map (negate =) '(1 2 3) '(1 1 1))

  (#f #t #t)

(curry proc)  procedure?

  proc : procedure?

(curry proc v ...+)  any/c

  proc : procedure?

  v : any/c

Returns a procedure that is a curried version of proc. When the resulting procedure is first applied, unless it is given the maximum number of arguments that it can accept, the result is a procedure to accept additional arguments.

Examples:

  > ((curry list) 1 2)

  #<procedure:curried>

  > ((curry cons) 1)

  #<procedure:curried>

  > ((curry cons) 1 2)

  (1 . 2)

After the first application of the result of curry, each further application accumulates arguments until an acceptable number of arguments have been accumulated, at which point the original proc is called.

Examples:

  > (((curry list) 1 2) 3)

  (1 2 3)

  > (((curry list) 1) 3)

  (1 3)

  > ((((curry foldl) +) 0) '(1 2 3))

  6

A function call (curry proc v ...) is equivalent to ((curry proc) v ...). In other words, curry itself is curried.

The curry function provides limited support for keyworded functions: only the curry call itself can receive keyworded arguments to be propagated eventually to proc.

Examples:

  > (map ((curry +) 10) '(1 2 3))

  (11 12 13)

  > (map (curry + 10) '(1 2 3))

  (11 12 13)

  > (map (compose (curry * 2) (curry + 10)) '(1 2 3))

  (22 24 26)

  > (define foo (curry (lambda (x y z) (list x y z))))

  > (foo 1 2 3)

  (1 2 3)

  > (((((foo) 1) 2)) 3)

  (1 2 3)

(curryr proc)  procedure?

  proc : procedure?

(curryr proc v ...+)  any/c

  proc : procedure?

  v : any/c

Like curry, except that the arguments are collected in the opposite direction: the first step collects the rightmost group of arguments, and following steps add arguments to the left of these.

Examples:

  > (map (curryr list 'foo) '(1 2 3))

  ((1 foo) (2 foo) (3 foo))