On this page:
arg+
arg+  -right
call
keyword-call
conjoin
disjoin
dynamic-wrap-procedure
normalize-procedure-arity
eta
define/  keywords
lambda/  keywords
8.12

7.1 mischief/function: Higher Order Functions🔗ℹ

 (require mischief/function) package: mischief

procedure

(arg+ proc arg ...)  procedure?

  proc : procedure?
  arg : any/c

procedure

(arg+-right proc arg ...)  procedure?

  proc : procedure?
  arg : any/c
Partially applies proc to the given args, which may include keyword arguments. The args are added as either the leftmost or rightmost arguments to proc, respectively.

Examples:
> (define one-two (arg+ list 1 2))
> (one-two 3 4)

'(1 2 3 4)

> (define sort< (arg+-right sort < #:cache-keys? #true))
> (sort< '("aunt" "anteater" "and" "an" "ant") #:key string-length)

'("an" "and" "ant" "aunt" "anteater")

procedure

(call proc arg-or-keyword-arg ...)  any

  proc : procedure?
  arg-or-keyword-arg : any/c
Applies proc to the given arg-or-keyword-args. Equivalent to (proc arg-or-keyword-arg ...).

Examples:
> (map call (list add1 sub1 - /) (list 1 2 3 4))

'(2 1 -3 1/4)

> (call sort '(one two three) string<? #:key symbol->string)

'(one three two)

procedure

(keyword-call proc ks vs x ...)  any

  proc : procedure?
  ks : (listof keyword?)
  vs : list?
  x : any/c
Applies proc to the positional arguments x ... and keyword arguments ks with values vs. Equivalent to (keyword-apply proc ks vs (list x ...)).

Example:
> (keyword-call
    sort
    '(#:cache-keys? key)
    (list #false first)
    '([2 a] [1 b] [3 c])
    <)

keyword-apply: contract violation

  expected: (listof keyword?)

  given: '(#:cache-keys? key)

  argument position: 2nd

  other arguments...:

   #<procedure:sort>

   '(#f #<procedure:first>)

   '(((2 a) (1 b) (3 c)) #<procedure:<>)

procedure

(conjoin proc ...)  procedure?

  proc : procedure?

procedure

(disjoin proc ...)  procedure?

  proc : procedure?
Produce the conjunction or disjunction, respectively, of the given predicates.

Examples:
> (define positive-integer? (conjoin positive? integer?))
> (positive-integer? 1)

#t

> (positive-integer? -1)

#f

> (positive-integer? 1.5)

#f

> (define <=? (disjoin < =))
> (<=? 1 2)

#t

> (<=? 1 1)

#t

> (<=? 2 1)

#f

> (define always-true (disjoin (const #true) error))
> (always-true #:irrelevant 'keyword)

#t

> (define never-true (conjoin (const #false) error))
> (never-true #:irrelevant 'keyword)

#f

procedure

(dynamic-wrap-procedure proc wrap)  procedure?

  proc : procedure?
  wrap : (-> (-> any) any)
Creates a procedure that invokes proc with its given arguments, but in a dynamic context established by wrap, such as the dynamic extent of parameterize.

Examples:
> (define (silent proc)
    (dynamic-wrap-procedure proc
      (lambda {thunk}
        (parameterize {[current-output-port (open-output-nowhere)]}
          (thunk)))))
> (define silent-write (silent write))
> (silent-write '(1 2 3))
> (silent-write '(1 2 3) (current-output-port))

(1 2 3)

> (with-output-to-string
    (lambda {}
      (silent-write "good night moon")))

""

procedure

(normalize-procedure-arity arity)  procedure-arity?

  arity : procedure-arity?
Produces a canonical form for the representation of a procedure’s arity.

Example:
> (normalize-procedure-arity (list 1 (arity-at-least 3) 0 4))

(list 0 1 (arity-at-least 3))

syntax

(eta proc-expr)

Eta-expands proc-expr; in other words, produces a procedure that behaves identically to proc-expr, except that proc-expr is not evaluated until the first time it is called.

Strictly speaking, eta-expansion would evaluate proc-expr every time it is called; the eta macro memoizes proc-expr itself. It does not memoize the results of the procedure proc-expr returns.

Examples:
> (define is-a-list?
    (disjoin empty?
      (conjoin cons?
        (compose (eta is-a-list?) rest))))
> (is-a-list? '(1 2 3))

#t

> (is-a-list? '(1 2 3 . more))

rest: contract violation

  expected: (and/c list? (not/c empty?))

  given: '(1 2 3 . more)

syntax

(define/keywords (name-id keys-id vals-id . formals) body ...+)

syntax

(lambda/keywords {keys-id vals-id . formals} body ...+)

Define or construct, respectively, a procedure that accepts arbitrary keyword arguments, binding the list of keywords to keys-id and their respective values to vals-id.

Examples:
> (define/keywords (f keys vals . others)
    (list keys vals others))
> (f #:x 1 2 3 #:y 4)

'((#:x #:y) (1 4) (2 3))