
(define-data-type list
  (null? null)
  (pair?
   (cons car cdr)
   (car type car set-car!)
   (cdr pair cdr set-cdr!)))

=>

(define null 0)
cons etc. as before

Type as before, except that LIST is defined to be a datatype
that includes NULL and PAIRs.  NULL and PAIRs are defined to
be subtypes of LISTs.  How do pairs and null get injected into
lists?

What about polymorphism?  Ignore it for now.

Note that setters have a problem with destructuring - they don't work.

(if (bar? baz)
    ...
    ...)

Need temporary type bindings, a la LET.  Env and type env?
Have to do shallow binding, the infer code doesn't use environments.

Hacks like

   (if (bar? baz)
       (error ...))
   ... baz is not a bar ...

won't work.

----------------

New plan.  Use functions for pattern matching, with a suitable macro.

(define-data-type list delistify match-list
  (null? null)
  (pair?
   (cons car cdr)
   (car type car set-car!)
   (cdr pair cdr set-cdr!)))

Defines null as 0 and pairs as before.
NULL? and PAIR? are only available at load time.  There is also a
deconstructor DELISTIFY: [b list, [] -> a , [b, b list] -> a] -> a

(define (map f l)
  (delistify l
    (lambda ()
      null)
    (lambda (car cdr)
      (cons (f car) (map f cdr)))))

Or, with syntax,

(define (map f l)
  (match-list l
    ((null)
     null)
    ((cons car cdr)
     (cons (f car) (map f cdr)))))

This requires no change at all for the type checker.  Hee Wack!




