Hi,
i making change in code that involuntary speedup the code.
(in macro to overload procedures). It is a bit too long to explain (see addendum at end of message).
I had this macro, the important part is only in the argument definition:
(define-syntax define-overload-existing-operator
(syntax-rules ()
((_ proc) (define-overload-existing-operator proc racket/base))
;; example: (define-overload-existing-operator · Scheme+/multiply)
((_ proc module-name)
(begin
(require (rename-in module-name (proc orig-proc)))
(define qproc (quote proc))
(define (proc . args-lst)
;;(display "proc=") (display proc) (newline)
;;(define ht (hash-table->alist $ovrld-ht$))
;;(display ht) (newline)
(define proc-lst (hash-table-ref $ovrld-ht$ qproc)) ;; example: ((number? string?) (lambda (n s) (display n) (display s) (newline)))
;;(display "proc-lst=") (display proc-lst)
;;(newline)
(define (check-args-lst pred-list) ; check arguments list match predicates
;;(display "pred-list=") (display pred-list) (newline)
;;(display "args-lst=") (display args-lst) (newline)
(check-arguments pred-list args-lst))
(define (test-proc pred-proc-list) ; test the procedure if it matches with arguments
;;(display "pred-proc-list=") (display pred-proc-list) (newline)
(if (check-args-lst (car pred-proc-list)) ;; check args
(car (cdr pred-proc-list)) ;; return procedure
#f))
(define proc-search-result (ormap test-proc proc-lst)) ; search for a procedure matching arguments
;;(display "proc-search-result=") (display proc-search-result) (newline)
(condx (proc-search-result (apply proc-search-result args-lst))
(exec
(define nb-args (length args-lst)))
((> nb-args 2) ;;(display ">2 args") (newline)
(proc (car args-lst) (apply proc (cdr args-lst))))
(else
;;(display "else") (newline)
(apply orig-proc args-lst))))
;;(hash-table-set! $ovrld-ht$ qproc (list (list (list number? number?) orig-proc)))
(hash-table-set! $ovrld-ht$ qproc '())
;;(replace-operator! orig-proc proc)
))))
and i added aside also this macro in code :
(define-syntax define-overload-existing-operator-annot
(syntax-rules ()
((_ proc orig-proc) (define-overload-existing-operator-annot proc orig-proc racket/base))
;; example: (define-overload-existing-operator · Scheme+/multiply)
((_ proc orig-proc module-name)
(begin
(require (rename-in module-name (proc orig-proc)))
(define qproc (quote proc))
(define (proc . args-lst)
;;(display "proc=") (display proc) (newline)
;;(define ht (hash-table->alist $ovrld-ht$))
;;(display ht) (newline)
(define proc-lst (hash-table-ref $ovrld-ht$ qproc)) ;; example: ((number? string?) (lambda (n s) (display n) (display s) (newline)))
;;(display "proc-lst=") (display proc-lst)
;;(newline)
(define (check-args-lst pred-list) ; check arguments list match predicates
;;(display "pred-list=") (display pred-list) (newline)
;;(display "args-lst=") (display args-lst) (newline)
(check-arguments pred-list args-lst))
(define (test-proc pred-proc-list) ; test the procedure if it matches with arguments
;;(display "pred-proc-list=") (display pred-proc-list) (newline)
(if (check-args-lst (car pred-proc-list)) ;; check args
(car (cdr pred-proc-list)) ;; return procedure
#f))
(define proc-search-result (ormap test-proc proc-lst)) ; search for a procedure matching arguments
;;(display "proc-search-result=") (display proc-search-result) (newline)
(condx (proc-search-result (apply proc-search-result args-lst))
(exec
(define nb-args (length args-lst)))
((> nb-args 2) ;;(display ">2 args") (newline)
(proc (car args-lst) (apply proc (cdr args-lst))))
(else
;;(display "else") (newline)
(apply orig-proc args-lst))))
(hash-table-set! $ovrld-ht$ qproc '())
))))
the critical change is that orig-proc (original procedure) is in the initial macro just a symbol in code, but in new macro it is now a parameter of the macro.
Also important part of code is :
(require (rename-in module-name (proc orig-proc)))
But then a running code pass from 27" to 15" with only those changes.
This is a good news !.
This is not a problem of course but i wanted to understand a bit what happen here,in cas of somebody have an idea? i suppose it is the internal process of Racket.
What have changed is that for example with + the annotation parser pass now orig-+ to the new macro define-overload-existing-operator-annot , it is no more orig-proc symbol that is used in the macro.
The global project is indeed code speed up but i did not expected speed up now as the code is not yet written, i use parser reader (#lang SRFI-105) ,syntax transformers (in Scheme+) and i'm adding a dispatcher parser for overloaded procedures and operators. For example + will only be used on integers fl+ will be used on floats,etc and so on for a lot of things. This of course require a sort of type annotation made by programmer. But the rest of the process should be transparent for programmer, made by the annotation parser.
Regards,
Damien
update with the current annot module, but it is of no importance :
(module annot racket/base
(require (only-in srfi/1 first second third))
(provide annot)
(define (is-define-overload-call? s)
(and (pair? s)
(eq? (car s) 'define-overload-existing-operator)))
; + --> orig-+
(define (create-original-symbol s)
(string->symbol (string-append "orig-" (symbol->string s))))
; (define-overload-existing-operator +) --> (define-overload-existing-operator-annot + orig-+)
(define (recreate-define-overload s) ; can shorten compute time from 27" to 15" without explainations !
(define len-s (length s))
(cond ((= len-s 2) `(define-overload-existing-operator-annot ,(second s) ,(create-original-symbol (second s))))
((= len-s 3) `(define-overload-existing-operator-annot ,(second s) ,(create-original-symbol (second s)) ,(third s)))
(else
(error "annot : bad overload syntax in : " s))))
(define (annot s)
(cond
((null? s) '()) ; empty list
((pair? s) ; proper list
(if (is-define-overload-call? (car s))
(cons (recreate-define-overload (car s))
(annot (cdr s)))
(cons (annot (car s))
(annot (cdr s)))))
(else s)) ; atom
)
) ; end module