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


5.8 Defining typed variables

In all the following syntax definitions, we assume the following formats for the input form components:

?standard-clause ==
  | (?standard-formals . ?body)

?typed-clause ==
  | (?typed-clause-formals . ?body)

?typed-clause-formals ==
  | ?typed-formals
  | (?anonymous-retvals . ?typed-formals)

?anonymous-retvals ==
  | (brace _ ?rv-type0 ?rv-type ...)
  | (brace _ ?rv-type ... . ?rest-rv-type)

?typed-var ==
  | ?name-id
  | (brace ?name-id ?type)

?typed-who ==
  | ?who-id
  | (brace ?who-id ?rv-type0 ?rv-type ...)
  | (brace ?who-id ?rv-type ... . ?rest-rv-type)

?standard-formals ==
  | ?args-id
  | (?arg-id ...)
  | (?arg-id ?arg-id0 ... . ?args-id)

?typed-formals ==
  | ?typed-args
  | (?typed-arg ...)
  | (?typed-arg0 ?typed-arg ... . ?typed-rest)

?typed-arg ==
  | ?arg-id
  | (brace ?arg-id ?arg-type)

?typed-args ==
  | ?args-id
  | (brace ?args-id ?args-type)

?typed-rest ==
  | ?rest-id
  | (brace ?rest-id ?rest-type)

?standard-binding ==
  | ?standard-var

?standard-var ==
  | ?name-id

?typed-binding ==
  | ?standard-var

where the following components are syntactic identifiers:

?name-id ?who-id ?arg-id ?args-id ?rest-id

the following components are type annotations:

?type ?arg-type ?rv-type

and the following components are type annotations that must represent lists:

?args-type ?rest-type ?rest-rv-type

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

Standard syntaxes

Syntax: define/std ?who-id
Syntax: define/std ?who-id ?expr
Syntax: define/std (?who-id . ?standard-formals) . ?body

This is the define syntax as defined by R6RS; whenever the define syntactic binding is used in code with the typed language disabled: it expands into a use of define/std.

Syntax: case-define/std ?who-id ?standard-clause0 ?standard-clause

This is a case-define syntax compatible with the R6RS language; whenever the case-define syntactic binding is used in code with the typed language disabled: it expands into a use of case-define/std.

Syntax: lambda/std ?standard-formals . ?body

This is the lambda syntax as defined by R6RS; whenever the lambda syntactic binding is used in code with the typed language disabled: it expands into a use of lambda/std.

Syntax: named-lambda/std ?name ?standard-formals . ?body

This is like lambda/std, but accepts an argument ?name which must be a syntactic identifier representing the name of the generated closure object. In the body of the clauses the quoted name is bound to the fluid syntax __who__.

Syntax: case-lambda/std ?standard-clause0 ?standard-clause

This is a case-lambda syntax defined by R6RS; whenever the case-lambda syntactic binding is used in code with the typed language disabled: it expands into a use of case-lambda/std.

Syntax: named-case-lambda/std ?name ?standard-clause0 ?standard-clause

This is like case-lambda/std, but accepts an argument ?name which must be a syntactic identifier representing the name of the generated closure object. In the body of the clauses the quoted name is bound to the fluid syntax __who__.

Syntax: let/std (?standard-binding …) . ?body
Syntax: let*/std (?standard-binding …) . ?body
Syntax: letrec/std (?standard-binding …) . ?body
Syntax: letrec*/std (?standard-binding …) . ?body

These are the binding syntaxes defined by R6RS: whenever the syntaxes let, let*, letrec, letrec* are used in code with the typed language disabled: they expand into a uses of let/std, let*/std, letrec/std, letrec*/std.

Syntax: receive/std ?standard-formals ?producer-expr . ?body
Syntax: receive-and-return/std ?standard-formals ?producer-expr . ?body

These are receive and receive-and-return syntaxes which define standard syntactic bindings: whenever the syntaxes receive, receive-and-return are used in code with the typed language disabled: they expand into a uses of receive/std and receive-and-return/std.

Checked syntaxes

Syntax: define/checked ?typed-var
Syntax: define/checked ?typed-var ?expr
Syntax: define/checked (?typed-who . ?typed-formals) . ?body

This is the define syntax that supports the typed language; whenever the define syntactic binding is used in code with the typed language enabled: it expands into a use of define/checked.

When defining a variable: the result of the expression is validated either at expand–time or at run–time, to make sure that it matches the type of the variable. The expression’s type must be a sub–type of the variable’s type.

When defining a function: the operands and return values are validated either at expand–time or at run–time, to make sure that they match the type of the function’s type signature. The operands’ types must be sub–types of the arguments’ types; the return values’ types must be sub–types of the declared signature types.

Usage examples:

(define/checked var1
  123)

(define/checked {var2 <string>}
  "hello")

(define/checked ({fun <string>} {N <fixnum>})
  (fixnum->string N))
Syntax: case-define/checked ?who-id ?typed-clause0 ?typed-clause

This is a case-define variant that supports the typed language. Operands and return values are validated either at expand–time or at run–time, to make sure that they match the type signature.

Usage examples:

(case-define/checked fun-1
  ((a b c)
   (list a b c))
  ((a b c . rest)
   (cons* a b c rest)))

