On this page:
2.1 Detecting Symbolic Link Changes
filesystem/  link-change-evt
filesystem/  link-change-evt-cancel
filesystem/  link-change-evt?
2.2 Miscellaneous Utilities
delay/  thread/  eager-errors
2.3 Static Argument Checking
define/  check-args
define/  check-args/  contract
2.4 Structures
struct/  derived
2.5 Extensions to find-executable-path
preferred-PATH-spec/  c
2.6 Testing Meta-Language
2.7 Extending require-provide

2 Experimental

Unlike the preceding, features documented in this section are experimental and/or under development and are subject to breaking changes without notice.

I obviously don’t intend to break things gratuitously, but I suggest that before using these features in production code you check with me about their status or, in the worst-case scenario, fork the library.

2.1 Detecting Symbolic Link Changes


(filesystem/link-change-evt path-string)

  path-string : path-string?


(filesystem/link-change-evt-cancel evt)  any

  evt : filesystem/link-change-evt?


(filesystem/link-change-evt? v)  any/c

  v : any/c
Similar to filesystem-change-evt, filesystem-change-evt-cancel, and filesystem-change-evt?, respectively, except that the events created by filesystem/link-change-evt become ready at additional times when path-string is a symbolic link (according to link-exists?).

Specifically, for symbolic links, filesystem change events detect changes on the target of the symbolic link, not on the link itself. In addition to detecting those changes, events created by filesystem/link-change-evt also become ready for synchronization when the link itself is deleted or changed to point to a different target (according to file-or-directory-identity).

Like filesystem change events, events created by filesystem/link-change-evt allocate resources at the operating-system level, which are placed in the custody of the current custodian. These resources are released automatically when the event is chosen for synchronization: otherwise, they must be released by shutting down the custodian via custodian-shutdown-all or by explicitly calling filesystem/link-change-evt-cancel. In either case, the event becomes ready for synchronization (if it is not already).

Note that these functions remain experimental. In particular, the desired behavior on Windows (where filesystem changes can be tracked only at directory-level resolution) has not been determined.

Added in version 0.2 of package adjutor.

2.2 Miscellaneous Utilities


(in-match val-expr maybe-bind-clause pat ...+)

maybe-bind-clause = 
  | #:bind [rslt-id ...]
A rather unusual form of sequence syntax. Using in-match creates a single-element, potentially-multi-valued sequence, somewhat like in-value*/expression, but its peculiar characteristics make it better thought of as a way of turning a for-clause into a binding form like match-let-values or match-define.

The maybe-bind-clause is mandatory unless in-match is used directly within a for-clause.

The val-expr is an expression, and each pat is a pattern for match: these are tried against the value of val-expr in the usual way. Each pat must bind every rslt-id, or an unbound identifier error will occur. The values of the sequence are those bound to the rslt-ids (in order) by the first pat which matches successfully.

