Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to (re)load files in Racket (X)REPL?

Suppose I have a file like

#lang racket/base
(define (hello) (print "Hello"))
... more definitions ...

and I would like to load the definitions in the file to interactively work with them in the (X)REPL. How do I do that?

If I start the (X)REPL and (load "/tmp/hello.rkt"), then the hello function is not made available to me:

-> (hello)
; hello: undefined;

If I (require (file "/tmp/hello.rkt")), the result is the same. Now I can (enter! (file "/tmp/hello.rkt")) and then (hello) works, but this seems rather ... unintuitive and beginner-unfriendly.

Is this indeed the way this should be done and should I simply read up on modules and namespaces to easily browse and experiment with my code or is there a simpler way I'm overlooking?

N.B. I found How do you load a file into racket via command line?, but that only explains how to run the file. Not how to load it in the REPL, so you can test/debug some specific definitions, then edit, reload, etc.

like image 796
Confusion Avatar asked Feb 16 '13 09:02

Confusion


2 Answers

Since files that start with #lang are modules, it does nothing if you load them. (Actually it does something, but probably not something that would help you.) It is really best to avoid using load completely, just pretend that it's not there.

Now, using require is the right thing, but what it does is instantiate the module and give you access to the names that it provides. In your case, you didn't provide anything which means that you can't use your hello. To do that, you can add (provide hello) to the file. But that's likely not what you want, since it seems that you want to debug code. (Ie, you won't want to provide everything from your module just to work on things.)

So the right thing to use is enter!, or if you're using xrepl, then there's a more convenient ,en command. This will instantiate the module and make the repl use the namespace of the module, so you can access everything. (And you don't need to load or require it.) You can also use it multiple times to reload the code if you change it. But note that there were some issues with it, so you might need to install a nightly build to work with it.

Finally, you probably know that, but working with DrRacket will make things much easier in general.

like image 73
Eli Barzilay Avatar answered Oct 04 '22 22:10

Eli Barzilay


Putting the #lang racket/base at the top of your file is marking the file as a module form (this is the #lang shorthand); thus loading the file is just adding a module definition for (file "/tmp/hello.rkt"), as you have discovered when you required that path.

If you just want to experiment with a set of definitions and try loading them interactively, you might try removing the #lang racket/base from the top of the file. I illustrate this here on a pair of "Racket toplevel" (rktl) files:

% cat hello-unhashed.rktl
(define (hello) (print "Hello") (newline))
% cat hello2-unhashed.rktl
(define (hello) (print "Hello2") (newline))
% racket
Welcome to Racket v5.3.2.
> (load "hello-unhashed.rktl")
> (hello)
"Hello"
> (load "hello2-unhashed.rktl")
> (hello)
"Hello2"
> (load "hello-unhashed.rktl")
> (hello)
"Hello"
> (exit)
% 

Note that there are plenty of pitfalls when working at the top-level in the manner illustrated above. To get a feeling for what I am talking about, try googling "racket top level is hopeless" or "plt scheme top level is hopeless"

like image 24
pnkfelix Avatar answered Oct 04 '22 22:10

pnkfelix