Added #:fast-defaults option to define-generics.

For datatypes that are disjoint with structs that might implement the generic,
this adds a "fast path" implementation that doesn't need to test for struct
properties.
This commit is contained in:
Carl Eastlund 2013-07-17 15:51:46 -04:00
parent 7deb4ad025
commit 1f267d479c
6 changed files with 57 additions and 23 deletions

View File

@ -20,6 +20,7 @@
ordered-methods ordered-methods
ordered-dict? ordered-dict?
dict-def-table) dict-def-table)
#:fast-defaults ()
#:defaults () #:defaults ()
#:fallbacks () #:fallbacks ()
#:derive-properties () #:derive-properties ()

View File

@ -7,13 +7,14 @@
(stream-first stream) (stream-first stream)
(stream-rest stream) (stream-rest stream)
(stream-empty? stream) (stream-empty? stream)
#:defaults #:fast-defaults
([list? ([list?
(define my-car car) (define my-car car)
(define stream-first my-car) (define stream-first my-car)
(define stream-rest cdr) (define stream-rest cdr)
(define stream-empty? null?)] (define stream-empty? null?)])
[s:stream? #:defaults
([s:stream?
(define stream-first s:stream-first) (define stream-first s:stream-first)
(define stream-rest s:stream-rest) (define stream-rest s:stream-rest)
(define stream-empty? s:stream-empty?)])) (define stream-empty? s:stream-empty?)]))

View File

