user8370684
user8370684

Reputation:

How to deal with name conflicts in Racket?

While learning Racket, I came across the gregor package which says that its date struct conflicts with the built-in date struct:

Gregor provides a date struct that represents a calendar date without a time or time zone. Unfortunately, the name date conflicts with an existing, incompatible definition in racket/base.

Before I do a (require gregor), I get the built-in date. After (require gregor), I get gregor's date. That's fine.

But, in the interest of understanding how to deal with conflicts and namespaces, is it possible for me to access the built-in date? Can I somehow put gregor into a namespace so I can use both? What's the idiomatic way of dealing with this?

Upvotes: 1

Views: 363

Answers (2)

Sylwester
Sylwester

Reputation: 48745

First off require overrides the base package the languages imported. Thus unlike standard Scheme where you need to rename or exclude from the base package you can require and as long the conflicting name is not from another require it works.

Imagine I use #!racket/base througout as the language. So lets imagine you want to do this:

(require racket) ; now date it will conflict
(require gregor)

I just press run and see whats happening. So I got an error that date? was a conflict and I choose to omit it:

(require (except-in racket/base date?)) 
(require gregor)

I still got the conflict date so I just add it to the exception:

(require (except-in racket date? date)) 
(require gregor)

Now we have something that works, but you cannot use date? and date from racket Now if you want to be able to use both you might want to add a prefix:

(require (prefix-in rb: racket))
(require gregor)

This will make a binding like rb:date as the racket/base one, but it will also have rb:second etc. If you just want to rename date? and date I would have done this:

(require (rename-in racket [date? rb:date?] [date rb:date]))
(require gregor)

Like this we have date? and date as rb:date? and rb:date while keeping all the other bindings like second as is.

You can mix and match and usually you choose the easiest solution for providing exactly what you want. More ways to do this in the codumentation for require and provide

Upvotes: 2

Sorawee Porncharoenwase
Sorawee Porncharoenwase

Reputation: 6502

You can rename each required ids to make them not conflict.

(require (rename-in gregor [date gregor-date]))
date ;; Racket's date
gregor-date ;; gregor's date

But a quick solution would be prefixing every required ids (which creates the "namespace" in a sense)

(require (prefix-in gregor: gregor))
date ;; Racket's date
gregor:date ;; gregor's date

See https://docs.racket-lang.org/reference/require.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._prefix-in%29%29

Upvotes: 3

Related Questions