Identifier already required?

hello,

i have this strange message when trying to redefine a 'if like in the file below.

Welcome to DrRacket, version 8.6 [cs].
Language: reader "racket/SRFI-105.rkt", with debugging; memory limit: 14000 MB.
. racket/if.rkt:1:20: module: identifier already required
also provided by: "racket/logiki+.rkt" in: do

file 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))))

any idea because i really do not know what is the problem....

Regards,

Damien

Can you provide a minimal, runnable program that produces the issue?

hello,
thank for your help.

yes here it is :

#lang racket
(provide (all-defined-out)) ;; export all bindings
(require srfi/43) ;; vector library
(include "racket/if.rkt")

it display this error:
Welcome to DrRacket, version 8.6 [cs].
Language: racket, with debugging; memory limit: 14000 MB.
. racket/if.rkt:1:20: module: identifier already required
also provided by: srfi/43 in: vector-copy!

why also provided by srfi/43 ?
at the bottom of the Racket windows i have:
racket/if.rkt:1:20: module: identifier already required at: vector-copy! in: racket/base also provided by: srfi/43

but it works if i create a module if-module.rkt :

#lang racket
(provide if)
(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 load it this way:

#lang racket
(provide (all-defined-out)) ;; export all bindings
(require srfi/43) ;; vector library
(require "racket/if-module.rkt")

test:

Welcome to DrRacket, version 8.6 [cs].
Language: racket, with debugging; memory limit: 14000 MB.

(if #t 'good_vibes)
'good_vibes

Damien

note that i should i have written if with a 'when:

#lang racket

(provide if)

(require (rename-in racket/base [if if-backup]))

(define-syntax if
  (syntax-rules ()
    ((_ tst ev)  (when tst ev))
    ((_ tst ev-then ev-else)  (if-backup tst ev-then ev-else))))

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.

1 Like

thank you, and furthermore my Scheme+ module include a racket/base but there was no concern about it:

(module Scheme+ racket
	
	(module test racket/base) ;; dummy

	(provide def $bracket-apply$ <- ← -> → <+ ⥆ +> ⥅ declare $ & condx <> ≠ ** <v v> ⇜ ⇝)

	(require srfi/31) ;; for 'rec in def.scm

	(include "included-files/def.scm")
	(include "included-files/array.scm")

	(require "required-files/apply-square-brackets.rkt")
	(require "required-files/assignment.rkt")

	(include "included-files/declare.scm")
	(include "included-files/condx.scm")
	(include "included-files/block.scm")
	(include "included-files/not-equal.scm")
	(include "library/exponential.scm")

	) ;; end module

racket/base is only here to pass the tests of Package system of Racket but i do not how to replace it by something more clever in my next release 4.0 that is coming soon...

Regards,
Damien