Question

Let's say I have the following two files:

;; demo.scm
(define-module (demo)
  #:export (f))

(define (g x) 1)
(define (f x) (g x))

... and in the same directory:

;; use-demo.scm
(add-to-load-path ".")
(use-modules (demo))

(define (g x) (+ x 1))
(display (f 5))
(newline)

Running use-demo.scm in Guile (2), I get the output 1. So it looks like the function f has 'closed over' the function g that's defined in module demo. Is there any way to get around this? I really want to use the version of g that I've redefined in use-demo.scm.

Was it helpful?

Solution

OK, just for the record, I did some research and am posting the solution to this specific problem in case it helps someone.

The trick is to not redefine g locally, but rather to 'inject' the new function into the demo module's mapping of names to values.

(add-to-load-path ".")
(use-modules (demo))

(module-define! (resolve-module '(demo)) 'g
  (lambda (x) (+ x 1)))

(display (f 5))
(newline)

OTHER TIPS

If you have specific functions that you'd like to be able to override, you could make them configurable using parameters. This has some advantages:

  1. You don't need to call reload-module to put the module back in its original configuration.
  2. The changes only apply for the scope of the code which needs the modified behaviour.
  3. It works properly when using multiple threads.

Obviously, the main disadvantage is that you need to add some boilerplate for each function that you want to allow to be overridden (although that's what hygienic macros are for, hehe).

The following code may work. I haven't run it.

;; demo.scm

(define-module (demo)
  #:export (f))

(define (default-g x) 1)
(define p (make-parameter default-g))
(define (f x) ((p) x))


;; use-demo.scm
(add-to-load-path ".")
(use-modules (demo))

(define (my-g x) (+ x 1))
(parameterize ((@@ (demo) p) my-g)
  (display (f 5))
  (newline))

Obviously, if you can provide some additional information about what the application for this capability is, I might be able to suggest alternative approaches (there are a few others).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top