Here's a subtle point of using Scheme (Chez, R6RS) records with inheritance:
;; creates a record, two default fields
(define-record-type Foo
(fields (mutable x) (mutable y))
(protocol (λ (new) (λ ()
(new 1 2) )))
)
;; creates a subtype, one specified field
(define-record-type Bar
(parent Foo)
(fields (mutable z))
(protocol (λ (super-new) (λ (z)
(let [ (new (super-new)) ]
(new z) ))))
)
(define b (make-Bar 3))
(Foo-x b)
1
(Foo-y b)
2
(Bar-z b)
3
The "new" your subtype protocol (constructor, in any OOP system) gets is a wrapper function that calls the parent protocol, and returns your actual "new". If you don't have a protocol, you just do (make-Bar 1 2 3)
and that works.
It's a little annoying that define-record-type doesn't copy accessors forward, leading to either that mess of Foo-x/y, Bar-z, or a long list of (define Bar-x Foo-x)
etc., but if I wanted a real object system I already have one. In my use case records are faster, I just didn't understand this quirk, and the docs don't help by calling the constructors "n" and "p".