Next: , Previous: , Up: syntaxes   [Contents][Index]


5.2 Defining type annotations

The following syntactic bindings are exported by the library (vicare).

Syntax: define-type ?name
Syntax: define-type ?name ?annotation

Define a new type annotation bound to ?name. The argument ?name must be a syntactic identifier. The argument ?annotation must be a type annotation syntax.

We can define new type annotations using the syntax define-type:

(define-type <nnfx>
  <non-negative-fixnum>)

(define-type <compound>
  (or <vector> <list>))

This syntax allows recursive type definitions:

(define-type <it>
  (or (list-of <fixnum>)
      (vector-of <it>)))

This syntax allows forward definitions: type annotations that are half–defined to allow for mutually recursive type definitions. Here is an example of forward definition that does nothing useful:

(define-type <it>)      ;forward definition
(define-type <it>)      ;does nothing

;;Complete the definition of "<it>".
(define-type <it> <number>)

Here is a possible definition for a <syntax-object> type using mutually recursive definitions:

(import (rename (only (vicare expander)
                      <stx> <syntactic-identifier>)
                (<stx> <wrapped-syntax-object>)))

(define-type <datum>
  (or <null> <boolean> <char> <number> <string> <bytevector>))

(define-type <syntax-object>)

(define-type <pair-of-syntax-objects>
  (pair-of <syntax-object>))

(define-type <vector-of-syntax-objects>
  (vector-of <syntax-object>))

(define-type <syntax-object>
  (or <datum>
      <wrapped-syntax-object>
      <syntactic-identifier>
      <pair-of-syntax-objects>
      <vector-of-syntax-objects>))

Forward definitions work only for identifiers defined in the same lexical contour. So the following works:

(define-type <it>)
(define-type <it>
  <fixnum>)

but the following will fail:

(define-type <it>)
(module (<it>)
  (define-type <it>
    <fixnum>))

because the concrete definition is inside a module, which represents a lexical contour.