Next: , Up: annotations   [Contents][Index]


2.1 Inserting type annotations

Everywhere the name of a syntactic binding appears in binding position: we can add a type annotation by wrapping the syntactic identifier in braces and appending a type syntax. With let–like syntaxes we can do:

(let (({a <fixnum>} 1)
      ({b <string>} "ciao")
      ({c <symbol>} 'hello))
  (list a b c))

with lambda and case-lambda syntaxes we can do:

(lambda ({a <fixnum>} {b <string>})
  (list a b))

(case-lambda
  (({a <fixnum>} {b <string>})
   (list a b))
  (({a <fixnum>} {b <string>} {c <symbol>})
   (list a b c)))

with define and case-define syntaxes we can do:

(define (fun1 {a <fixnum>} {b <string>})
  (list a b))

(case-define fun2
  (({a <fixnum>} {b <string>})
   (list a b))
  (({a <fixnum>} {b <string>} {c <symbol>})
   (list a b c)))

When using the syntaxes lambda, case-lambda, define, case-define, receive, let-values and let*-values we can specify a “rest” argument that is bound to a list of the rest of the operands; this syntactic binding can be annotated only with a type that is a sub–type of <list>, and so represents a list. For example:

((lambda ({a <fixnum>} {b <string>} . {rest (list-of <symbol>)})
   (vector a b rest))
 1 "ciao" 'x 'y 'z)
⇒ #(1 "ciao" (x y z))

((lambda {args <list>} args)
 1 2 3)
⇒ (1 2 3)

(receive ({a <fixnum>} {b <string>} . {rest <list>})
    (values 1 "ciao" 'x 'y 'z)
  rest)
⇒ (x y z)