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

Recursive types, reader extensions, tuples

Posted on Thu Aug 25, 2016

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.

Recursive types and forward type definitions

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>

(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>

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!

Reader extensions

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:

(reader-import (libdemo))
(program (demo)
  (import (rnrs))
  (display #<doit 456>#)
  (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.

Tuples on top of lists and vectors

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

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