Racket: How to provide/require bindings only? - racket

In a file add42.rkt I have the following definition + effect:
#lang racket
(provide add42)
(define (add42 x)
(+ x 42))
(displayln "-- add42.rkt --")
In a file test.rkt, I require + test:
#lang racket
(require rackunit "add42.rkt")
(check-equal? (add42 0) 42)
The test works fine, however, -- add42.rkt -- is also displayed. Is there a way to only export the function definition from add42.rkt? (I thought (provide add42) would only do that).

Sort of. You can change add42.rkt so that the effects don't run when it is required by another module.
If you can reorganize add42.rkt so that the effects are all in a main submodule, then those effects will happen when add42.rkt is run by itself, but not when it is required into test.rkt.
In add42.rkt separate the effects into a main submodule with module+ main:
#lang racket
(provide add42)
(define (add42 x)
(+ x 42))
(module+ main
(displayln "-- add42.rkt --"))
The effects in the main submodule will be run after the other top-level expressions only if add42.rkt is being run as the main program, not required as a library.

Related

How to require inside a Racket macro?

I currently am putting unit tests at the bottom of the file I'm working on, like this:
(provide foo)
(define (bar x) (+ 1 x))
;; unit tests
(module+ test
(require racket/pretty)
(define testcases '(2 3 4))
(for ([test testcases])
(pretty-print (bar test))))
This works, but I want to avoid repeating the boilerplate unit test code for all my modules. Having never written a macro in Racket before, I'm unsure how to get the various parts to fit together.
I would like to have the following code expand to the boilerplate version above:
(provide foo)
(define (bar x) (+ 1 x))
;; unit tests
(test foo '(2 3 4))
For the test macro, are you sure you need to generate a require from the macro? You can have the test macro generate a use of pretty-print if racket/pretty is required in the file that defines test, and then it doesn't matter whether there's a require in the file that uses test.
For example if you have two files macro.rkt and use.rkt:
file macro.rkt:
#lang racket
(provide test)
(require racket/pretty
syntax/parse/define)
(define-simple-macro (test fn:id args:expr)
(module+ test
(define testcases args)
(for ([test testcases])
(pretty-print (fn test)))))
file use.rkt:
#lang racket
(require "macro.rkt")
(provide foo)
(define (foo x) (+ 1 x))
;; unit tests
(test foo '(2 3 4))
Then the reference to pretty-print works in the output of the macro even though it's not normally available in use.rkt. It works because pretty-print gets its scope from the macro definition site, not the use site.
Does this work for your problem?

How to 'require' a Racket module that doesn't have a #lang header line?

As just one of many possible examples, break-example.rkt would be a perfectly valid Java program, except for the #lang mini-java header that Racket requires.
So e.g. if I've written a Java interpreter/compiler in Racket as a Racket module language, how can I say, "require this file Main.java which is written in module language mini-java but doesn't have any Racket-specific header"?
(Note that I have almost non-zero practical experience with Racket. I'm evaluating this for a specific use case I have for Racket + DrRacket, which has nothing to do with Java by the way. I searched the documentation but couldn't find any way to achieve this.)
I can’t run or test this right now, but maybe you can start from here and experiment with it. The main thing it uses is include/reader:
#lang racket
(require racket/include
syntax/parse/define
(for-syntax racket/syntax
racket/port
syntax/modread))
(define-simple-macro (require/mini-java path)
#:with modname (generate-temporary #'path)
(begin
(include/reader path (mini-java-reader 'modname))
(require 'modname)))
(begin-for-syntax
;; Symbol -> [Any InputPort -> Syntax]
(define ((mini-java-reader modname) src input)
(cond
[(port-closed? input) eof]
[else
(define stx
(with-module-reading-parameterization
(lambda ()
(read-syntax src
(input-port-append #t
(open-input-string "#lang mini-java\n")
input)))))
(close-input-port input)
(syntax-parse stx
[(module _ l . b)
#`(module #,modname l . b)])])))

Certain functions not loading into repl

Working through Little Schemer,
We're required to define a few of our own functions.
I've defined them, only add1 and sub1 appear in the repl after it loads. I'm using Racket v7.0.
#lang racket
(provide atom? add1 sub1)
(define atom?
(lambda (x)
(and (not (pair? x)) (not (null? x)))))
(define add1
(lambda (x)
(+ x 1)))
(define sub1
(lambda (x)
(- x 1)))
I cannot figure out why (atom?) does not load. When I copy paste the s-expression into repl it works. Any ideas?
Since you are unsing #lang racket and provide the correct way to use the file is with require.
$ ls
toys.rkt
$ racket
Welcome to Racket v6.8.
> (require "toys.rkt")
> (atom? '())
#f
So imagine you make a program like this:
#lang racket
(require "toys.rkt")
(if (atom? 'test)
'atom
'no-atom)
You save it and run it:
$ racket program.rkt
'atom
Also note that you can use R6RS and make toys a library. You then need to use plt-r6rs --install toys.rkt and then use (import (rnrs base) (toys)).

Racket REPL and Submodules

Is there an easy way for me to load a submodule in the current file in racket-mode in emacs?
For example if I have the following file
#lang racket
(define (foo x)
x)
(module+ sub
(define (bar x y)
x))
and I hit f5 in racket-mode to start the repl then foo is available but bar is not.
You can combine dynamic-enter! and quote-module-path to do this.
Given a repl interaction for the code above that you posted:
> (require racket/enter syntax/location)
> (dynamic-enter! (quote-module-path sub))
> bar
#<procedure:bar>
Alternatively, you could use dynamic-require/expose (the expose part allows you require things that are not provided), as done here.
It works the same way in DrRacket. You have to provide bar from the submodule, and require the submodule to use it. Try the following code:
#lang racket
(define (foo x)
x)
(module+ sub
(define (bar x y)
x)
(provide bar))
;; (bar 1 2) -- undefined
(require (submod "." sub))
(bar 1 2) ;; -- works here

How to use `typed/racket` in `scribble/lp`

Is it possible to use other #langs in #lang scribble/lp for literate programming?
For example, I want to use #lang typed/racket in #lang scribble/lp. How to realize that?
TL;DR: There are two ways. First, you can simply put your code in a submodule, and require it immediately. Second, you can use my fork of scribble/lp2, which allows you to specify the underlying module language.
First method
Due to an issue, you'll have to wrap the whole thing in a (begin …), although there's a pull request which should fix this on the way.
#lang scribble/lp2
#chunk[<*>
(begin
(module main typed/racket
(define a : Number 1)
(provide a)
(module moo racket/base '…)
(module+ test
(require typed/rackunit)
(check-equal? a (+ 1/2 1/2))))
(require 'main)
(provide (all-from-out 'main))
(module test typed/racket
(require (submod ".." main test))))]
Bear in mind that these are submodule, so you can't put your test module inside main, as it won't be executed. Here, I have a (module+ test …) inside main, and it is required by a test module at the root level. If the (module test at the root is commented out, then the tests won't be executed.
The same concern applies also when requiring moo from another module, you'll have to use (require (submod "myfile.lp2.typed.rkt" main moo)), or make an "alias" like is done above for test and main.
Keep also in mind that the more nested a submodule is, the more times it gets visited and/or instantiated (not sure which). This can have a serious impact on the loading speed in typed/racket programs, as they are already themselves visited and/or instantiated multiple times. You can see this by adding (begin-for-syntax (displayln 'executed)) in your code, it gets printed many times.
Second method
My fork of scribble/lp2, hyper-literate (for hypertext literate programming) only alters scribble/lp2 and relies on the original version of scribble for the rest.
I don't guarantee backwards compatibility, as I'm currently fixing some bugs and adding extra features like being able to re-print a chunk to refresh the reader's memory, etc. The stackoverflow-q-18877881 branch I linked to should remain stable, though. Newer stuff will go in master.
Here's a small example file. There's a more complete example in test/test.hl.rkt:
#lang hyper-literate/typed typed/racket/base
#(require (for-label typed/racket/base
typed/rackunit))
#title{Title}
Hello world.
#chunk[<*>
(require typed/rackunit)
;; Would give an error as typed/racket/base is used on the #lang line:
;curry
(check-equal? ((make-predicate One) 1) #t)
(define (f [x : 'e123]) x)
(define ee (ann (f 'e123) 'e123))
(provide ee)]
It doesn't appear so, but you can use a typed/racket evaluator with scribble/eval.
#lang scribble/manual
#(require racket/sandbox
scribble/eval)
#(define my-evaluator
(parameterize ([sandbox-output 'string]
[sandbox-error-output 'string])
(make-evaluator 'typed/racket/base)))
#interaction[#:eval my-evaluator
(: my-sqr (Real -> Real))
(define (my-sqr x)
(* x x))
(my-sqr 42)]
Example taken from here.