# Eval in a function

**URL:** <https://racket.discourse.group/t/eval-in-a-function/1896>\
**Category:** General\
**Created:** [April 27, 2023, 2:22pm UTC](https://racket.discourse.group/t/eval-in-a-function/1896 "2023-04-27T14:22:02Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![damien\_mattei](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/damien_mattei/32/2706_2.png) [@damien\_mattei](https://racket.discourse.group/u/damien_mattei)\
**Post date:** [April 27, 2023, 2:22pm UTC](https://racket.discourse.group/t/eval-in-a-function/1896/1 "2023-04-27T14:22:02Z")

</div>

hello,

how can i make this eval working as in toplevel:

```scheme
#lang racket
(define (foo)
  (define x 7)
  (eval (quote x)))

```

Welcome to DrRacket, version 8.7 [cs].  
Language: racket, with debugging; memory limit: 8192 MB.

> (foo)  
> . . x: undefined;  
> cannot reference an identifier before its definition  
> (define x 7)  
> (eval (quote x))  
> 7

---

<div class="post-metadata">

**Author:** ![soegaard](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/soegaard/32/19_2.png) [@soegaard](https://racket.discourse.group/u/soegaard)\
**Post date:** [April 27, 2023, 2:25pm UTC](https://racket.discourse.group/t/eval-in-a-function/1896/2 "2023-04-27T14:25:25Z")

</div>

Like this:

```scheme
(define ns (make-base-namespace))
(define (foo)
  (displayln (eval '(define x 7) ns))
  (displayln (eval 'x ns)))
(foo)

```

Note that you need to evaluate `(define x 7)`.  
There is by design no way to access local variables via `eval`.

---

<div class="post-metadata">

**Author:** ![damien\_mattei](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/damien_mattei/32/2706_2.png) [@damien\_mattei](https://racket.discourse.group/u/damien_mattei)\
**Post date:** [April 27, 2023, 4:00pm UTC](https://racket.discourse.group/t/eval-in-a-function/1896/3 "2023-04-27T16:00:58Z")

</div>

too bad... i'm writing an infix evaluator with precedence and i need to use the already defined variable at any level,for example in a function or a macro.

---

<div class="post-metadata">

**Author:** ![shhyou](https://avatars.discourse-cdn.com/v4/letter/s/ccd318/32.png) [@shhyou](https://racket.discourse.group/u/shhyou)\
**Post date:** [April 27, 2023, 6:32pm UTC](https://racket.discourse.group/t/eval-in-a-function/1896/4 "2023-04-27T18:32:33Z")

</div>

Don't quote anything; don't use eval.

Use syntax objects (`syntax->list` and `#‵(...)`) and keep the identifiers so the scopes are intact. To see if two identifiers are "the same", like comparing `+`, `*`, etc., use `free-identifier=?`.

---

<div class="post-metadata">

**Author:** ![damien\_mattei](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/damien_mattei/32/2706_2.png) [@damien\_mattei](https://racket.discourse.group/u/damien_mattei)\
**Post date:** [April 27, 2023, 7:51pm UTC](https://racket.discourse.group/t/eval-in-a-function/1896/5 "2023-04-27T19:51:01Z")

</div>

yes i have other versions with limited features that do not use quote and eval.

"syntax object" : i do not want to dive into that , i'm so ignorant about that i would have for weeks, not portable too

---

<div class="post-metadata">

**Author:** ![shhyou](https://avatars.discourse-cdn.com/v4/letter/s/ccd318/32.png) [@shhyou](https://racket.discourse.group/u/shhyou)\
**Post date:** [April 28, 2023, 8:50pm UTC](https://racket.discourse.group/t/eval-in-a-function/1896/6 "2023-04-28T20:50:39Z")

</div>

Just pattern-based macros that recognize outermost operators should work too like this example. Afterwards, replace `printf-reverse` by calls to some infix-to-postfix conversion algorithm and use the `op` struct to identify operators.

```plaintext
#lang racket/base

(struct op (sym) #:transparent)

(define-syntax mark-$-ops
  (syntax-rules (+ - * /)
    [(_ () (e-acc ...))
     (list e-acc ...)]
    [(_ (+ e ...) expr-acc) (mark-$-ops (e ...) ((op '+) . expr-acc))]
    [(_ (- e ...) expr-acc) (mark-$-ops (e ...) ((op '-) . expr-acc))]
    [(_ (* e ...) expr-acc) (mark-$-ops (e ...) ((op '*) . expr-acc))]
    [(_ (/ e ...) expr-acc) (mark-$-ops (e ...) ((op '/) . expr-acc))]
    [(_ (expr0 e ...) expr-acc) (mark-$-ops (e ...) (expr0 . expr-acc))]))

(define-syntax $
  (syntax-rules ()
    [(_ e ...)
     (printf "TODO: parse and convert to postfix\n~a\n"
             (reverse (mark-$-ops (e ...) ())))]))

(define y 456)

(define (compute x)
  (let ([z 7])
    ($ x + 3 * y + z / 2)))

(compute 9)

```

Here is the result of macro expansion displayed in the macro stepper:

 ![step-dollar](https://global.discourse-cdn.com/free1/uploads/racket/original/2X/f/f412c79a30b063cc5566df6f600044922cc19bf4.jpeg)

---

<div class="post-metadata">

**Author:** ![damien\_mattei](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/damien_mattei/32/2706_2.png) [@damien\_mattei](https://racket.discourse.group/u/damien_mattei)\
**Post date:** [April 29, 2023, 9:27am UTC](https://racket.discourse.group/t/eval-in-a-function/1896/7 "2023-04-29T09:27:20Z")

</div>

yes pattern based is a way i think ,i suppose it can solve the overloaded operator problem ,but notice that when dealing operator one by one in the pattern , a user can have defined a new operator not in the pattern cases ,but perheaps i did not well understood your code if expr0 deal with specific user defined operator...

note about overload operator problem: it is the fact that when you want to compare the operator to find precedence rules you must compare quoted operators or symbols ,if you use procedure comparaison the \<procedure +\> could be different from \<new procedure + overloaded\> a way i find to solve the operator overloaded problem is quote all operators and evaluate them later (works in Guile) or rebuild a precedence list of operator each time i call the infix with precedence evaluation. Then in the precedence list :

```scheme
(define infix-operators
  
  (list
   
   (list expt **)
   (list * / %)
   (list + -)
   
   (list << >>)

   (list & ∣ )

   (list < > = <> ≠ <= >=)
   
   
   ;;(list 'dummy) ;; can keep the good order in case of non left-right assocciative operators.(odd? reverse them) 
   
   
   )
  )

```

the operators are up to date with the last definitions known. (note that in the previous list operators are NOT quoted)

and this solution is only working if i have my scheme-infix.rkt module included , it is not working if required in a module because the data are then encapsulated in the module and again i have to test that in real code,not only in simple examples sometimes only made at REPL, anyway a good solution seems to make all the overload before the scheme-infix.rkt is read,so the code included (not required) know all the procedures bind to operators symbols.

---

<div class="post-metadata">

**Author:** ![shhyou](https://avatars.discourse-cdn.com/v4/letter/s/ccd318/32.png) [@shhyou](https://racket.discourse.group/u/shhyou)\
**Post date:** [April 29, 2023, 10:22pm UTC](https://racket.discourse.group/t/eval-in-a-function/1896/8 "2023-04-29T22:22:05Z")

</div>

The code as written only recognizes the bindings of `+`, `-`, `*` and `/` at the outermost level. Of course, if you don't want to recognize operators by bindings, it is possible to compare operators by symbols.

However, The **name** of the set of operators that `$` recognizes could be configurable **at expansion time** or in user-provided code, but must be fixed before the code starts running and especially must be determined before any uses of the `$` macro. At runtime, of course, you can provide a different interpretation of the names. A possible way is to have the configuration written in a separate module.

Unless you are using **the top level** i.e. the REPL, Racket won't let you redefine bindings. Note that the expansion time and the run time are separated, so it is important to add new operators to both expansion and run time. The macro `add-new-operator` implements one possible idea:

In a file `ops.rkt`:

```plaintext
#lang racket/base

(provide op-map)

(define op-map
  (make-hash
   (list (cons 'expt expt)
         (cons '* *)
         (cons '/ /)
         (cons '+ +)
         (cons '- -)
         (cons '= =))))

```

In the macro definition file, `dollar.rkt`:

```plaintext
#lang racket/base

(provide $ add-new-operator)

(struct op (sym) #:transparent)

(require (for-syntax racket/base "ops.rkt"))
(define-syntax (mark-$-ops stx)
  (syntax-case stx ()
    [(_ () (e-acc ...))
     #'(list e-acc ...)]
    [(_ (rator e ...) expr-acc)
     (and (identifier? #'rator) (hash-has-key? op-map (syntax-e #'rator)))
     #'(mark-$-ops (e ...) ((op 'rator) . expr-acc))]
    [(_ (expr0 e ...) expr-acc)
     #'(mark-$-ops (e ...) (expr0 . expr-acc))]))

(define-syntax $
  (syntax-rules ()
    [(_ e ...)
     (interp (reverse (mark-$-ops (e ...) ())))]))

(require "ops.rkt")
(define (interp expr)
  (printf "expr = ~s\n" expr)
  (for ([e (in-list expr)])
    (when (op? e)
      (printf "op ~s maps to: ~s\n" e (hash-ref op-map (op-sym e))))))

(define-syntax (add-new-operator stx)
  (syntax-case stx ()
    [(_ new-op)
     (let ()
       (hash-set! op-map (syntax-e #'new-op) #f)
       #'(hash-set! op-map 'new-op new-op))]))

```

Here is an example use that interprets `=` as `eqv?` and adds `quotient` to the list of operators:

```plaintext
#lang racket/base

(require "dollar.rkt" "ops.rkt")
(hash-set! op-map '= eqv?)

(define y 456)

(add-new-operator quotient)
(define (compute x)
  (let ([z 7])
    ($ x + 3 * y = quotient z 2)))

(compute 9)

```

---

<div class="post-metadata">

**Author:** ![damien\_mattei](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/damien_mattei/32/2706_2.png) [@damien\_mattei](https://racket.discourse.group/u/damien_mattei)\
**Post date:** [May 1, 2023, 12:56pm UTC](https://racket.discourse.group/t/eval-in-a-function/1896/9 "2023-05-01T12:56:52Z")

</div>

i agree with you , my solution works only at REPL in Racket, but is ok in Guile at REPL and toplevel (not in procedure of course)

i'm searching a solution, first understand what is the difference between Guile and Racket modules? ...

---

<div class="post-metadata">

**Author:** ![damien\_mattei](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/damien_mattei/32/2706_2.png) [@damien\_mattei](https://racket.discourse.group/u/damien_mattei)\
**Post date:** [May 1, 2023, 1:12pm UTC](https://racket.discourse.group/t/eval-in-a-function/1896/10 "2023-05-01T13:12:02Z")

</div>

i isolated the problem (because as i use a SRFI-105 REPL parser and modules) if you could have a look at.

Again this works in Guile , not Racket:

file test-racket.rkt:

```scheme
#lang racket

(include "overload.scm")

(display "before plus") (newline)
+

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

(overload + add-vect-vect (list? list?) 'operator)

```

my overload.scm file that works well in Guile REPL and top-level files but works only in Racket REPL:

```scheme
;; overload
;; use with Scheme+:

;; scheme@(guile-user)> (use-modules (Scheme+))
;; scheme@(guile-user)> (define (add-vect-vect v1 v2) (map + v1 v2))
;; scheme@(guile-user)> (overload + add-vect-vect (list? list?) 'operator)
;; create-overloaded-operator : pred-list = (#<procedure list? (_)> #<procedure list? (_)>)
;; funct: #<procedure add-vect-vect (v1 v2)>
;; orig-funct: #<procedure + (#:optional _ _ . _)>
;; old-funct: #<procedure + (#:optional _ _ . _)>
;; new-funct: #<procedure new-funct args>
;; scheme@(guile-user)> (+ '(1 2 3) '(4 5 6) '(7 8 9))
;; new-funct: new-funct = #<procedure new-funct args>
;; new-funct : pred-list = (#<procedure list? (_)> #<procedure list? (_)>)
;; new-funct : args = ((1 2 3) (4 5 6) (7 8 9))
;; new-funct : nb-args = 3
;; (12 15 18)

(define-syntax overload

  (syntax-rules ()

    ;; arguments are symbol of 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) (overload-operator funct-symb proc (pred-arg1 ...)))))

;; (define (mult-num-vect k v) (map (λ (x) (* k x)) v))
  
;; (overload * mult-num-vect (number? list?) 'operator) 

;; (* 3 (+ '(1 2 3) '(4 5 6)))

;; (15 21 27)

;; (+ (* 3 '(1 2 3)) '(4 5 6))
;; (7 11 15)

;; {3 * '(1 2 3) + '(4 5 6)}
;; (7 11 15)

;; {3 * '(1 2 3) + '(4 5 6) + '(7 8 9)}
;; (14 19 24)

;; scheme@(guile-user)> {3 * '(1 2 3)}
;; $3 = (3 6 9)

;; scheme@(guile-user)> (define (add-vect v) v)
;; scheme@(guile-user)> (overload + add-vect (list?) 'operator)
;; scheme@(guile-user)> (+ '(1 2 3))
;; $7 = (1 2 3)

;; scheme@(guile-user)> (define (add-pair p1 p2) (cons (+ (car p1) (car p2)) (+ (cdr p1) (cdr p2))))
;; scheme@(guile-user)> (overload + add-pair pair? pair?)
;; overload
;; scheme@(guile-user)> (+ (cons 1 2) (cons 3 4))
(define-syntax overload-procedure
  
  (syntax-rules ()

    ((_ orig-funct funct (pred-arg1 ...)) 
     (define orig-funct (create-overloaded-procedure orig-funct funct (list pred-arg1 ...))))))

      ;;'(define orig-funct (create-overloaded-procedure-macro orig-funct funct (list pred-arg1 ...))))))

(define-syntax overload-operator
  
  (syntax-rules ()

    ((_ orig-funct funct (pred-arg1 ...))
     (define orig-funct (create-overloaded-operator orig-funct funct (list pred-arg1 ...))))))
 
     ;;(define orig-funct (create-overloaded-operator-macro orig-funct funct (list pred-arg1 ...))))))

(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
	;;(every (λ (p) ((car p) (cdr p)))
		pred-arg-list))
      #f))

;; (define (add-list-list L1 L2) (map + L1 L2))
;; (define + (overload-proc + add-list-list (list list? list?)))
;; (+ '(1 2 3) '(4 5 6))
;; (define (add-pair p1 p2) (cons (+ (car p1) (car p2)) (+ (cdr p1) (cdr p2))))
;; (define + (overload-proc + add-pair (list pair? pair?)))
;; (+ (cons 1 2) (cons 3 4))

;; when a function that overload an operator has more than 2 args (f a1 a2 a3 ...) and only (f a1 a2) is defined
;; we do: (f a1 (f a2 a3 ...)) for operators like: + - * / ^ and other if any... we detect those operators to separate distinct case from simple functions.
;; note: this could not be done recursively in the general case, we need an hash table
(define (create-overloaded-procedure orig-funct funct pred-list)

  (display "create-overloaded-procedure")
  (display " : pred-list = ") (display pred-list) (newline)
  (define old-funct orig-funct)
  (define new-funct (lambda args ;; args is the list of arguments
		      (display "new-funct: ") (display new-funct) (newline)
		      (display "new-funct : pred-list = ") (display pred-list) (newline)
		      (display "new-funct : args = ") (display args) (newline)
		      (if (check-arguments pred-list args)
			  (begin
			    (display "new funct :calling:") (display funct) (newline)
			    (apply funct args))
			  (begin
			    (display "new funct :calling:") (display old-funct) (newline)
			    (apply old-funct args)))))
				    
  (display "funct: ") (display funct) (newline)
  (display "orig-funct: ") (display orig-funct) (newline)
  (display "old-funct: ") (display old-funct) (newline)
  (display "new-funct: ") (display new-funct) (newline)

  new-funct)

;; scheme@(guile-user)> (use-modules (overload))
;; ;;; note: source file /usr/local/share/guile/site/3.0/overload.scm
;; ;;; newer than compiled /Users/mattei/.cache/guile/ccache/3.0-LE-8-4.6/usr/local/share/guile/site/3.0/overload.scm.go
;; ;;; note: auto-compilation is enabled, set GUILE_AUTO_COMPILE=0
;; ;;; or pass the --no-auto-compile argument to disable.
;; ;;; compiling /usr/local/share/guile/site/3.0/overload.scm
;; ;;; compiled /Users/mattei/.cache/guile/ccache/3.0-LE-8-4.6/usr/local/share/guile/site/3.0/overload.scm.go
;; scheme@(guile-user)> (define (add-vect-vect v1 v2) (map + v1 v2))
;; scheme@(guile-user)> (overload + add-vect-vect (list? list?) 'operator)
;; create-overloaded-operator : pred-list = (#<procedure list? (_)> #<procedure list? (_)>)
;; funct: #<procedure add-vect-vect (v1 v2)>
;; orig-funct: #<procedure + (#:optional _ _ . _)>
;; old-funct: #<procedure + (#:optional _ _ . _)>
;; new-funct: #<procedure new-funct args>
;; scheme@(guile-user)> (+ '(1 2 3) '(4 5 6))
;; new-funct: #<procedure new-funct args>
;; new-funct : pred-list = (#<procedure list? (_)> #<procedure list? (_)>)
;; new-funct : args = ((1 2 3) (4 5 6))
;; new funct :calling:#<procedure add-vect-vect (v1 v2)>
;; $1 = (5 7 9)
;; scheme@(guile-user)> (+ 2 3)
;; new-funct: #<procedure new-funct args>
;; new-funct : pred-list = (#<procedure list? (_)> #<procedure list? (_)>)
;; new-funct : args = (2 3)
;; new funct :calling:#<procedure + (#:optional _ _ . _)>
;; $2 = 5
;; scheme@(guile-user)> (+ '(1 2 3) '(4 5 6) '(7 8 9))
;; new-funct: #<procedure new-funct args>
;; new-funct : pred-list = (#<procedure list? (_)> #<procedure list? (_)>)
;; new-funct : args = ((1 2 3) (4 5 6) (7 8 9))
;; $3 = (12 15 18)

;; scheme@(guile-user)> {'(1 2 3) + '(4 5 6) + '(7 8 9)}
;; new-funct: new-funct = #<procedure new-funct args>
;; new-funct : pred-list = (#<procedure list? (_)> #<procedure list? (_)>)
;; new-funct : args = ((1 2 3) (4 5 6) (7 8 9))
;; new-funct : nb-args = 3
;; (12 15 18)

(define (create-overloaded-operator orig-funct funct pred-list) ;; works for associative operators

  (display "create-overloaded-operator")
  (display " : pred-list = ") (display pred-list) (newline)
  (define old-funct orig-funct)
  (define new-funct (lambda args ;; args is the list of arguments
		      (display "new-funct: new-funct = ") (display new-funct) (newline)
		      (display "new-funct : pred-list = ") (display pred-list) (newline)
		      (display "new-funct : args = ") (display args) (newline)
		      (define nb-args (length args))
		      (display "new-funct : nb-args = ") (display nb-args) (newline)
		      (cond ((check-arguments pred-list args) (begin
								(display "new funct :calling:") (display funct) (newline)
								(apply funct args)))
			    ((> nb-args 2) (new-funct (car args) (apply new-funct (cdr args)))) ;; op(a,b,...) = op(a,op(b,...))
			    (else
			     (begin
			       (display "new funct :calling: ") (display old-funct) (newline)
			       (apply old-funct args))))))
				    
  (display "funct: ") (display funct) (newline)
  (display "orig-funct: ") (display orig-funct) (newline)
  (display "old-funct: ") (display old-funct) (newline)
  (display "new-funct: ") (display new-funct) (newline)

  new-funct)

(define-syntax create-overloaded-operator-macro

  (syntax-rules ()

     ((_ orig-funct funct pred-list) ;; works for associative operators

      (begin ;; will cause Error with define not allowed in this expression context !!!
	(display "create-overloaded-operator")
	(display " : pred-list = ") (display pred-list) (newline)
	(define old-funct orig-funct)
	(define new-funct (lambda args ;; args is the list of arguments
			    (display "new-funct: new-funct = ") (display new-funct) (newline)
			    (display "new-funct : pred-list = ") (display pred-list) (newline)
			    (display "new-funct : args = ") (display args) (newline)
			    (define nb-args (length args))
			    (display "new-funct : nb-args = ") (display nb-args) (newline)
			    (cond ((check-arguments pred-list args) (begin
								      (display "new funct :calling:") (display funct) (newline)
								      (apply funct args)))
				  ((> nb-args 2) (new-funct (car args) (apply new-funct (cdr args)))) ;; op(a,b,...) = op(a,op(b,...))
				  (else
				   (begin
				     (display "new funct :calling: ") (display old-funct) (newline)
				     (apply old-funct args))))))
	
	(display "funct: ") (display funct) (newline)
	(display "orig-funct: ") (display orig-funct) (newline)
	(display "old-funct: ") (display old-funct) (newline)
	(display "new-funct: ") (display new-funct) (newline)
	
	new-funct))))

;; (overload-function (+ (L1 list?) (L2 list?)) (map + L1 L2)) ;; bad example ,it is not a function but an operator!
(define-syntax overload-function
  
  (syntax-rules ()

    ((_ (orig-funct (arg1 pred-arg1) ...) expr ...) (overload orig-funct (lambda (arg1 ...) expr ...) (pred-arg1 ...)))))

```

the error is caused by the overload, after that + is unknow!!!??? i do not understand (again works with guile and the same macros)

```scheme
Welcome to DrRacket, version 8.7 [cs].
Language: racket, with debugging; memory limit: 8192 MB.
before plus
. . +: undefined;
 cannot reference an identifier before its definition

```

note: i admit i have warning in guile i never have: " warning: non-idempotent binding for `+'. When first loaded, value for `+` comes from imported binding, but later module-local definition overrides it; any module reload would capture module-local binding rather than import." I suppose Racket is more strict.

---

<div class="post-metadata">

**Author:** ![shhyou](https://avatars.discourse-cdn.com/v4/letter/s/ccd318/32.png) [@shhyou](https://racket.discourse.group/u/shhyou)\
**Post date:** [May 1, 2023, 4:43pm UTC](https://racket.discourse.group/t/eval-in-a-function/1896/11 "2023-05-01T16:43:09Z")

</div>

**At run time** , the expressions are evaluated from top to bottom and from left to right. However, the bindings are determined **at expansion time** and have nothing to do with run time.

For modules, the bindings are mutually recursive. This is what the code looks like after expansion (check the macro stepper):

```plaintext
   #lang racket
   (display "before plus")
   (newline)
   +
   (display "before add-vect-vect")
   (newline)
   (define (add-vect-vect v1 v2) (map + v1 v2))
   (display "before overload")
   (newline)
   (define +
     (create-overloaded-operator
      +
      add-vect-vect
      (list list? list?)))))

```

Because module-level bindings are mutually recursive, the `+` in line 4 refers to the `+` define at the end of the code. Therefore, **at run time** line 4 of the code tries to use the value of `+` that has not been evaluated yet, leading to the error you see. This is the same class of runtime errors as this piece of code:

```plaintext
#lang racket
(+ x y) ;; <- x and y has not been evaluated yet
(define x 5)
(define y 8)

```

---

<div class="post-metadata">

**Author:** ![damien\_mattei](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/damien_mattei/32/2706_2.png) [@damien\_mattei](https://racket.discourse.group/u/damien_mattei)\
**Post date:** [May 1, 2023, 4:45pm UTC](https://racket.discourse.group/t/eval-in-a-function/1896/12 "2023-05-01T16:45:06Z")

</div>

my problem is this code works in Guile , in a file:

```scheme
(define (foo p) p)

(define + (foo +))

```

but not in a Racket file:

+: undefined;  
cannot reference an identifier before its definition

any idea to force the Guile behavior?

---

<div class="post-metadata">

**Author:** ![shhyou](https://avatars.discourse-cdn.com/v4/letter/s/ccd318/32.png) [@shhyou](https://racket.discourse.group/u/shhyou)\
**Post date:** [May 1, 2023, 5:13pm UTC](https://racket.discourse.group/t/eval-in-a-function/1896/13 "2023-05-01T17:13:12Z")

</div>

Sol 1: Use `#lang racket/load` to use the REPL language.

Sol 2: Use

```scheme
(require (prefix-in r: racket/base))
(define (foo p) p)
(define + (foo r:+))

```

What you are asking is precisely the behavior of the REPL, contradicting to the semantics of modules.

---

<div class="post-metadata">

**Author:** ![damien\_mattei](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/damien_mattei/32/2706_2.png) [@damien\_mattei](https://racket.discourse.group/u/damien_mattei)\
**Post date:** [May 1, 2023, 5:35pm UTC](https://racket.discourse.group/t/eval-in-a-function/1896/14 "2023-05-01T17:35:51Z")

</div>

yes i had noticed about the top to bottom evaluation and moved the code to the good place (seems i had not this problem in Guile?) and try the  
#lang racket/load it works but i cannot use it with my  
#lang reader "SRFI-105.rkt"  
if i put #lang racket/load replacing #lang racket it does not work with the srfi 105 code reader and parser.

i got this error:

Welcome to DrRacket, version 8.7 [cs].  
Language: reader "SRFI-105.rkt", with debugging; memory limit: 8192 MB.  
. . ../../../../../../../../Applications/Racket v8.7/collects/compiler/private/cm-minimal.rkt:741:23: standard-module-name-resolver: collection not found  
for module path: racket/lang/lang/reader  
collection: "racket/lang/lang"  
in collection directories:  
/Users/mattei/Library/Racket/8.7/collects  
/Applications/Racket v8.7/collects/  
... [170 additional linked and package directories]  
no package suggestions are available .

Interactions disabled.

my SRFI-105.rkt begin like this:

```scheme

#lang racket/lang ;; use to be racket
(compile-enforce-module-constants #f)
(require syntax/strip-context)

(provide (rename-out [literal-read read]
                     [literal-read-syntax read-syntax]))

(define (literal-read in)
  (syntax->datum
   (literal-read-syntax #f in)))
 
(define (literal-read-syntax src in)
  
  (define lst-code (process-input-code-tail-rec in))

  (strip-context `(module anything racket ,@lst-code)))
 

;; read all the expression of program
 
...

```

---

<div class="post-metadata">

**Author:** ![shhyou](https://avatars.discourse-cdn.com/v4/letter/s/ccd318/32.png) [@shhyou](https://racket.discourse.group/u/shhyou)\
**Post date:** [May 1, 2023, 7:09pm UTC](https://racket.discourse.group/t/eval-in-a-function/1896/15 "2023-05-01T19:09:45Z")

</div>

Try something like

```scheme
;; custom reader
#lang racket

(require syntax/strip-context)

(provide (rename-out [literal-read read]
                     [literal-read-syntax read-syntax]))

(define (literal-read in)
  (syntax->datum
   (literal-read-syntax #f in)))
 
(define (literal-read-syntax src in)
  
  (define lst-code (process-input-code-tail-rec in))

  (strip-context `(module anything racket/load (compile-enforce-module-constants #f) ,@lst-code)))

```

---

<div class="post-metadata">

**Author:** ![damien\_mattei](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/damien_mattei/32/2706_2.png) [@damien\_mattei](https://racket.discourse.group/u/damien_mattei)\
**Post date:** [May 1, 2023, 8:47pm UTC](https://racket.discourse.group/t/eval-in-a-function/1896/16 "2023-05-01T20:47:02Z")

</div>

yes it worked but now the 'require' is forbidden and with SRFI-105 this is a problem because the reader infix does not include and parse recursively the files, for this reason i used require with a #lang reader "SRFI-105.rkt", this is hard to solve.

---

<div class="post-metadata">

**Author:** ![shhyou](https://avatars.discourse-cdn.com/v4/letter/s/ccd318/32.png) [@shhyou](https://racket.discourse.group/u/shhyou)\
**Post date:** [May 1, 2023, 9:28pm UTC](https://racket.discourse.group/t/eval-in-a-function/1896/17 "2023-05-01T21:28:13Z")

</div>

What does require forbidden or parse recursively means? The code I posted roughly works like this:

Some reader file, like `load-reader.rkt` -- for example, modifying the SRFI-105 reader, and the client code of this reader can use `require`

```plaintext
;; custom reader
#lang racket

(require syntax/strip-context)

(provide (rename-out [literal-read read]
                     [literal-read-syntax read-syntax]))

(define (literal-read in)
  (syntax->datum
   (literal-read-syntax #f in)))

(define (literal-read-syntax src in)
  (define lst-code (read-all-and-print in))
  (strip-context `(module anything racket/load (compile-enforce-module-constants #f) ,@lst-code)))

(define (read-all-and-print in)
  (define expr (read in))
  (if (eof-object? expr)
      '()
      (list* `(printf "Running ~s\n" ',expr)
             expr
             (read-all-and-print in))))

```

Some client code:

```plaintext
#lang reader "load-reader.rkt"

(displayln (+ 3 4))

(require racket/unsafe/ops)
(displayln unsafe-fx+)

```

---

<div class="post-metadata">

**Author:** ![soegaard](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/soegaard/32/19_2.png) [@soegaard](https://racket.discourse.group/u/soegaard)\
**Post date:** [May 2, 2023, 7:32am UTC](https://racket.discourse.group/t/eval-in-a-function/1896/18 "2023-05-02T07:32:48Z")

</div>

Have you experimented with `(compile-enforce-module-constants #f)` ?

> <https://stackoverflow.com/questions/38786405/allow-redefinition-of-initial-bindings-for-r5rs-without-using-drracket/38796720#38796720>

---

<div class="post-metadata">

**Author:** ![damien\_mattei](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/damien_mattei/32/2706_2.png) [@damien\_mattei](https://racket.discourse.group/u/damien_mattei)\
**Post date:** [May 2, 2023, 8:10am UTC](https://racket.discourse.group/t/eval-in-a-function/1896/19 "2023-05-02T08:10:31Z")

</div>

yes ,tried at many places, no effect.

---

<div class="post-metadata">

**Author:** ![sorawee](https://avatars.discourse-cdn.com/v4/letter/s/ea5d25/32.png) [@sorawee](https://racket.discourse.group/u/sorawee)\
**Post date:** [May 2, 2023, 8:42am UTC](https://racket.discourse.group/t/eval-in-a-function/1896/20 "2023-05-02T08:42:11Z")

</div>

I think it would be nice to take a step back and think about what you really want to do. Who will be the users of this library? How will the library be used? Do you intend that regular Racket programs are able to `require` your library, or is it in its own ecosystem entirely?

From a quick glance, it looks like you are circumventing the module system and hygienic macro system, and using reflection liberally. Those are things that regular Racket programs would not do, unless there is a really good justification. I wouldn’t be surprised if right now Racket programs can’t interop well with the library.

[Next page](https://racket.discourse.group/t/eval-in-a-function/1896.md?page=2)
