Next: , Up: interfaces   [Contents][Index]


10.1 Introduction to interfaces

Let’s consider this code:

(define-record-type <a-vector>
  (fields {vec <nevector>})
  (method ({first <top>})
    (vector-ref (.vec this) 0)))

(define-record-type <a-string>
  (fields {vec <nestring>})
  (method ({first <top>})
    (string-ref (.vec this) 0)))

(define-record-type <a-list>
  (fields {vec <nelist>})
  (method ({first <top>})
    (car (.vec this))))

(define (fun O)
  (.first O))

(fun (new <a-vector> '#(1 2 3)))        ⇒ 1
(fun (new <a-string> "ABC"))            ⇒ #\A
(fun (new <a-list> '(a b c)))           ⇒ a

everything works fine in the function fun because all of <a-vector>, <a-string> and <a-list> implement the method ‘first’. The code (.first O) expands into a call to method-call-late-binding, which, at run–time, finds the method implementation functions in the type descriptors of <a-vector>, <a-string> and <a-list>.

Fine, but the code is not type–checked at expand–time. Enter interfaces. Let’s modify the code as follows:

(define-interface-type <Sequence>
  (method-prototype first
    (lambda () => (<top>))))

(define-record-type <a-vector>
  (implements <Sequence>)
  (fields {vec <nevector>})
  (method ({first <top>})
    (vector-ref (.vec this) 0)))

(define-record-type <a-string>
  (implements <Sequence>)
  (fields {vec <nestring>})
  (method ({first <top>})
    (string-ref (.vec this) 0)))

(define-record-type <a-list>
  (implements <Sequence>)
  (fields {vec <nelist>})
  (method ({first <top>})
    (car (.vec this))))

(define (fun {O <Sequence>})
  (.first O))

(fun (new <a-vector> '#(1 2 3)))        ⇒ 1
(fun (new <a-string> "ABC"))            ⇒ #\A
(fun (new <a-list> '(a b c)))           ⇒ a

everything works almost as before, but the record–type definition clause (implements <Sequence>) causes the expander to validate, at expand-time, that the record–types actually implement a method first with the correct type signature.

Also, the function application (fun ?operand) is validated at expand–time to verify that the type of ?operand is an object–type that implements <Sequence>. Such validation can happen only if the expander is able to determine the type of ?operand; this validation cannot happen at run–time, so, for example, it is impossible for label types to implement interfaces.


Next: , Up: interfaces   [Contents][Index]