Why does (require (for-syntax 'm)) execute expressions in the required module 3 times in DrRacket? - racket

I don't know how to explain the following behavior in DrRacket's interactions window. I think the output should be only one "hello", since the module m should be instantiated once in this case. But actually "hello" is printed 3 times.
> (module m racket
(printf "hello\n"))
> (module n racket
(require (for-syntax 'm)))
hello
hello
hello
>
The same behavior also exists if I write this example in DrRacket's definitions window and run it.
#lang racket
(module m racket
(printf "hello\n"))
(module n racket
(require (for-syntax (submod ".." m))))
hello
hello
hello
>
This example is a simplified version of one from Racket's guide (https://docs.racket-lang.org/guide/macro-module.html) -- the first example in 16.3.2. The behavior shown in that document
is intuitive (printing the string one time), but when I execute that code in DrRacket's interactions window, it also prints the string 3 times.
I'm using DrRacket version 7.7.

See also https://github.com/greghendershott/racket-mode/issues/379 and https://github.com/racket/drracket/issues/278.
The latter in particular indicates that one of the extra ones is from errortrace instrumentation, which is on by default in DrRacket.

Related

How do I set the meta-language in the Racket REPL?

I have a program that uses the at-exp meta-language:
#lang at-exp racket
(define v '#f{str})
(displayln v)
I want to manually type it line-by-line into the Racket REPL. Unfortunately, #lang at-exp racket is not valid in the REPL:
$ racket
Welcome to Racket v6.11.
> #lang at-exp racket
; readline-input:1:0: read: #lang not enabled in the current context [,bt for
; context]
; at-exp: undefined;
; cannot reference undefined identifier
; [,bt for context]
; racket: undefined;
; cannot reference undefined identifier
; [,bt for context]
>
How do I set the meta-language in the Racket REPL?
For the beginners who have ended up here, the short answer is no. The #lang shorthand should only be used in files. If you want to run your example program in the REPL, you could load it using this command.
racket --repl --eval '(enter! (file "your-file.rkt"))'
The more detailed answer is that the #lang shorthand gets re-written behind the scenes into module form.
So for example something like this...
#lang racket
(define v "Hello!")
(displayln v))
Is re-written to what you see below and you could copy and paste this into the repl and then require the module, e.g. in the repl type...
> (module the-hello-module racket
(define v "Hello!")
(displayln v))
> (require 'the-hello-module)
Hello!
But from what I can tell, that re-write is dependent on the languages you're using, so the rewrite is probably not something you want to do manually and I don't think the at-exp metalanguage is something you would be add manually to module form.
I don't know why they're different, but the REPL inside DrRacket can use the #lang shorthand:
Unlike the command-line REPL, the DrRacket REPL adopts the language spec­i­fied by the #lang line at the top of the defi­n­i­tions panel. DrRacket also uses the REPL itself to print output from the program.
https://beautifulracket.com/explainer/repl.html#a_Rv5YS
So if you have #lang at-exp racket/base in the definitions panel and click "Run" the bottom REPL panel will show Language: at-exp racket/base, etc., and this will work:
> #string-append{this is a test}
"this is a test"
That page also says:
More intri­cate REPL hacking is possible. For instance, the REPL can be config­ured to use a custom reader (other than Racket’s default S-expres­sion reader).
https://beautifulracket.com/basic-3/the-repl.html
However, the steps described there are much more involved than I care to get into. I don't know what DrRacket is doing in the background to make #lang at-exp work.

Why is "swindle" different in the racket interpreter than in drracket?

Can someone explain the difference between using drracket with swindle (any of the versions) and firing up the interpreter as: racket -I swindle
Many expressions evaluate the same in both environments, but some don't. For example:
(let-syntax ((let* (syntax-rules () ((let* a b) "You used let*")))) (let* 3 4))
... evaluates to "You used let*" in every scheme-based language I tried in drracket. However, it fails in the interpreter brought up by "racket -I swindle" on the command line with the error
; readline-input:1:20: syntax-rules: unbound identifier;
; also, no #%app syntax transformer is bound in the transformer phase
; at: syntax-rules
; in: (syntax-rules () ((let* a b) "You used let*"))
; [,bt for context]
Your example uses syntax-rules at phase 1 (aka the "for-syntax phase", aka the "transformer phase"), but it appears that the swindle module (unlike racket/base and racket) does not provide any bindings for-syntax. (It looks like swindle uses an old technique to provide phase-1 bindings that works for modules written in the swindle language but not for a REPL started with racket -l swindle.)
One workaround is to evaluate
(require (for-syntax racket/base))
before evaluating your example, and then your example should work as you expect.

how can I create a new language in racket?

I would like to create a new language that has the same syntax as typed racket, but when executed will do two things:
run the given program as typed racket
if type checks, then translates the input into another language (say python). I am planning to write a translator from typed racket forms to python syntax.
Any suggestions on how to start or pointers to some skeleton code? I have read this tutorial but it mostly talks about creating new syntax which I don't need in my case.
I understand how I can write racket code to translate from one language to another, what I don't get is how I can do both of the above, i.e., first run it as another language, and then do something else with the same input.
It sounds like you want to make a language with a new #%module-begin form. This form is either inserted by the reader (when you do a #lang .... line at the top of your file, or by the language if you wrote the module out by hand. Either way, its generally associated with your language definition. This macro has full access to the entire module's unexpanded syntax. So for example, a macro like this:
(provide (rename-out [-module-begin #%module-begin]))
(define-simple-macro (-module-begin body ...)
(#%module-begin
(writeln '(body ...))
body ...))
Would create a language that does two things:
Print out the body of the code (as an s-expression), and
Run the body with the #%module-begin that the language definition was written in.
You can see how you can use this technique to grab the body of your program twice, and do two different things with it. So let's try running this example. First, lets take the sample from above, and put it in a file "mylang.rkt":
#lang racket
(provide (rename-out [-module-begin #%module-begin])
(except-out (all-from-out racket) #%module-begin))
(require syntax/parse/define)
(define-simple-macro (-module-begin body ...)
(#%module-begin
(writeln '(body ...))
body ...))
And now we can write a program in mylang like this:
#lang s-exp "mylang.rkt"
(+ 1 2)
And when you run it, you'll get something like this:
((+ 1 2))
3
First its printing out the program text, then running it.
You can read more about this process in a paper I wrote discussing this aspect of the Video language. You might also find the book Beautiful Racket to have some examples you might find useful.

Undefined ADT in r5rs

I'm writing an ADT in r5rs and I'm using DrRacket. I put #lang r5rs at the top of my file and chose Determine Language from Source from DrRacket, but it tells me my ADT is undefined. I'm using DrRacket version 6.0. It's the first time I've had this and can't understand what I'm doing wrong.
My ADT
#lang r5rs
(#%require "queue.rkt") ;A required file
(#%provide (all-defined))
(define (my-ADT)
(let ((val1 '())
(val2 '()))
(define (foo) ...)
(define (bar) ...)
(define (dispatch msg)
(case msg
((foo) foo)
((bar) bar)
(else "Unknown message")))
dispatch))
When I try to create an instance of my-ADT I get the following output: my-ADT: undefined; cannot reference an identifier before its definition
When I remove #lang r5rs from the top and choose R5RS as language in DrRacket, it seems to work. But then my queue.rkt file still has #lang r5rs at the top and Determine Language from Source. When I remote #lang r5rs and choose R5RS as language in that file also, I get the following in the my-ADT file:
default-load-handler: expected a `module' declaration
found: something else
in: #<path:/Users/path/path/path/queue.rkt>
The error
my-ADT: undefined; cannot reference an identifier before its definition
normally indicates that the function my-ADT was used before it was defined.
That is, one must place all definitions on top of the file and place the expressions below.
Your example above has no uses of my-ADT so if you get this error, the problem might be in "queue.rkt". Can you run "queue.rkt" without errors?

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.