i'm renaming the identifier, or duplicating it with rename-in but strangely my code is not working, i post it for help, sorry for the length but i have no idea why it fails, it is some overloading procedure not completely written but they should work (at least for new procedures):
(require srfi/69) ;; Basic hash tables
(define $ovrld-ht$ (make-hash-table))
(define-syntax overload
(syntax-rules ()
;; arguments are function to be overloaded, procedure that do the overloading, list of predicate to check the arguments
((_ funct-symb proc (pred-arg1 ...))
(overload-procedure funct-symb proc (pred-arg1 ...)))
;;((_ funct-symb proc (pred-arg1 ...) quote-operator)
;;(begin
;; (overload-operator funct-symb proc (pred-arg1 ...))
;; (update-operators))
;; )
;;((_ funct-symb proc (pred-arg1 ...) quote-operator quote-n-arity)
;;(begin
;;(overload-n-arity-operator funct-symb proc (pred-arg1 ...))
;;(update-operators)))
))
(define-syntax overload-procedure
(syntax-rules ()
((_ orig-funct funct (pred-arg1 ...))
(let ((ovrld-lst (hash-table-ref $ovrld-ht$ orig-funct)))
(hash-table-set! $ovrld-ht$ orig-funct
(cons (list (list pred-arg1 ...) ;; example: ((number? string?) (lambda (n s) (display n) (display s) (newline)))
funct)
ovrld-lst))))))
;; args must be the same number as predicates and their types must match
(define (check-arguments pred-list args)
(if (= (length pred-list) (length args))
(let ((pred-arg-list (map cons pred-list args)))
(andmap (λ (p) ((car p) (cdr p)))
;; replace andmap with every in Guile
;;(every (λ (p) ((car p) (cdr p)))
pred-arg-list))
#f))
(define-syntax define-overload-existing-procedure
(syntax-rules ()
((_ proc)
(begin
(require (rename-in racket/base (proc
orig-proc)))
(define (proc . args-lst)
(display proc) (newline)
(define ht (hash-table->alist $ovrld-ht$))
(display ht) (newline)
(define proc-lst (hash-table-ref $ovrld-ht$ proc)) ;; example: ((number? string?) (lambda (n s) (display n) (display s) (newline)))
;;(display proc-lst)
;;(newline)
(define (check-args-lst pred-list) ; check arguments list match predicates
(check-arguments pred-list args-lst))
(define (test-proc pred-proc-list) ; test the procedure if it matches with arguments
(if (check-args-lst (car pred-proc-list))
(car (cdr pred-proc-list))
#f))
(define proc-search-result (ormap test-proc proc-lst)) ; search for a procedure matching arguments
(if proc-search-result
(apply proc-search-result args-lst)
(apply orig-proc args-lst)))
(hash-table-set! $ovrld-ht$ proc '())))))
;; > (define-overload-procedure area)
;; > (define (area-square x) (* x x))
;; > (area-square 4)
;; 16
;; > (hash-table->alist $ovrld-ht$)
;; '((#<procedure:area>))
;; > (overload area area-square (number?))
;; > (hash-table->alist $ovrld-ht$)
;; '((#<procedure:area> ((#<procedure:number?>) #<procedure:area-square>)))
;; > (area 2)
;; 4
;; > (define (area-rectangle x y) (* x y))
;; > (overload area area-rectangle (number? number?))
;; > (area 2 5)
;; 10
(define-syntax define-overload-procedure
(syntax-rules ()
((_ proc)
(begin
(define (proc . args-lst)
(define proc-lst (hash-table-ref $ovrld-ht$ proc)) ;; example: ((number? string?) (lambda (n s) (display n) (display s) (newline)))
;;(display proc-lst)
;;(newline)
(define (check-args-lst pred-list) ; check arguments list match predicates
(check-arguments pred-list args-lst))
(define (test-proc pred-proc-list) ; test the procedure if it matches with arguments
(if (check-args-lst (car pred-proc-list))
(car (cdr pred-proc-list))
#f))
(define proc-search-result (ormap test-proc proc-lst)) ; search for a procedure matching arguments
(if proc-search-result
(apply proc-search-result args-lst)
(error 'overload "failed because procedure ~a can not be applied to arguments list ~a" proc args-lst)))
(hash-table-set! $ovrld-ht$ proc '())))))
it works for overloading new procedure:
;; > (define-overload-procedure area)
;; > (define (area-square x) (* x x))
;; > (area-square 4)
;; 16
;; > (hash-table->alist $ovrld-ht$)
;; '((#<procedure:area>))
;; > (overload area area-square (number?))
;; > (hash-table->alist $ovrld-ht$)
;; '((#<procedure:area> ((#<procedure:number?>) #<procedure:area-square>)))
;; > (area 2)
;; 4
;; > (define (area-rectangle x y) (* x y))
;; > (overload area area-rectangle (number? number?))
;; > (area 2 5)
;; 10
but fails with existing one, for example if i try to overload length ,which already exist in Scheme ,to works both for list and vector:
(define-overload-existing-procedure length)
> (overload length vector-length (vector?))
> (length #(1 2 3 4))
#<procedure:length>
((#<procedure:length> ((#<procedure:vector?>) #<procedure:vector-length>)))
. . ../../Scheme-PLUS-for-Racket/main/Scheme-PLUS-for-Racket/included-files/overload.scm:382:26: hash-table-ref: no value associated with #<procedure:length>
> (hash-table-ref $ovrld-ht$ length)
'(((#<procedure:vector?>) #<procedure:vector-length>))
> (hash-table->alist $ovrld-ht$)
'((#<procedure:length> ((#<procedure:vector?>) #<procedure:vector-length>)))
the problem come from here:
(define proc-lst (hash-table-ref ovrld-ht proc))
in define-overload-existing-procedure
the hash-table seems to have a key for length , (in fact #procedure:length, but is it the old one or the overloaded one? are they the same?
it can not find the value for the key, indeed all seems fine in hash table
note: i hope the code is complete to test for the one who can help