| t.link | Software | Links |
This Scheme package implements some macros: set/a!, define/a,
lambda/a, let/a, and let/a*. These macros aim at dealing with
optional arguments, type annotations, and interactive retrieval of
help information in Scheme.
Type annotations have the form: NAME:TYPE. The name may contain
colons, provided that there is a type annotation or that the last
character is a colon, which will not be part of the name. If there is
no type annotation, a variable is of type value. Thus, NAME:value
is the same as NAME.
Examples:
| Symbol: | Name: | Type: |
| x | x | value |
| x: | x | value |
| x:value | x | value |
| x:t: | x:t | value |
| :x | :x | value |
| x:t | x | t |
| x:x:t | x:x | t |
A type definition is a list of tags and corresponding values. New
types are being defined with the command (tl-type-set! NAME '(TAG
VALUE ...)). Here are some examples:
(tl-type-set! integer0-10
`(&type integer
&range ,(lambda (val) (and (>= val 0) (<= val 10)))))
(tl-type-set! my-number '(&or (integer real)))
(tl-type-set! colour '(&enum (red blue yellow black white)))
(tl-type-set! colours '(&list colour))
(tl-type-set! lower-case `(&check ,char-lower-case?))
(tl-type-set! lower-string '(&string lower-case))
(tl-type-set! char-numeric `(&check ,char-numeric?))
(tl-type-set! lower-case-or-number '(&or (lower-case char-numeric)))
(tl-type-set! lower-string '(&string lower-case-or-number))
(tl-type-set! small-integer `(&type integer &min 0 &max 10))
(tl-type-set! small-even-integer `(&type small-integer &min 2 &step 2))
As you can see from these examples, there are some predefined tags with special meanings:
&type SUPER&or (TYPE1 TYPE2 ...)&check FN/1#t
if a value conforms with the type definition. This one should only be
used for "native" types and class conformance.
&enum (SYMBOL1 SYMBOL2 ...)&list, &vector, &string TYPETYPE.
&min, &max, &step NN&step tag can
only be used with integers.
&frozen-type
This type system was made to allow run-time checks and to emulate some
kind of assertion mechanism as it is known from languages like Eiffel.
You can switch on and off certain checks when debugging your program.
Which run-time checks are performed is controlled by the variables
tl-types-excluded, tl-types-included, tl-types-enabled?, and the
following functions:
(tl-type-disable!)(tl-type-enable!)(tl-type-exclude . types)(tl-type-include . types)Example:
(let/a* ((a:integer 1) (b:integer a)) (+ a b))
Example:
(set/a! x:integer 2) (+ x 2)
Example:
(define x (lambda/a (a:integer b:integer) (+ a b)))
This form (but also lambda/a) allows the programmer to annotate
his/her definitions with some additional information. These tags are:
&optional (NAME DEFAULT)&rest NAME&returns TYPE or (TYPE1 TYPE2 ...)
As you can see from the example below, this approach is inspired by
Lisp's defun.
Example definition & function calls:
(define/a (test a b
&optional (c:integer 0)
&rest d
&returns (integer integer integer))
(values (+ a b) (+ a c) (apply + `(,a ,b ,c . ,d))))
| (test 1 2) | -> {3 1 3} |
| (test 1 2 (&optional 'c 3)) | -> {3 4 6} |
| (test 1 2 4 5 6) | -> {3 1 18} |
| (test 1 2 (&optional 'c 3) 4 5 6) | -> {3 4 21} |
| (test 1 2 (&optional 'c 3.5)) | -> type error |
| (test 1.5 2 (&optional 'c 3)) | -> {3.5 4 6.5} -> type error |
Anyway, you can also use the Scheme way to define a rest-argument.
(define/a (test a b c . d)
(values (+ a b) (+ a c) (apply + `(,a ,b ,c . ,d))))
(define/a (test a b c
&returns (integer integer integer)
. d)
(values (+ a b) (+ a c) (apply + `(,a ,b ,c . ,d))))
It is possible to add a documentations string to the define/a
form. You don't have to use this feature if you don't like it.
Example:
(define/a (test a b) "Surprise, it's a test" (+ a b))
These document strings are being gathered in a central database. The
information can be retrieved interactively by using the command
tl-info, e.g. (tl-info 'test). In a future version it will also be
possible to automatically create a html documention.
When using lambda/a or define/a two variables are being defined:
&optional-args (optional arguments) and &args (optional and
"rest" arguments). This means you can't access similarly named
variables "outside" the function. On the other hand, this, eh,
feature can be used to easily pass on optional arguments to other
functions.
The code has been tested (more or less) with MzScheme and should be
fairly portable as only low level macros are used. Anyway, in order to
use this package you will have to ...
"tsl" of where your
collections reside
(require-library "tl-define.scm" "tsl").
define/a and if tl-define isn't already loaded, you will have to
load (or require) "tl-optional.scm".
Preliminary version 0110a: define-a.tar.gz
| (c) 2001 Thomas Link (last updated Mar 27 2003) | home | top |