Re: field initialization: Backward compatible suggestion
Andre van Tonder 16 Sep 2005 23:41 UTC
For what it's worth, here is a revised suggestion that can handle
everything mentioned so far. It is backward compatible with the draft.
The hash table example looks just like in the draft:
(define-type hash-table (pred hasher size)
(fields (pred immutable)
(hasher immutable)
(data mutable (make-vector (nearest-prime size)))
(count mutable 0)))
(define-type eq-hash-table (pred hasher size)
(parent hash-table pred hasher size)
(fields (gc-count mutable 0)))
For more nontrivial things, there is a |constructor| clause:
(define-type rational (x y)
(fields (num immutable)
(denom immutable))
(constructor
(if (= y 0)
(fields (num 1)
(denom 0))
(let ((common (gcd x y)))
(fields
(num (/ x common))
(denom (/ y common)))))))
This works by binding the |fields| identifier to a macro whose scope is the
|constructor| clause, where it is used to specify fields by keyword.
For brevity, only the fields whose defaults we want to override need appear
in the constructor clause. For example, here is a hash table that adapts its
strategy based on size:
(define-type hash-table (pred hasher size)
(fields (pred immutable)
(hasher immutable)
(data mutable (make-vector (nearest-prime size)))
(count mutable 0))
(constructor
(if (and (eqv? pred eq?)
(< size 10))
;; assume speed of assq faster for <10
(fields (hasher (lambda (key) 0))
(data (make-vector 1)))
(fields)))))
Here, e.g., (fields) in the last line will just follow the defaults.
Cheers
Andre