More work in the master
branch of Vicare. I have bumped the version number
of the library (vicare)
to (0 4 2016 8 25)
.
The typed language now implements recursive types and forward type definitions; with this the toolbox for object–oriented programming should be complete. Mixins exist, but I have a lingering desire to attempt a traits implementation; I do not know if I will do them.
Everything I discuss here is relative to code in the head of the master
branch.
The syntax define-type
has seen development and it is now the only way to
define new type annotations. We can define new type annotations as follows:
(define-type <nnfx> <non-negative-fixnum>) (define-type <compound> (or <vector> <list>))
This syntax allows recursive type definitions:
(define-type <it> (or (list-of <fixnum>) (vector-of <it>)))
This syntax allows forward definitions: type annotations that are half–defined to allow for mutually recursive type definitions. Here is an example of forward definition that does nothing useful:
(define-type <it>) ;forward definition (define-type <it>) ;does nothing ;;Complete the definition of "<it>". (define-type <it> <number>)
Here is a possible definition for a <syntax-object>
type using mutually
recursive definitions:
(import (rename (only (vicare expander) <stx> <syntactic-identifier>) (<stx> <wrapped-syntax-object>))) (define-type <datum> (or <null> <boolean> <char> <number> <string> <bytevector>)) (define-type <syntax-object>) (define-type <pair-of-syntax-objects> (pair-of <syntax-object>)) (define-type <vector-of-syntax-objects> (vector-of <syntax-object>)) (define-type <syntax-object> (or <datum> <wrapped-syntax-object> <syntactic-identifier> <pair-of-syntax-objects> <vector-of-syntax-objects>))
EDIT (Fri Aug 26, 2016) This is broken for record–types. Whenever a method in a record–type definition has the record–type itself in its type signature: an error is raised. This is a design problem that slipped under my radar. It is not easy to fix it. Damn!
When the source–code reader is in #!vicare
mode, it is possible to include
“here documents” processed (at read–time) by custom functions. This feature works
only when reading source code for libraries or programs, at present it does
not work at the repl.
Let’s see how it works. Assuming the following library is in the search path:
(library (libdemo) (export doit) (import (rnrs)) (define (doit input-string) (read (open-string-input-port input-string))))
let’s consider this program file:
#!vicare (reader-import (libdemo)) (program (demo) (import (rnrs)) (display #<doit 456>#) (newline) (flush-output-port (current-output-port)))
we see that at the beginning of a program file (before the program
form) we have:
(reader-import (libdemo))
and in the body of the program we have the block:
#<doit 456>#
such block is converted by the reader to the form:
(doit "456")
notice that whitespace characters after the symbol "doit" are discarded. Such form
is handed to eval
and evaluated in the context of the lexical environment
resulting from importing (libdemo)
; the result of the evaluation is returned
to the reader for inclusion in its output. So the reader gets the symbolic
expression ‘456’.
So if we have a json parser library we can put a block #<json-to-sexp
...>#
in the code and have the json data converted to Scheme symbolic
expressions at read–time.
The new library (vicare language-extensions tuples)
implements tuples on top
of lists and vectors (using the typed language). Tuple–types are just label–types
used to provide convenient read–only access to lists and vectors. Tuples cannot be
sub–typed and have no methods; we have to use the full labels for that.
Usage examples with lists and untyped fields:
(define-list-tuple-type <stuff> (fields a b c)) (define T (new <stuff> 1 2 3)) (.a T) ⇒ 1 (.b T) ⇒ 2 (.c T) ⇒ 3
usage examples with vectors and typed fields:
(define-vector-tuple-type <stuff> (fields {a <fixnum>} {b <flonum>} {c <string>})) (define T (new <stuff> 1 2.3 "ciao")) T ⇒ #(1 2.3 "ciao") (.a T) ⇒ 1 (.b T) ⇒ 2.3 (.c T) ⇒ "ciao" (.length (.c T)) ⇒ 4