Conceptually, the following sequences written using in-match and in-value*/expression are equivalent:
(in-match val-expr #:bind [rslt-id ...] pat ...+)
(let ([val val-expr])
   (match val
      (values rslt-id ...)]

Asside from brevity, the key advantage of in-match is that it installs the values of the rslt-ids based on their names, eliminating the requirement of getting them in the right order in every match clause, as one must with in-value*/expression.

As a special case, when in-match is used directly within a for-clause, the maybe-bind-clause may be omitted. Omitting the maybe-bind-clause is equivalent to using the same identifiers bound by the for-clause, so that the following are equivalent:
(for ([(rslt-id ...) (in-match val-expr
                               pat ...+)])
  for-body ...+)
(for ([(rslt-id ...) (in-match val-expr
                               #:bind [rslt-id ...]
                               pat ...+)])
  for-body ...+)

If the maybe-bind-clause is used inside a for-clause, it must bind the same number of values expected by the for-clause; otherwise, a syntax error is raised.

An in-match application can provide better performance when it appears directly in a for-clause (with or without a maybe-bind-clause).

> (for*/list ([spec `([3 4 5]
                      [10 20])]
              [(a b c) (in-match spec
                                 (list a b c)
                                 (list a (and b c)))])
    (+ a b c))

'(12 50)

> (for/list ([(x y) (in-match '(1 2)
                              #:bind [a b]
                              (list a b))])
    (+ x y))


> (for/first ([(x y) (in-match '(1 2)
                               (list x z))])
    (+ x y))

y: undefined;

 cannot reference undefined identifier


(multi subs ...+)

subs = sub-path
  | (sub-path ...)
sub-path = rel-string
  | id
Like multi-in, but for use with require-provide.

Added in version 0.1 of package adjutor.


(delay/thread/eager-errors option ... body ...+)

option = #:pred pred
  | #:handler handler
  pred : (-> any/c any/c)
  handler : (-> any/c any)
Like (delay/thread body ...), but, if forcing the promise would raise an exception satisfying pred (which defaults to exn:fail?), handler (which defaults to raise) is called on the exception immediately in a background thread, without waiting for a call to force. Note that forcing a promise which raised such an exception still re-raises the exception as usual.

Note that, because handler is called in a new thread, catching such exceptions can be subtle.

> (require racket/promise)
> (force (delay/thread/eager-errors 42))


> (define example-promise
    (with-handlers ([exn:fail? (λ (e) (displayln "Never gets here."))])
      (delay/thread/eager-errors (error 'example))))
; The background-raised exception doesn't show well in Scribble.
; Try this at the REPL.
> example-promise

#<promise!exn!"error: example">

> (force example-promise)

error: example

2.3 Static Argument Checking


(define/check-args function-header body ...+)

Like the function form of define, but actually defines a macro that statically checks the number (and keywords) of arguments before expanding to an application of the underlying function. The function-header uses the same syntax as define (including curried functions, rest arguments, etc.), except that a plain identifier is dissalowed, as define/check-args must be able to determine the required arguments at compile time.

The resulting function can still be used as a first-class value, but checking only occurs for statically visible uses.

> (define/check-args (recur arg)
      [(pair? arg)
       (println (car arg))
       ; Oops! Forgot the arguments ...

eval:1.0: recur: too few by-position arguments

  at: ()

  within: (recur)

  in: (recur)


(define/check-args/contract function-header contract-expr body ...+)

  contract-expr : contract?
Like define/check-args, but the resulting function is additionally protected by the contract contract-expr. Unlike define/contract, blame is assigned to the module where the function is used (not necessarily the module where it is defined), facilitating the export of the identifier bound by define/check-args/contract.

2.4 Structures


 (error-id orig-form ...)
 id maybe-super (field ...)
 struct-option ...)
maybe-super = 
  | super-id
Defines a new structure type like struct, but with syntax errors reported in terms of (error-id orig-form ...) like define-struct/derived.

See struct for the grammar of field and struct-option.


(structure id maybe-super (field ...)
  option ...)
maybe-super = 
  | super-id
option = structure-option
  | restricted-struct-option
structure-option = #:constructor-contract contract-expr
  | #:constructor constructor-wrapper-expr
  | #:match-expander new-match-transformer
  contract-expr : contract?
  constructor-wrapper-expr : contract-expr
  new-match-transformer : (-> syntax? syntax?) ; in the transformer environment
In the simplest case, when no structure-options are given, defines a new structure type like struct, where a restricted-struct-option is any option that can be given to struct except for #:constructor-name, #:extra-constructor-name, #:name, and #:extra-name.

Any structure-options that are given control the meaning of id.

If a #:constructor option is given, the constructor-wrapper-expr is accessed instead of the default constructor when id is used as an expression. The constructor-wrapper-expr must satisfy the contract contract-expr if a #:constructor-contract option is given; otherwise, it is required to be a procedure. Inside the constructor-wrapper-expr, raw-constructor can be used to access the default constructor.

If a #:constructor-contract option is given without a #:constructor option, the default constructor is protected with the contract contract-expr.

If a #:match-expander clause is given, the new-match-transformer must be an expression in the transformer environment that produces a function from syntax to syntax. It is used instead of the default pattern-matching behavior when id is used as a match expander. Inside the new-match-transformer, raw-match-transformation can be used to implement transformers that expand to the default pattern-matching behavior.

As with struct, id can be used as a structure type transformer which can be used to define subtypes and cooperates with shared, struct-out, etc. (But note that a #:match-expander clause contols id’s cooperation with match.) For more detailed information about these uses of id, see Structure Type Transformer Binding.

Within a #:constructor clause of structure, accesses the plain constructor for the structure type. Illegal elsewhere.
Within a #:match-expander clause of structure, accesses a function that accepts a syntax object of the shape #'(_ pat ...) and returns syntax for match that matches each pat against the fields of the structure. Illegal elsewhere.

> (require (for-syntax racket/base syntax/parse))
> (structure point (x y z)
    #:constructor (λ ([x 0] [y 0] [z 0])
                    (raw-constructor x y z))
    #:constructor-contract (->* {}
                                {real? real? real?}
    #:match-expander (syntax-parser
                       [(_ x y z)
                        (raw-match-transformation #'(_ x y z))]
                       [(_ x y)
                        #'(point x y _)]
                       [(_ x)
                        #'(point x _ _)]
                        #'(point _ _ _)]))
> (match (point)
    [(point x) x])


> (struct-copy point (point 5)
               [z 42])

(point 5 0 42)

> (point #f)

point: contract violation

  expected: real?

  given: #f

  in: the 1st argument of

      (->* () (real? real? real?) point?)

  contract from: (definition point)

  blaming: top-level

   (assuming the contract is correct)

  at: eval:2.0

2.5 Extensions to find-executable-path

 (require adjutor/find-executable-path) package: adjutor

Racket provides find-executable-path for finding the paths of executables (or related files/directories) based on the PATH environment variable. However, in some cases programmers do not want to use the system-provided PATH.

In particular, on Mac OS, GUI programs are initialized with a very minimal PATH (at the time of writing, /usr/bin:/bin:/usr/sbin:/sbin), which prevents such programs from finding paths to most user-installed executables using find-executable-path unless the user takes special measures.

This library provides find-executable-path* and related bindings to address these cases at a higher level than manipulating environment variable sets directly.


(find-executable-path* program    
  deepest?])  (or/c path? #f)
  program : path-string?
  related : (or/c path-string? #f) = #f
  deepest? : any/c = #f
Like find-executable-path, but uses a PATH based on current-preferred-PATH-spec rather than current-environment-variables.


(current-preferred-PATH-spec)  preferred-PATH-spec/c

(current-preferred-PATH-spec spec)  void?
  spec : preferred-PATH-spec/c


preferred-PATH-spec/c : contract?

(or/c 'inherit
The parameter current-preferred-PATH-spec controls the PATH used by find-executable-path*. On platforms other than Mac OS, the default value is 'inherit.

On Mac OS, the default value is a byte string obtained by invoking Bash as a login shell and printing the PATH. This allows the PATH to be modified by the user’s .bash_profile and is consistent with the behavior of Terminal.app.

The derived parameter current-preferred-PATH can be used to access the actual byte string which find-executable-path* will use as the PATH.

The meaning of spec is as follows:
  • A value of 'inherit indicates that the PATH from current-environment-variables should be used, in which case find-executable-path* will work just like find-executable-path.

  • A value of #f means to use an environment with no mapping for PATH.

  • A byte string satisfying bytes-no-nuls? is coerced to an immutable byte string and used as the PATH.

  • A string satisfying string-no-nuls? is coerced to an immutable string, and the PATH is the result of converting the string to an (immutable) byte string using string->bytes/locale.

Support for additional kinds of spec is planned for the future, in which case the preferred-PATH-spec/c contract will be extended.


(or/c #f (and/c bytes-no-nuls?
(current-preferred-PATH spec)  void?
  spec : preferred-PATH-spec/c
An alternative interface to the same parameter as current-preferred-PATH-spec (see make-derived-parameter), but accesses the actual byte string which find-executable-path* will use as the PATH (or #f if it will use an environment with no mapping for PATH).

2.6 Testing Meta-Language

 #lang adjutor/test package: adjutor

The adjutor/test meta-language is useful for files that should only contain a test submodule. It chains to the following language like at-exp, then transforms the result of the other reader to place the body in a test submodule, leaving the enclosing module empty. It also arranges for a special #%top-interaction for the enclosing module so that the REPL is inside the test submodule.

To a first approximation, this is how a module using #lang adjutor/test is read compared to some host language:

#lang adjutor/test

Host Language


#lang adjutor/test lang-spec
body ...
#lang lang-spec
body ...


(module mod-name racket/base
  (module* test mod-lang
    body ...))
(module mod-name mod-lang
  body ...)

The main differences between the above table and the actual implementation of #lang adjutor/test are that a private module language is used instead of racket/base (to provide a useful #%top-interaction) and that a configure-runtime submodule is added.


(#%top-interaction . form)

The #%top-interaction installed for the enclosing module by #lang adjutor/test is configured to always enter! the test submodule before evaluating form.

2.7 Extending require-provide

The bindings in this section are provided for-syntax to be used in implementing extensions to require-provide. They are particularly experimental and subject to change.

A simple-require-provide-transformer contains a function proc (perhaps created syntax-parser) that specifies a simple macro-like rewrite rule. Like a macro, proc is called with the parenthesized form beginning with the identifier bound to the transformer itself. Its result must be a require-provide-spec.


(struct require-provide-transformer (proc))

  proc : 
(-> syntax?
    (values syntax? syntax?))
A require-provide-transformer is like a simple-require-provide-transformer, but more general. Its proc returns two syntax objects: the first must be a valid require-spec for use with require, and the second must be a provide-spec for use with provide.

syntax class


syntax class


Syntax classes recognizing the grammer for module paths and phase levels as specified by require and provide.

A syntax class recognizing the grammar documented under require-provide, including derived-require-provide-specs created with require-provide-transformer or simple-require-provide-transformer. It has two attributes require-stx and provide-stx, which are the syntax to be passed on to require and provide, respectively.