# Why modules and when?

**URL:** <https://racket.discourse.group/t/why-modules-and-when/2447>\
**Category:** Questions & Answers\
**Tags:** question, module\
**Created:** [October 30, 2023, 11:03pm UTC](https://racket.discourse.group/t/why-modules-and-when/2447 "2023-10-30T23:03:00Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![thrilway](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/thrilway/32/1398_2.png) [@thrilway](https://racket.discourse.group/u/thrilway)\
**Post date:** [October 30, 2023, 11:03pm UTC](https://racket.discourse.group/t/why-modules-and-when/2447/1 "2023-10-30T23:03:00Z")

</div>

I'm working on a project in racket—a web app—and I'm wondering whether to make my individual rkt files into modules so the can be imported as, _e.g._,`(require users)`, or just leave them as is so they'd be imported as, _e.g._, `(require "users.rkt")`. Are there any benefits to either choice, or is it a question of taste or style?

---

<div class="post-metadata">

**Author:** ![usao](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/usao/32/1375_2.png) [@usao](https://racket.discourse.group/u/usao)\
**Post date:** [October 31, 2023, 10:05am UTC](https://racket.discourse.group/t/why-modules-and-when/2447/2 "2023-10-31T10:05:00Z")

</div>

There seems to be a confusion regarding what a “module” is. Essentially, every file that starts with [a `#lang` line](https://docs.racket-lang.org/guide/Module_Syntax.html#%28part._hash-lang%29) _is_ a module. The difference between the two [_module paths_](https://docs.racket-lang.org/guide/module-paths.html) `"some-module.rkt"` and `some-collection/some-module` is that the former is a relative import, while the latter is a library import. The convention is that relative imports are used for package-internal imports, whereas library imports for package-external ones. As a library writer, you should expose useful exports in public modules (preferably under a collection to avoid potential conflict) so that clients can import them as libraries.

---

<div class="post-metadata">

**Author:** ![thrilway](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/thrilway/32/1398_2.png) [@thrilway](https://racket.discourse.group/u/thrilway)\
**Post date:** [November 1, 2023, 6:44pm UTC](https://racket.discourse.group/t/why-modules-and-when/2447/3 "2023-11-01T18:44:47Z")

</div>

So if I'm reading this correctly, there's no real downside to sticking with _relative imports_ if I'm building an app and I have no expectation that anyone will use it as a library, but if I were building a library for other programmers, then I should use _library imports_

Is that about right?

---

<div class="post-metadata">

**Author:** ![sorawee](https://avatars.discourse-cdn.com/v4/letter/s/ea5d25/32.png) [@sorawee](https://racket.discourse.group/u/sorawee)\
**Post date:** [November 1, 2023, 7:16pm UTC](https://racket.discourse.group/t/why-modules-and-when/2447/4 "2023-11-01T19:16:26Z")

</div>

That’s not what @usao meant.

When you use stuff from your current project, use relative import. When you use stuff from other projects, use library import. This applies to both applications and libraries.

For example, let’s say I am building an app with the main file `app.rkt`. The file depends on `helper.rkt` in the same project, and `/path/to/another-project/easy-xml/transform.rkt`. In that case, your `app.rkt` would have:

```scheme
(require "helper.rkt"
         easy-xml/transform)

```

provided that you installed `/path/to/another-project/easy-xml` so that the library import `easy-xml/transform` works.

---

<div class="post-metadata">

**Author:** ![thrilway](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/thrilway/32/1398_2.png) [@thrilway](https://racket.discourse.group/u/thrilway)\
**Post date:** [November 1, 2023, 8:55pm UTC](https://racket.discourse.group/t/why-modules-and-when/2447/5 "2023-11-01T20:55:07Z")

</div>

If that is what @usao meant, then I didn't phrase my question correctly. Actually, it would be better to say that my question was based on a faulty presupposition. The resulting confusion made me go back and read the docs more carefully, and I think I understand where I went wrong now. Allow me to explain.

Suppose I am writing an app consisting of two files in a directory like so:

```scheme
my-app/
├─ main.rkt
├─ helper.rkt

```

I was trying to figure out what I would have to to `helper.rkt` so that I could use a library import in `main.rkt`—_i.e._, `(require helper)` or `(require my-app/helper)`—rather than a relative import. I had thought that this could be accomplished by use of the `module` form in `helper.rkt`.

Based on my closer reading, my thinking was incorrect. If I understand correctly, in order to import a module using a library import, it is necessary—though maybe not sufficient—for that module to be in the proper collection directories—_e.g._ `/usr/share/racket/collects`. As such, it is practically impossible, in the app described above, to import `helper.rkt` into `main.rkt` using a library import.

Is this roughly correct?

---

<div class="post-metadata">

**Author:** ![jbclements](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/jbclements/32/11_2.png) [@jbclements](https://racket.discourse.group/u/jbclements)\
**Post date:** [November 1, 2023, 10:04pm UTC](https://racket.discourse.group/t/why-modules-and-when/2447/6 "2023-11-01T22:04:54Z")

</div>

I think you're a lot closer, yes.  
(1) It's standard to just use relative imports to import files that are part of the same package, that's not worse than importing them using a package-relative spec.  
(2) It's probably easier than you think to get your directory to be a package that can be imported from other places; it's generally as simple as putting a little stub `info.rkt` file in your directory (and indeed, I think you may even be able to skip adding the `info.rkt`), and then installing your directory as a package with e.g.

```scheme
raco pkg install ./my-app

```

... from the parent directory.

EDIT: the point here is that you definitely _don't_ have to move your directory to be in the "proper collection directories."
