[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: field initialization: Backward compatible suggestion



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