(case-define/checked fun-2
  (({_ (list <fixnum> <fixnum> <fixnum>)}
      {a <fixnum>} {b <fixnum>} {c <fixnum>})
   (list a b c))
  (({_ (list-of <fixnum>)}
      {a <fixnum>} {b <fixnum>} {c <fixnum>}
      . {rest (list-of <fixnum>)})
   (cons* a b c rest)))
Syntax: lambda/checked ?typed-clause-formals . ?body

This is the lambda syntax that supports the typed language; whenever the lambda syntactic binding is used in code with the typed language enabled: it expands into a use of lambda/checked.

The operands and return values are validated either at expand–time and at run–time, to make sure that they match the type of the function’s type signature. The operands’ types must be sub–types of the arguments’ types; the return values’ types must be sub–types of the declared signature types.

Usage examples:

(lambda/checked (a b)
  (list a b))

(lambda/checked ({_ (list <fixnum> <fixnum>)}
                  {a <fixnum>} {b <fixnum>})
  (list a b))
Syntax: named-lambda/checked ?name ?typed-clause-formals . ?body

This is like lambda/checked, but accepts an argument ?name which must be a syntactic identifier representing the name of the generated closure object. In the body of the clauses the quoted name is bound to the fluid syntax __who__.

Usage examples:

(named-lambda/checked fun ({_ <string>} {N <fixnum>})
  (fixnum->string N))
Syntax: case-lambda/checked ?typed-clause0 ?typed-clause

This is a case-lambda syntax that supports the typed language; whenever the case-lambda syntactic binding is used in code with the typed language enabled: it expands into a use of case-lambda/checked.

Usage examples:

(case-lambda/checked
  (({_ <string>} {N <fixnum>})
   (fixnum->string N))
  (({_ <string>} {N <fixnum>} {base <fixnum>})
   (fixnum->string N base)))
Syntax: named-case-lambda/checked ?name ?typed-clause0 ?typed-clause

This is like case-lambda/checked, but accepts an argument ?name which must be a syntactic identifier representing the name of the generated closure object. In the body of the clauses the quoted name is bound to the fluid syntax __who__.

Syntax: let/checked (?typed-binding …) . ?body
Syntax: let/checked ?recur (?typed-binding …) . ?body
Syntax: let*/checked (?typed-binding …) . ?body
Syntax: letrec/checked (?typed-binding …) . ?body
Syntax: letrec*/checked (?typed-binding …) . ?body

These are the binding syntaxes that support the typed language: whenever the syntaxes let, let*, letrec, letrec* are used in code with the typed language enabled: they expand into a uses of let/checked, let*/checked, letrec/checked, letrec*/checked.

Notice how we can specify type annotation when using the named–let syntax. The following recursive function and its application to operands:

(define/checked ({loop <fixnum>} {a <fixnum>} {b <list>})
  (if (fx=? a 3)
      b
    (loop (fxadd1 a) (cons a b))))

(loop 1 '())

can be written:

(let/checked {loop <fixnum>} (({a <fixnum>} 1)
                                ({b <list>}   '()))
  (if (fx=? a 3)
      b
    (loop (fxadd1 a) (cons a b))))

where the “name” of the named–let contains the type annotations of the return values.

Syntax: receive/checked ?typed-formals ?producer-expr . ?body
Syntax: receive-and-return/checked ?typed-formals ?producer-expr . ?body

These are receive and receive-and-return syntaxes which define typed syntactic bindings: whenever the syntaxes receive, receive-and-return are used in code with the typed language enabled: they expand into a uses of receive/checked and receive-and-return/checked.

Typed syntaxes

Syntax: define/typed ?typed-var
Syntax: define/typed ?typed-var ?expr
Syntax: define/typed (?typed-who . ?typed-formals) . ?body

This is a define syntax variant that supports the typed language: with expand–time validation, without run–time validation.

When defining a variable: the result of the expression is validated only at expand–time, to make sure that it matches the type of the variable. The expression’s type must be a sub–type of the variable’s type.

When defining a function: the operands and return values are validated only at expand–time, to make sure that they match the type of the function’s type signature. The operands’ types must be sub–types of the arguments’ types; the return values’ types must be sub–types of the declared signature types.

Syntax: case-define/typed ?who-id ?typed-clause0 ?typed-clause

This is a case-define variant that supports the typed language. Operands and return values are validated only expand–time, to make sure that they match the type signature.

Syntax: lambda/typed ?typed-clause-formals . ?body

This is a lambda syntax variant supports the typed language: with expand–time validation, without run–time validation.

The operands and return values are validated only at expand–time, to make sure that they match the type of the function’s type signature. The operands’ types must be sub–types of the arguments’ types; the return values’ types must be sub–types of the declared signature types.

Syntax: named-lambda/typed ?name ?typed-clause-formals . ?body

This is like lambda/typed, but accepts an argument ?name which must be a syntactic identifier representing the name of the generated closure object. In the body of the clauses the quoted name is bound to the fluid syntax __who__.

Syntax: case-lambda/typed ?typed-clause0 ?typed-clause

This is a case-lambda syntax that supports the typed language: with expand–time validation, without run–time validation.

Syntax: named-case-lambda/typed ?name ?typed-clause0 ?typed-clause

This is like case-lambda/typed, but accepts an argument ?name which must be a syntactic identifier representing the name of the generated closure object. In the body of the clauses the quoted name is bound to the fluid syntax __who__.


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