Let provider of generics check if a method exists
This change adds an additional argument to define-generics that binds a procedure to check if a given method is defined for an instance of the generic.
This commit is contained in:
parent
518bf0fd30
commit
e3b7640528
|
@ -23,10 +23,16 @@
|
|||
(provide define-generics)
|
||||
(define-syntax (define-generics stx)
|
||||
(syntax-case stx ()
|
||||
[(_ (name prop:name name?) (generic . generic-args) ...)
|
||||
;; defined-table binding is optional, so if it's not provided just
|
||||
;; hygienically generate some name to bind it to.
|
||||
[(_ (name prop:name name?) (generic . generics-args) ...)
|
||||
#'(define-generics (name prop:name name? defined-table)
|
||||
(generic . generics-args) ...)]
|
||||
[(_ (name prop:name name? defined-table) (generic . generic-args) ...)
|
||||
(and (identifier? #'name)
|
||||
(identifier? #'prop:name)
|
||||
(identifier? #'name?)
|
||||
(identifier? #'defined-table)
|
||||
(let ([generics (syntax->list #'(generic ...))])
|
||||
(and (pair? generics) (andmap identifier? generics))))
|
||||
(let ([idxs (for/list ([i (in-naturals 0)]
|
||||
|
@ -85,7 +91,7 @@
|
|||
#'id]
|
||||
[()
|
||||
#'()])))])
|
||||
#'(begin
|
||||
#`(begin
|
||||
(define-syntax name (list #'generic ...))
|
||||
; XXX optimize no kws or opts
|
||||
(define generic-arity-coerce
|
||||
|
@ -113,6 +119,14 @@
|
|||
(and mthd-generic
|
||||
(generic-arity-coerce mthd-generic)))
|
||||
...))))
|
||||
;; Hash table mapping method name symbols to
|
||||
;; whether the given method is implemented
|
||||
(define (defined-table this)
|
||||
(unless (name? this)
|
||||
(raise-type-error 'defined-table name-str this))
|
||||
(for/hash ([name (in-list '(#,@(map syntax->datum generics)))]
|
||||
[gen (in-vector (get-generics this))])
|
||||
(values name (not (not gen)))))
|
||||
(define generic
|
||||
(generic-arity-coerce
|
||||
(make-keyword-procedure
|
||||
|
|
Loading…
Reference in New Issue
Block a user