@ -22,7 +22,8 @@
(define-primitive-generics (define-primitive-generics
(foo gen:foo prop:foo foo-methods foo? dummy) (foo gen:foo prop:foo foo-methods foo? dummy)
#:defaults ([number? (define (meth foo #:kw kw) kw)]) #:fast-defaults ([number? (define (meth foo #:kw kw) kw)])
#:defaults ()
#:fallbacks () #:fallbacks ()
#:derive-properties () #:derive-properties ()
(meth foo #:kw kw)) (meth foo #:kw kw))

View File

@ -31,6 +31,16 @@
(parse #'args (hash-set options 'defaults #'([pred defn ...] ...))))] (parse #'args (hash-set options 'defaults #'([pred defn ...] ...))))]
[(#:defaults . other) [(#:defaults . other)
(wrong-syntax (stx-car stx) "invalid #:defaults specification")] (wrong-syntax (stx-car stx) "invalid #:defaults specification")]
[(#:fast-defaults ([pred defn ...] ...) . args)
(if (hash-ref options 'fast-defaults #f)
(wrong-syntax (stx-car stx)
"duplicate #:fast-defaults specification")
(parse #'args
(hash-set options
'fast-defaults
#'([pred defn ...] ...))))]
[(#:fast-defaults . other)
(wrong-syntax (stx-car stx) "invalid #:fast-defaults specification")]
[(#:fallbacks [fallback ...] . args) [(#:fallbacks [fallback ...] . args)
(if (hash-ref options 'fallbacks #f) (if (hash-ref options 'fallbacks #f)
(wrong-syntax (stx-car stx) "duplicate #:fallbacks specification") (wrong-syntax (stx-car stx) "duplicate #:fallbacks specification")
@ -60,6 +70,7 @@
"expected a method identifier with formal arguments")] "expected a method identifier with formal arguments")]
[() (values (hash-ref options 'methods '()) [() (values (hash-ref options 'methods '())
(hash-ref options 'table generate-temporary) (hash-ref options 'table generate-temporary)
(hash-ref options 'fast-defaults '())
(hash-ref options 'defaults '()) (hash-ref options 'defaults '())
(hash-ref options 'fallbacks '()) (hash-ref options 'fallbacks '())
(hash-ref options 'derived '()))] (hash-ref options 'derived '()))]
@ -73,8 +84,9 @@
(parameterize ([current-syntax-context stx]) (parameterize ([current-syntax-context stx])
(unless (identifier? #'name) (unless (identifier? #'name)
(wrong-syntax #'name "expected an identifier")) (wrong-syntax #'name "expected an identifier"))
(define-values (methods table defaults fallbacks derived) (define-values (methods table fast-defaults defaults fallbacks derived)
(parse #'rest)) (parse #'rest))
(define/with-syntax [fast-default ...] fast-defaults)
(define/with-syntax [default ...] defaults) (define/with-syntax [default ...] defaults)
(define/with-syntax [fallback ...] fallbacks) (define/with-syntax [fallback ...] fallbacks)
(define/with-syntax [derive ...] derived) (define/with-syntax [derive ...] derived)
@ -94,6 +106,7 @@
(define-primitive-generics/derived (define-primitive-generics/derived
original original
(name gen-name prop-name get-name pred-name table-name) (name gen-name prop-name get-name pred-name table-name)
#:fast-defaults [fast-default ...]
#:defaults [default ...] #:defaults [default ...]
#:fallbacks [fallback ...] #:fallbacks [fallback ...]
#:derive-properties [derive ...] #:derive-properties [derive ...]

View File

@ -179,7 +179,7 @@
(define-primitive-generics (define-primitive-generics
(dict gen:dict prop:gen:dict prop:gen:dict-methods dict? dict-def-table) (dict gen:dict prop:gen:dict prop:gen:dict-methods dict? dict-def-table)
#:defaults #:fast-defaults
([mutable-hash? ([mutable-hash?
(define dict-ref hash-ref) (define dict-ref hash-ref)
(define dict-set! hash-set!) (define dict-set! hash-set!)
@ -222,6 +222,7 @@
(define dict-iterate-next assoc-iterate-next) (define dict-iterate-next assoc-iterate-next)
(define dict-iterate-key assoc-iterate-key) (define dict-iterate-key assoc-iterate-key)
(define dict-iterate-value assoc-iterate-value)]) (define dict-iterate-value assoc-iterate-value)])
#:defaults ()
#:fallbacks () #:fallbacks ()
#:derive-properties () #:derive-properties ()
(dict-ref dict key [default]) (dict-ref dict key [default])

View File

@ -34,6 +34,7 @@
accessor-name accessor-name
predicate-name predicate-name
supported-name) supported-name)
#:fast-defaults ([fast-pred fast-defn ...] ...)
#:defaults ([default-pred default-defn ...] ...) #:defaults ([default-pred default-defn ...] ...)
#:fallbacks [fallback-defn ...] #:fallbacks [fallback-defn ...]
#:derive-properties ([derived-prop derived-impl] ...) #:derive-properties ([derived-prop derived-impl] ...)
@ -54,21 +55,25 @@
(define/with-syntax [method-index ...] method-indices) (define/with-syntax [method-index ...] method-indices)
(define/with-syntax contract-str (define/with-syntax contract-str
(format "~s" (syntax-e #'predicate-name))) (format "~s" (syntax-e #'predicate-name)))
(define/with-syntax ([default-pred-name default-impl-name] ...) (define/with-syntax (default-pred-name ...)
(for/list ([pred-stx (in-list (syntax->list #'(default-pred ...)))] (generate-temporaries #'(default-pred ...)))
[i (in-naturals 0)]) (define/with-syntax (default-impl-name ...)
(list (format-id (syntax-local-introduce #'self-name) (generate-temporaries #'(default-pred ...)))
"~a-default-pred~a" (define/with-syntax (fast-pred-name ...)
#'self-name (generate-temporaries #'(fast-pred ...)))
i) (define/with-syntax (fast-impl-name ...)
(format-id (syntax-local-introduce #'self-name) (generate-temporaries #'(fast-pred ...)))
"~a-default-impl~a"
#'self-name
i))))
(define/with-syntax fallback-name (define/with-syntax fallback-name
(format-id (syntax-local-introduce #'self-name) (generate-temporary #'self-name))
"~a-fallback" (define/with-syntax forward-declaration
#'self-name)) (if (eq? (syntax-local-context) 'top-level)
#'(define-syntaxes (fast-pred-name ...
fast-impl-name ...
default-pred-name ...
default-impl-name ...
fallback-name)
(values))
#'(begin)))
#'(begin #'(begin
(define-syntax generic-name (define-syntax generic-name
(make-generic-info (quote-syntax property-name) (make-generic-info (quote-syntax property-name)
@ -97,16 +102,25 @@
derived-impl))) derived-impl)))
...) ...)
#t)) #t))
forward-declaration
(define (predicate-name self-name) (define (predicate-name self-name)
(or (prop:pred self-name) (default-pred-name self-name) ...)) (or (fast-pred-name self-name)
...
(prop:pred self-name)
(default-pred-name self-name)
...))
(define (table-name self-name [who 'table-name]) (define (table-name self-name [who 'table-name])
(cond (cond
[(fast-pred-name self-name) fast-impl-name]
...
[(prop:pred self-name) (accessor-name self-name)] [(prop:pred self-name) (accessor-name self-name)]
[(default-pred-name self-name) default-impl-name] [(default-pred-name self-name) default-impl-name]
... ...
[else (raise-argument-error who 'contract-str self-name)])) [else (raise-argument-error who 'contract-str self-name)]))
(define-values (default-pred-name ...) (define fast-pred-name fast-pred)
(values default-pred ...)) ...
(define default-pred-name default-pred)
...
(define-generic-support supported-name (define-generic-support supported-name
self-name self-name
[method-name ...] [method-name ...]
@ -120,6 +134,9 @@
(vector-ref fallback-name 'method-index)) (vector-ref fallback-name 'method-index))
original) original)
... ...
(define fast-impl-name
(generic-method-table generic-name fast-defn ...))
...
(define default-impl-name (define default-impl-name
(generic-method-table generic-name default-defn ...)) (generic-method-table generic-name default-defn ...))
... ...