Evaluating file at runtime in Racket

This is originally a Stack Overflow post however issue A in the comment of the answer still persists. Thanks for any help in advance!

=====Copy & Paste of the Stack Overflow Question=====

I am making an application using Racket in which Racket is also used as a scripting language. I want users to write scripts utilizing some structs and procedures provided in my executable.

For example I have userruntime.rkt:

(struct result (x y z))
(provide (all-from-out racket/base))
(provide (struct-out result))

And user writes script.rkt:

(define (my-even? x)
  (if (eq? x 0) #t
                (not (my-odd? (sub1 x)))))

(define (my-odd? x)
  (not (my-even? (sub1 x))))

(result (my-odd? 1) (my-odd? 2) (my-odd? 3))

I want to evaluate to the following result (you get the idea):

'(#<void> #<void> (result #t #f #t))

It seems that make-module-evaluator in racket/sandbox satisfies my needs. However I failed to find a way to pass the module (as a file compiled and linked in the final executable). The official documentation gives the following example:

(define base-module-eval
    (make-evaluator 'racket/base '(define (f) later)
                                 '(define later 5)))

Which is not requiring a file. When I try:

(make-module-evaluator "userruntime.rkt")  ; make-module-evaluator: expecting a `module' program; got userruntime.rkt [,bt for context]
;; or
(make-module-evaluator 'userruntime)  ; make-module-evaluator: expecting a `module' program; got userruntime[,bt for context]

How do I refer to the module in the file correctly?

If I understand you correctly, you would like three modules:

  1. support.rkt to define the result struct once and for all
  2. (possibly many) client.rkt modules, which are not supposed to (require “support.rkt”) [for reasons to be clarified]
  3. combine.rkt to link client.rkt with support.rkt retroactively.

Is that the case? If so, why can’t client.rkt not require the support file?

1 Like

@EmEf Yes exactly. To be more specific, I want to treat userruntime.rkt or support.rkt as a module language. I also hope to rename and re-export some racket symbols (for example, list to r:list), thus make client.rkt some sort of DSL based on Racket.

Also to clarify, the StackOverflow answer works but only works when code is loaded dynamically. However, I hope to embed userruntime.rkt to the binary distribution.