Next: overview enabling, Up: overview [Contents][Index]
In this document we refer to the standard Scheme language defined by the R6RS specifications as the standard language; we refer to the typed Scheme language defined by Vicare as the typed language.
To understand how Vicare represents the types of values, we must remember that every Scheme expression might return multiple values; so we can think of an expression evaluation as follows:
(call-with-values (lambda () ?epxr) (lambda ?formals ?body))
the return values of ?expr are bound to the ?formals and used in the ?body. For example, in the code:
(call-with-values (lambda () (values 1 2 3)) (lambda (a b c) ?body))
while the expansion of ?body takes place: a typed language would
annotate the syntactic bindings a
, b
and c
with the
information that the values are fixnums.
The tuple of type annotations associated to the ?formals is called type signature; a type signature represents informations about both the number of values and their type. We need a type signature to represent the types of values returned by an expression. We need a type signature to represent the types of the arguments accepted in a function application.
Given the call-with-values
model of thinking to expressions
evaluations: the whole purpose of a typed language is to verify, at
expand–time, that the type signature of an expression matches the type
signature of the arguments of a function.
The standard language already mandates that the operands in a function application must be validated at run–time; this means the type signature of the operands is matched, at run–time, with the type signature of the arguments. The typed language extends this feature to make it possible at expand–time.
Type annotations are not mandatory in the typed language, so some operands are validated and others are not.
To understand the role of Vicare’s typed language extensions, we have to consider that:
flsin
can be implemented
as:
#!r6rs (import (except (rnrs (6)) flsin) (vicare system $flonums)) (define (flsin x) (assert (flonum? x)) ($flsin x))
#!r6rs (import (rnrs (6))) (define (flsomething x) (values (flsin x) (flcos x) (fltan x)))
can be transformed into (pseudo–code):
#!r6rs (import (rnrs (6)) (vicare system $flonums)) (define (flsomething x) (assert (flonum? x)) (values ($flsin x) ($flcos x) ($fltan x)))
or automatically defined safe and unsafe variants of the same function:
#!r6rs (import (rnrs (6)) (vicare system $flonums)) (define (flsomething x) (assert (flonum? x)) ($flsomething x)) (define ($flsomething x) (values ($flsin x) ($flcos x) ($fltan x)))
so that the unsafe $flsomething
can be used later in place of the
safe flsomething
if we know that the argument is a flonum.
Since there is no type inference: the code writer is invited to explicitly add type annotations to the syntaxes that establish syntactic bindings.
Next: overview enabling, Up: overview [Contents][Index]