4

I'm trying to require one file in another while working with Racket. I have two files in the same folder. They are world.rkt and ant.rkt.

world.rkt:

(module world racket
  (provide gen-grid gen-cell)

  (define (gen-cell item fill)
    (cons item fill))

  (define (gen-grid x y fill)
    (begin
      (define (gen-row x fill)
        (cond ((> x 0) (cons (gen-cell (quote none) fill)
                             (gen-row (- x 1) fill)))
              ((<= x 0) (quote ()) )))

      (cond ((> y 0) (cons (gen-row x fill)
                           (gen-grid x (- y 1) fill)))
            ((<= y 0) (quote ()) )))))

ant.rkt:

(module ant racket
  (require "world.rkt")

  (define (insert-ant grid x y)
    (cond ((> y 0) (insert-ant (cdr grid) x (- y 1)))
          ((< y 0) 'Error)
          ((= y 0) (begin
                     (define y-line (car grid))
                     (define (get-x line x)
                       (cond ((> x 0) (get-x (cdr line) (- x 1)))
                             ((< x 0) 'Error)
                             (= x 0) (gen-cell 'ant (cdr (car line))) ))

                     (get-x y-line x))))))

Now, I can type (require "ant.rkt") in the REPL, and then when I type (gen-cell 'none 'white) I get the error:

reference to undefined identifier: gen-cell  

I've looked up documentation on imports and exports, but I can't get it to import correctly. I feel like it's something really simple that I just don't understand about the syntax.

How should I change my code so that I can use gen-grid and gen-cell in ant.rkt?

dbmikus
  • 5,018
  • 6
  • 31
  • 37
  • 1
    maybe you should read this: http://stackoverflow.com/questions/4809433/including-an-external-file-in-racket – Eineki Jun 27 '11 at 18:38
  • No, that question is asking about `include` for module-less code. But in this question dbmikus is already using modules, so he's in a better starting point. – Eli Barzilay Jun 27 '11 at 20:00

1 Answers1

6

Your code looks fine, and when I tested it there were no problems.

But note two things:

  1. It is much better these days to start your code with #lang racket (or #lang racket/base). Not only has this became the convention, it allows using whatever syntactic extensions the language provides you with, whereas module means that you're using the default sexpr. (BTW, it's also more convenient in that you don't need to make the module name be the same as the file name.)

  2. Using load with modules is probably doing something different than what you think it does. It's really best to just avoid using load, at least until you know exactly what it's doing. (It is exactly as bad as eval.) Instead, you should always stick to require. And when you learn some more, you can see that sometimes dynamic-require is useful too, but just keep load out for now.

Eli Barzilay
  • 29,301
  • 3
  • 67
  • 110
  • Eli, you don't mention what to use in place of 'load'; I'm assuming that you're suggesting either using 'require' or just calling racket with the file on the command-line. – John Clements Jun 27 '11 at 19:33
  • Ok, I switched my code up a little bit. It is now reflected in the question. I can type `(require "ant.rkt")`, but then when I call `(gen-cell 'none 'white)` I get an error message saying that `gen-cell` is undefined. It seems like it should import `"world.rkt"`. How can I fix that? – dbmikus Jun 27 '11 at 21:10
  • 1
    Ah, that makes a much easier answer: you should either `require` `world.rkt` from the repl too, or re-`provide` the `gen-cell` binding from `ant.rkt`. For example, see `all-from-out`. – Eli Barzilay Jun 27 '11 at 21:14
  • So you're saying I only ever need one of `#lang racket` and `(module ...` Do I interpret this correctly? Does this mean it automatically creates a module when I write `#lang racket`? – Zelphir Kaltstahl Oct 28 '16 at 18:35
  • Yes, and yes -- but `#lang racket` can provide more stuff than `(module...)`, and as time passes more functionality depends on it. – Eli Barzilay Oct 28 '16 at 20:45
  • Would it make sense to update the answer to reflect the new question? – Leif Andersen Jan 31 '18 at 17:40
  • @LeifAndersen, I think so, assuming that you'll keep the encouragement for using `#lang` instead of `(module ...)`. – Eli Barzilay Feb 02 '18 at 20:25