Do I understand correctly that this is your setup? You have two files: main.rkt
and racket/if.rkt
.
;; main.rkt
#lang racket
(provide (all-defined-out)) ;; export all bindings
(require srfi/43) ;; vector library
(include "racket/if.rkt")
;; racket/if.rkt
(require (rename-in racket/base [if if-backup]))
(define-syntax if
(syntax-rules ()
((_ tst ev) (if-backup tst ev '()))
((_ tst ev-then ev-else) (if-backup tst ev-then ev-else))))
And when you run main.rkt
, you get the following error:
racket/if.rkt:1:20: module: identifier already required
also provided by: srfi/43 in: vector-copy!
So what’s going on here? Well, include
essentially copies and pastes the code from racket/if.rkt
into where it is included. So your main.rkt
is effectively:
#lang racket
(provide (all-defined-out)) ;; export all bindings
(require srfi/43) ;; vector library
(require (rename-in racket/base [if if-backup]))
(define-syntax if
(syntax-rules ()
((_ tst ev) (if-backup tst ev '()))
((_ tst ev-then ev-else) (if-backup tst ev-then ev-else))))
which also fails with the same error.
The issue is that both srfi/53
and racket/base
provide vector-copy!
, so there’s a conflict. Racket doesn't know which is the one that you want.
One possible solution is to replace rename-in
to only-in
in racket/if.rkt
. (rename-in racket/base [if if-backup])
requires everything in racket/base
, but changes the name of if
to if-backup
. In contrast, (only-in racket/base [if if-backup])
requires only if
, and changes the name of if
to if-backup
.
With only-in
, your program runs with no problem, since there is no conflict anymore.
But this also demonstrates why include
is not widely used in Racket. It makes reasoning with code difficult. Unless you have a good reason to use include
, I would encourage you to use the if-module.rkt
version instead.