This is a problem I have with my minikanren implementation, it's split into a lot of files and I want to swap out the implementation of substitutions. Here is a cut down explanation of the problem:
I have a module peano
which I implement another module four
using.
;; peano.sld
(define-library (peano)
(import (scheme base))
(export one add)
(begin
(define one `(s z))
(define (add p q)
(if (eq? 'z p)
q
`(s ,(add (cadr p) q))))
))
;; four.scm
(define four
(let ((two (add one one)))
(add two two)))
Someone comes along with a more efficient data structure or something called numeral
and I want to try swapping peano out for it.
;; numeral.scm
(define-library (numeral)
(import (scheme base))
(export one add)
(begin
(define one 1)
(define (add p q) (+ p q))
))
I can share the implementation of four
using two different .sdl files which both include it:
;; four-peano.sld
(define-library (four-numeral)
(import (scheme base)
(numeral))
(export four)
(include "four.scm"))
;; four-numeral.sld
(define-library (four-numeral)
(import (scheme base)
(numeral))
(export four)
(include "four.scm"))
and this works nicely
sash> (import (four-peano))
#<unspecified>
sash> four
(s (s (s (s z))))
sash> (import (four-numeral))
#<unspecified>
sash> four
4
If my program has a dependency tree like this:
A <= B <= PEANO <= FOUR <= X <= Y <= Z
then I have to have .sld files for each of these:
A <= B <= PEANO <= FOUR-P <= X-P <= Y-P <= Z-P
<= NUMERAL <= FOUR-N <= X-N <= Y-N <= Y-N
This is too much code duplication, if you had this happen to another module you'd be dealing with 4x as many SLDs.
I suggest define
add
andone
as modifiable (parameterizable) object.You can choose effect by what you import.