Next: annotations relations, Previous: annotations inserting, Up: annotations [Contents][Index]
Type annotations are either standalone type identifiers like
<fixnum>
, <string>
, &message
or compound type
syntaxes like the following:
(pair <fixnum> <string>) (list <fixnum> <string> <symbol>) (vector <fixnum> <string> <symbol>) (pair-of <fixnum>) (list-of <fixnum>) (nelist-of <fixnum>) (vector-of <fixnum>) (nevector-of <fixnum>) (hashtable <symbol> <string>) (alist <symbol> <string>) (enumeration ?symbol0 ?symbol ...) (condition &who &message &irritants) (or <false> <symbol> <string>) (and <exact> <positive>) (not <exact>) (maybe <string>) (lambda (<fixnum>) => (<string>)) (case-lambda ((<fixnum>) => (<string>)) ((<flonum>) => (<string>))) (type-of ?expr)
and others; compound type annotations can be nested at will:
(or (list-of <fixnum>) (vector-of <fixnum>))
For every type annotation: a parent type is documented, but the
super–type/sub–type relation is “flexible”. For example,
list-of
and list
annotations are both sub–types of
<list>
; but it also stands that:
(type-annotation-super-and-sub? (list-of <fixnum>) (list <fixnum> <fixnum>)) ⇒ #t (type-annotation-super-and-sub? (list-of <fixnum>) (list <fixnum> <string>)) ⇒ #f
The following syntactic bindings are exported by (vicare)
.
Describe a pair having car of type ?car-type and cdr of type ?car-type. Both ?car-type and ?cdr-type are nested type annotations.
(is-a? '(1 . 2.3) (pair <fixnum> <flonum>)) ⇒ #t
Describe a proper list holding a fixed number of items of the specified types (in the given order). Every ?item-type is a nested type annotation.
(is-a? '(1 2.3) (list <fixnum> <flonum>)) ⇒ #t
Describe a vector holding a fixed number of items of the specified types (in the given order). Every ?item-type is a nested type annotation.
(is-a? '#(1 2.3) (vector <fixnum> <flonum>)) ⇒ #t
Describe a pair having both the car and cdr of type ?item-type. The syntax ?item-type is a nested type annotation.
(is-a? '(1 . 2) (pair-of <fixnum>)) ⇒ #t
Describe a proper list holding any number of items (including zero) all of the specified type. The syntax ?item-type is a nested type annotation.
(is-a? '(1 2) (list-of <fixnum>)) ⇒ #t (is-a? '() (list-of <fixnum>)) ⇒ #t
Describe a proper non–empty list holding any number of items all of the specified type. The syntax ?item-type is a nested type annotation. This type annotation is expanded to:
(pair ?item-type (list-of ?item-type))
Describe a vector holding any number of items (including zero) all of the specified type. The syntax ?item-type is a nested type annotation.
(is-a? '#(1 2) (vector-of <fixnum>)) ⇒ #t (is-a? '#() (vector-of <fixnum>)) ⇒ #t
Describe a vector holding one or more items all of the specified type. The syntax ?item-type is a nested type annotation.
(is-a? '#(1 2) (nevector-of <fixnum>)) ⇒ #t (is-a? '#() (nevector-of <fixnum>)) ⇒ #f
Describe a hashtable having keys of type ?key-type and values of type ?value-type. Both ?key-type and ?value-type are nested type annotations.
Describe an enumeration of symbols; it is used to match a symbol in a specified enumeration set.
(is-a? 'ciao (enumeration hello ciao salut ohayo)) ⇒ #t (is-a? 'blue (enumeration hello ciao salut ohayo)) ⇒ #f
As special case, if we define an alias for an enumeration
type
annotation: we can use such identifier to validate symbols. Example:
(define-type greetings (enumeration hello ciao salut ohayo)) (is-a? 'ciao greetings) ⇒ #t (greetings ciao) ⇒ ciao (greetings blue) error→ symbol not in enumeration
The enumeration identifier is indeed used in the implementation of the
define-enumeration
built–in syntax; (vicare-scheme)define-enumeration.
(define-enumeration greetings (hello ciao salut ohayo) make-greetings) (is-a? 'ciao greetings) ⇒ #t (greetings ciao) ⇒ ciao (greetings blue) error→ symbol not in enumeration
Describe an association list having keys of type ?key-type and values of type ?value-type. Both ?key-type and ?value-type are nested type annotations.
Describe a compound condition object holding at least one instance of
the specified types (the order does not matter). Every ?cond-type
is a nested type annotation that must be one among: <condition>
,
<compound-condition>
, a sub–type of &condition
.
(is-a? (condition (make-who-condition 'I) (make-message-condition "hello")) (condition &who &message)) ⇒ #t (is-a? (condition (make-who-condition 'I) (make-message-condition "hello")) (condition &message &who)) ⇒ #t
Describe a sub–type of <procedure>
having a single clause, like
procedures defined by lambda
. =>
is the syntactic
binding exported by (rnrs base (6))
.
The argument ?args-signature must be a syntax object representing the type signature of the procedure’s arguments. The argument ?rv-signature must be a syntax object representing the type signature of the procedure’s return values.
Describe a sub–type of <procedure>
having multiple clauses, like
procedures defined by case-lambda
. =>
is the
syntactic binding exported by (rnrs base (6))
.
Each ?clause argument must have the format:
(?args-signature => ?rv-signature)
where: ?args-signature must be a syntax object representing the type signature of the clause’s arguments; ?rv-signature must be a syntax object representing the type signature of the clause’s return values.
Describe the union between the specified types. Every ?type is a nested type annotation. A value matches a union of types if its type matches at least one of the union’s types.
(is-a? 1 (or <fixnum> <string>)) ⇒ #t (is-a? "ciao" (or <fixnum> <string>)) ⇒ #t (is-a? 1.23 (or <fixnum> <string>)) ⇒ #f
Describe the union between the specified types. Every ?type is a nested type annotation. A value matches a union of types if its type matches at least one of the union’s types.
(is-a? 1 (or <fixnum> <string>)) ⇒ #t (is-a? "ciao" (or <fixnum> <string>)) ⇒ #t (is-a? 1.23 (or <fixnum> <string>)) ⇒ #f
It is a shortcut for:
(or <false> ?type)
Describe the complement of the type. The argument ?type is a nested type annotation. A value of type ?val-type matches the complement of ?type if ?val-type is neither ?type nor a sub–type of ?type.
(is-a? 1 (not <string>)) ⇒ #t (is-a? 1.0 (not <fixnum>)) ⇒ #f ;;If something is not a "<number>", for sure it is ;;not a "<fixnum>". (type-annotation-super-and-sub? (not <fixnum>) (not <number>)) ⇒ #t
Describe the parent of the type; an exception is raised if the type has no parent. The argument ?type is a nested type annotation.
(type-annotation=? <struct> (parent-of <record>)) ⇒ #t (type-annotation=? <fixnum> (parent-of <positive-fixnum>)) ⇒ #t (type-annotation=? <positive-fixnum> (parent-of <fixnum>)) ⇒ #f
Describe the ancestors of the type; if the type has no parent: the list of ancestors is empty. The argument ?type is a nested type annotation and it is not included in its list of ancestors.
This type annotation can be used to match exactly a type annotation with one of the ancestors of ?type:
(type-annotation-matching (ancestor-of &condition) &condition) ⇒ no-match (type-annotation-matching (ancestor-of &condition) <condition>) ⇒ exact-match (type-annotation-matching (ancestor-of &condition) <record>) ⇒ exact-match (type-annotation-matching (ancestor-of &condition) <struct>) ⇒ exact-match (type-annotation-matching (ancestor-of &condition) <top>) ⇒ exact-match (type-annotation-matching <condition> (ancestor-of &condition)) ⇒ exact-match
When used along with not
, it is used to avoid matching exactly
a type annotation with one of the ancestors of ?type:
(type-annotation-matching (not (ancestor-of &condition)) <condition>) ⇒ no-match
A short–cut to specify:
(lambda (?type) => (<boolean>))
A short–cut to specify:
(lambda (?type ?type) => (<boolean>))
A short–cut to specify:
(lambda (?type ?type) => (<fixnum>))
A short–cut to specify:
(lambda (?type) => (<non-negative-fixnum>))
Describe the type of ?expr, which must be a Scheme expression. The type signature of ?expr must hold a single value. The expression is expanded and not evaluated; the side effects of the expansion are performed, so this type annotation must be used with care.
(type-annotation-syntax (type-of 123)) ⇒ <positive-fixnum> (type-annotation-syntax (type-of (void))) ⇒ <void> (let ((fun (lambda () 123))) (type-annotation-syntax (type-of (fun)))) ⇒ <positive-fixnum> (type-annotation-syntax (or (type-of 1) (type-of "ciao") (type-of 'hey))) ⇒ (or <positive-fixnum> <string> (enumeration hey))
The expression is not allowed not to return:
(type-annotation-syntax (type-of (error #f "error"))) error→ &assertion
The expression is not allowed to return zero, two or more values:
(type-annotation-syntax (type-of (values))) error→ &assertion (type-annotation-syntax (type-of (values 1 2))) error→ &assertion (type-annotation-syntax (type-of (values 1 2 3))) error→ &assertion
The expression is not allowed to return unspecified values:
(letrec ((fun (lambda ({_ . <list>}) (fun)))) (type-annotation-syntax (type-of (fun)))) error→ &assertion
The expression is expanded in the current lexical environment for phase zero, but with empty lexical environment for the other phases:
(let-syntax ((outer (lambda (stx) 123))) (type-annotation-syntax (outer))) error→ identifier OUTER out of context (let-syntax ((outer (lambda (stx) 123))) (type-annotation-syntax (type-of (let-syntax ((inner (lambda (stx) (outer)))) (inner))))) error→ identifier OUTER out of context
Next: annotations relations, Previous: annotations inserting, Up: annotations [Contents][Index]