I can not find a real subject for this problem : (display +) (define + 7) : error

#lang racket
(display +)
(define + 3)
Welcome to DrRacket, version 8.9 [cs].
Language: racket, with debugging; memory limit: 8192 MB.
. . +: undefined;
 cannot reference an identifier before its definition

does anyone know how to avoid this problem? it is really a true problem in my code but i can simplify it to this example , i need to have operators such as + defined before i modify them ... and avoid this nightmare :slight_smile:
sometimes i really love Python

What do you expect (display +) to do in this situation?

it is just to show the problem the true code is bigger consider this example if you prefer:

#lang racket
(+ 3 2)
(define + 3)

the true code giving same problem was:

#lang racket

(require srfi/69) ;; Basic hash tables
(define $ovrld-ht$ (make-hash-table))


;; 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-operator

  (syntax-rules ()

    ((_ proc)

     (begin

       (define qproc (quote proc)) 
       
       (define (proc . args-lst)
	 
	 (define proc-lst (hash-table-ref $ovrld-ht$ qproc)) ;;  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

         (define nb-args (length args-lst))
         
	 (cond  (proc-search-result (apply proc-search-result args-lst))
		 
		 ((> nb-args 2) (proc (car args-lst) (apply proc (cdr args-lst))))
		 (else (error 'overload "failed because procedure ~a can not be applied to arguments list ~a" qproc args-lst))))
       
       (hash-table-set! $ovrld-ht$ qproc '())

       ;;(update-operators)
       ))))


(display +)

(define-overload-operator +)

(display +)

Works for me.

Welcome to Racket v8.9 [cs].
> (display +)
#<procedure:+>
> (define + 3)
> +
3

yes but at toplevel....

i think we already discussed this topic with me but i can not fond the thread again...
and i can't remember the conclusions

Imagine a mathematics book.

On page 2, you encounter a reference to a function called Plus.

You read on. And you’re confused on page 3, page 4, page 5, and so on.

On page 11, you discover that the Plus is - (subtraction). Now everything makes sense on pages 2 through 10.

;; - - -

Racket modules enforce that definitions that bind names to values (for example functions or objects) occur before your program de-references the name. So even if everything is defined properly — like in the silly example above — when a name is used (its meaning must be understood now), the ordering of evaluation of definitions matters.

The Racket top-level is hopeless, meaning it’s like the book above.

i know that. problem is in my code that redefine a racket/base function, and i too much tested in toplevel, thing now fails in module, yes toplevel is hopeless and useless

but at the end your completely right :slight_smile:

i had a big file with many include and putting the overload definition in front of all the code that use the overloaded operator solve the problem ( had the same problem 2 or 3 months ago)

now let see what happens with the modules , it is not win, because if i have module that refer to module,i have an infix parser that usually is required before the user definitions of overload some operators but modules are set in top of file in racket and if infix parser do not have the new version of + it will not work at all on any + operation, not only with vectors but even with number as + is now defined later

but i think solution is already written in my code , as in Guile,i first define that a procedure will be overloaded and next i specialized it where i want in code:

(define-overload-existing-operator +)

;; far away in the code below:

(display +)
(overload + add-list-list (list? list?))
(display +)


#<procedure:+>#<procedure:+>

now will see if the infix with precedence code is still working on overloaded operators....

note that in the above example the #procedure:+ after overload is displayed the same: #procedure:+ but it is another +

i can not find a way to modify a variable of another module,even creating accessor! does not work , i tried to do it as documented:
https://docs.racket-lang.org/guide/module-set.html

(define-namespace-anchor ankh)
(define bsns (namespace-anchor->namespace ankh))
(current-namespace bsns)






;; a list of lists of operators. lists are evaluated in order, so this also
;; determines operator precedence
;;  added bitwise operator with the associated precedences and modulo too
(define infix-operators-lst
  
  ;;'()
  
  (list
   
   (list expt **)
   (list * / %)
   (list + -)
   
   (list << >>)

   (list & ∣ )

  					; now this is interesting: because scheme is dynamically typed, we aren't
  					; limited to any one type of function
   
   (list < > = <> ≠ <= >=)
    
   ;;(list 'dummy) ;; can keep the good order in case of non left-right assocciative operators.(odd? reverse them) 
   
   )

  )


(define (set-infix-operators! updated-infix-operators)
  (set! infix-operators-lst updated-infix-operators))



;; this function teach the overloaded operators to scheme infix procedures
(define-syntax update-operators

  (syntax-rules ()

    ((_)
  
     (set-infix-operators! (list
   
			    (list expt **)
			    (list * / %)
			    (list + -)
			    
			    (list << >>)
			    
			    (list & ∣ )
			    
					; now this is interesting: because scheme is dynamically typed, we aren't
					; limited to any one type of function
			    
			    (list < > = <> ≠ <= >=)
			    
			    ;;(list 'dummy) ;; can keep the good order in case of non left-right assocciative operators.(odd? reverse them) 
			    
			    )
			   
			   )
     )))



but i must include the above definition in my main file

#lang reader "../Scheme-PLUS-for-Racket/main/Scheme-PLUS-for-Racket/SRFI/SRFI-105.rkt"


(provide (all-defined-out)) ;; export all bindings



(require "../Scheme-PLUS-for-Racket/main/Scheme-PLUS-for-Racket/Scheme+.rkt")

(require "racket/logiki+.rkt")

(require "racket/operation+.rkt")

(require "racket/subscript+.rkt")


;; now required from Scheme+
;;(require "../Scheme-PLUS-for-Racket/main/Scheme-PLUS-for-Racket/required-files/scheme-infix.rkt")



;; overload tests



(display "before add-list-list") (newline)
(define (add-list-list v1 v2) (map + v1 v2))
(display "before overload") (newline)

(define-overload-existing-operator +)
(define-overload-existing-operator *)

(include "../Scheme-PLUS-for-Racket/main/Scheme-PLUS-for-Racket/required-files/scheme-infix.rkt")

perheaps the (define-namespace-anchor ankh) is not at the good place and should be in the module at the upper level to make all variable accessible from all the files/modules....