moduleracketrequire

Is there a way to require a module and change the name of some its bindings?


I need to test different implementations of the same function from one single unit test file, with different files holding different implementations.

The problem is that with normal requires, everything is imported without a name space, so functions with the same name cannot co-exist.

Is there a way to bind imported modules to a name space? Or to rename the elements of an imported module?

Something like

; All files contain a function named "fun" that needs to be tested.
(require 
  (rename "implementation-one.rkt" fun fun-one) 
  (rename "implementation-two.rkt" fun fun-two)
  (rename "implementation-three.rkt" fun fun-three))

(check-equal? (fun-one 0) 0 "first implementation")
(check-equal? (fun-two 0) 0 "second implementation")
(check-equal? (fun-three 0) 0 "third implementation")

Here I'm importing the fun function from each implementation file, and renaming it so something else. This is not valid Racket though.

I looked into modules, but it seems that the same problem happens; when requiring a module everything inside is exposed without a name space.

Is there a way to specify the name of an imported module, or change the names of the contents of the module? Perhaps by renaming the module's bindings, or by encapsulating imports in a name space, or some sort of named import? How are name conflicts like this normally resolved in Racket?

Should modules contain structs and/or objects that encapsulate each implementation? Or is there a way to do it with simple modules that provide functions?


Solution

  • (require 
      (rename-in "implementation-one.rkt" [fun fun-one]) 
      (rename-in "implementation-two.rkt" [fun fun-two])
      (rename-in "implementation-three.rkt" [fun fun-three]))
    

    See the manual for require.