Contract violation expected when using a module from R6RS - racket

I have the following module in abc/main.rkt:
#lang racket
(provide (all-defined-out))
(define (abc) 10)
Here's a short R6RS program which imports that module:
#!r6rs
(import (rnrs) (abc))
(display (abc))
(newline)
This error message appears at the bottom of the DrRacket window when that program is loaded:
+: contract violation expected: number? given: #f argument position: 1st other arguments...: 0
I'm able to run the program successfully however.
Any suggestions on how to get rid of the error?

Related

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

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.

lisp: tracing a macro in an imported package [duplicate]

The trace macro is very useful for debugging. But it comes to a halt, when used upon any macro. Like if I try to do the following :
CL-USER> (trace push)
Then, it'll give an error saying:
can't use encapsulation to trace anonymous function #<FUNCTION (MACRO-FUNCTION
PUSH) {100053FB9B}>
[Condition of type SIMPLE-ERROR]
Well, that's obvious because the clhs page of trace, clearly defines it upon functions. So, what is the reason for not having any facility for tracing macros in Common Lisp?
Is there any other (unconventional) way to trace macros in Common Lisp?
The Common Lisp standard only mentions tracing of functions. In compiled implementations, macro expansion usually takes place at compile time and thus tracing of macros is usually not supported.
But some Common Lisp implementations can trace macros via a Lisp interpreter (!):
CLISP can trace macros:
[1]> (defmacro foo (a) a)
FOO
[2]> (trace foo)
;; Tracing macro FOO.
(FOO)
[3]> (loop for i below 4 collect (foo i))
1. Trace: (FOO I)
1. Trace: FOO ==> I
1. Trace: (FOO I)
1. Trace: FOO ==> I
1. Trace: (FOO I)
1. Trace: FOO ==> I
1. Trace: (FOO I)
1. Trace: FOO ==> I
(0 1 2 3)
LispWorks is another implementation which supports tracing of macros.
So, what is the reason for not having any facility for tracing macros in Common Lisp?
As mentioned that's the language standard. Beyond the language standard implementations provide all kinds of language extensions in various ways, including the ability of some Lisp interpreters (!) to trace macros.
If the code is already compiled, tracing won't work anyway. Having a Lisp interpreter helps, but implementations are not required to have an interpreter. Lisp interpreter here means an executing engine which works from Lisp code as data.
Using trace on a macro seems a little odd, but it works in CLISP:
(trace push)
(defparameter *stack* '())
(defun push-xy (x y)
(push x *stack*)
(push y *stack*))
; 1. Trace: (push x *stack*)
; 1. Trace: push ==> (setq *stack* (cons x *stack*))
; 1. Trace: (push y *stack*)
; 1. Trace: push ==> (setq *stack* (cons y *stack*))
; ==> push-xy
The standard does not say when it should expand macros so this might happen when functions and lambdas are defined, compiled and sometimes called. Some implementations run the macro twice so you get double the output.
I never use this. I rather use macroexpand-1:
(macroexpand-1 '(push x *stack)))
; ==> (setq *stack (cons x *stack))
; ==> t
If your form returns a new form that uses macros you might want to try macroexpand instead. Its like calling macroexpand-1 over and over until there are no transformation left.
*macroexpand-hook* is the expected method for tracing macros.
http://www.lispworks.com/documentation/HyperSpec/Body/v_mexp_h.htm#STmacroexpand-hookST

Racket error - module: identifier already required

Am getting the following error when trying to run (require 2htdp/image) in DrRacket:
module: identifier already required
The error occurs after updating from DrRacket 7.3 to 7.4.
I uninstalled all previous versions of DrRacket including 7.4 and reinstalled 7.3. Am continuing to get error.
I went through some of the solutions in stackoverflow for this error message before posting. However, my code is simple. I cannot even run (require 2htdp/image) on its own without code without triggering the error.
[edit]
Check-syntax:
unsaved-editor:2:9: module: identifier already required in: rectangle
I have no idea what that means, since there is no rectangle attached to this test.
[edit]
Language: Beginning Student [custom]; memory limit: 128 MB.
Teachpack: world.rkt.
it's means you added teachpack (*.rkt) has same function name "rectangle".
just clear teachpacks only add you really needed teachpacks
(require 2htdp/image) "image.rkt" have function rectangle.
(require htdp/world) "world.rkt" also have function rectangle.
In same folder create a.rkt b.rkt c.rkt
create file a.rkt
#lang racket
(provide t)
(define (t x) (+ x 1))
create file b.rkt
#lang racket
(provide t)
(define (t x) (+ x 2))
create file c.rkt
#lang racket
(require (file "a.rkt"))
(require (file "b.rkt"))
(t 3)
run c.rkt will shows
module: identifier already required in: t

How do I make my Racket-designed language run scripts from external files?

I've got a custom language I'm designing in Racket, let's call it waffle.
Let's say I have
(define (printstr . input)
(if (string? (car input))
(write (string-join input ""))
(write input)))
; ... a whole bunch of other definitions
(command-line
#:multi
[("-v" "--verbose") "more verbose" (set! loglevel (add1 loglevel))]
[("-q" "--quiet") "be quiet" (set! loglevel 0)]
#:once-any
[("-i" "--in-place") "edit in-place" (set! mode 'in-place)]
[("-c" "--create-new") "create a new file" (set! mode 'new)]
[("-n" "--dry-run") "do nothing" (set! mode #f)]
#:once-each
[("-d" "--directory") dir "work in a given directory" (set! root dir)]
#:help-labels "operations to perform:"
#:multi
[("+l" "++line") "add a line" (set! ops `(,#ops "add"))]
[("-l" "--line") "delete a line" (set! ops `(,#ops "delete"))]
[("-e" "--edit") "edit a line" (set! ops `(,#ops "edit"))]
#:args (file)
(define in (open-input-file file))
; This is probably where I'm going wrong with how my language REPL evaluates files passed to it.
(eval (file->list file) ns))
Then I create an executable from DrRacket using 'Racket [menu] -> Create Executable ... -> [Type] Launcher'. Name is e.g. waffle-test.
I've got a file written in my waffle language, hello.waffle:
(printstr "Hello!")
I expect this to print 'Hello!' on the command line and then exit without errors. But I get a strange error I don't understand, and I get my prompt back without a newline.
$ ./waffle-test hello.waffle
application: not a procedure;
expected a procedure that can be applied to arguments
given: #<void>
arguments...: [none]
context...:
eval-one-top12
"/home/connie/Desktop/racket-ffgardfghf/waffle": [running body]
temp37_0
for-loop
run-module-instance!125
perform-require!78
"Hello!" $
I know you're not supposed to use eval but I can't find out how to make my language executable read and run files I pass to it. What is the best approach to doing this?
Just with this simple test I figured out a couple of things:
#!racket
(file->list "test.waffle")
With test.waffle as:
(waffle me)
(waffle it)
The repl printed:
((waffle me)
(waffle it))
However that is not valid code, even if waffle is a valid procedure. You need it to look like this:
(begin
(waffle me)
(waffle it))
Now you can do this by require your language to have it, but you can also just cons a begin to the resulting structure and eval will evaluate each top level form one by one in order.
You will run into problems with using eval. You'll know that soon enough. The correct way to make an interpreter is by creating your own eval that implements your languages syntax and takes en environment with primitives. It has an interface to use the host, but not regardless. With eval waffle programs has access to all internals and you're not really creating an interpreter since you just expose Racket.
I remember someone did the same with Ruby and had a web page and someone just tried to type in a command that deleted all the files on the system and the web service went away.
By fixing a few bugs in my code I managed to solve my problem!
I changed
(eval (file->list file) ns))
to
(define program (cons 'begin (file->list file)))
(eval program ns))
I also changed the 'printstr' function from
(define (printstr . input)
(if (string? (car input))
(write (string-join input ""))
(write input)))
to
(define (printstr input)
(displayln input))

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?