Interface-Oriented Programming for Classes (original) (raw)
8.15
Ryan Culpepper <ryanc@racket-lang.org>
(define-interface name-id (super-ifc-id ...) (method-id ...))
Defines name-id as a static interface extending the interfaces named by the super-ifc-ids and containing the methods specified by the method-ids.
A static interface name is used by the checked method call variants (send/i, send*/i, and send/apply/i). When used as an expression, a static interface name evaluates to an interface value.
Examples:
> (define-interface stack<%> () (empty? push pop)) > stack<%> #<interface:stack<%>>
(define-interface/dynamic name-id ifc-expr (method-id ...))
Defines name-id as a static interface with dynamic counterpart ifc-expr, which must evaluate to an interface value. The static interface contains the methods named by themethod-ids. A run-time error is raised if anymethod-id is not a member of the dynamic interfaceifc-expr.
Use define-interface/dynamic to wrap interfaces from other sources.
Examples:
(send/i obj-exp static-ifc-id method-id arg-expr ...)
Checked variant of send.
The argument static-ifc-id must be defined as a static interface. The method method-id must be a member of the static interface static-ifc-id; otherwise a compile-time error is raised.
The value of obj-expr must be an instance of the interfacestatic-ifc-id; otherwise, a run-time error is raised.
Examples:
> (define s (new stack%)) > (send/i s stack<%> push 1) > (send/i s stack<%> popp) eval:9:0: send/i: method not in static interface in: popp > (send/i (new object%) stack<%> push 2) send/i: interface check failed on: (object)
(send*/i obj-expr static-ifc-id (method-id arg-expr ...) ...)
Checked variant of send*.
Example:
> (send*/i s stack<%> (push 2) (pop))
(send/apply/i obj-expr static-ifc-id method-id arg-expr ... list-arg-expr)
Example:
> (send/apply/i s stack<%> push (list 5))
(define/i id static-ifc-id expr)
Checks that expr evaluates to an instance ofstatic-ifc-id before binding it to id. Ifid is subsequently changed (with set!), the check is performed again.
No dynamic object check is performed when calling a method (usingsend/i, etc) on a name defined via define/i.
(init/i (id static-ifc-id maybe-default-expr) ...) (init-field/i (id static-ifc-id maybe-default-expr) ...) (init-private/i (id static-ifc-id maybe-default-expr) ...) maybe-default-expr = () | default-expr
Checked versions of init and init-field. The value attached to each id is checked against the given interface.
No dynamic object check is performed when calling a method (usingsend/i, etc) on a name bound via one of these forms. Note that in the case of init-field/i this check omission is unsound in the presence of mutation from outside the class. This should be fixed.
(define-interface-expander id transformer-expr)
Defines id as a macro that can be used withindefine-interface forms.
Examples: