; scheme!!
(define (ar-funcaller1)
(lambda (f arg1)
;dispatch based on f, argument types, etc.
...))
(I've actually already implemented this experimentally, but the performance didn't increase much - however this was before I implemented serious multimethods (which I haven't actually completed implementing anyway...), so I suppose I can bring this back to amortize multimethod lookup.)
By using a callsite lambda object, we can keep track of previous multimethod etc. lookups.
And then we can make the compiler emit code especially for (foo 'bar) forms:
callsite1 can then cache lookups on hidden classes.
(define (always-false . rest) #f)
(define (ar-quotecaller1 quoted)
; use only a single variable to prevent
; race conditions in multi-threaded code
; (might not always work if using true
; threads instead of green ones though)
(let ((checker-and-dispatch (cons always-false #f)))
(lambda (ob)
; copy to our own local variable to
; prevent race conditions (assuming
; the read is atomic anyway)
(let* ((my-checker-and-dispatch checker-and-dispatch)
(checker (car my-checker-and-dispatch)))
(if (not (checker ob))
(begin
(set! my-checker-and-dispatch
(patch-quotecaller1 ob quoted))
(set! checker-and-dispatch my-checker-and-dispatch)))
((cdr my-checker-and-dispatch) ob quoted)))))
(define (patch-quotecaller1 ob quoted)
(cond
((table-with-hidden-class? ob) ; implemented however you will
(let* ((hidden-class (hidden-class-get ob))
(hidden-class-index (hidden-class-index-lookup hidden-class quoted)))
(cons
; checker
(lambda (ob _)
(and (table-with-hidden-class? ob)
(eq? hidden-class (hidden-class-get ob))))
; dispatcher
(lambda (ob _)
(hidden-class-ref ob hidden-class-index)))))
(... ;other conditions: functions, methods, other data types...
)))
I was actually going to implement this, but then I thought that using arc hash tables as objects - and in particular the (tb 'key) form - wasn't actually that common enough (at least in Arc) to justify optimizing for it. Hmm.