General question:
Can I invoke the current racket
executable from within a running Racket script?
Basically, I'd like a replacement for (system "racket ...")
in the case that (find-executable-path "racket")
does not return a path to the Racket executable I'm currently using.
Context:
What I really want is to try compiling a few expressions and assert that they raise compilation errors. This is for unit testing.
On Windows, you can start DrRacket from the Racket entry in the Start menu. In Windows Vista or newer, you can just type DrRacket. You can also run it from its folder, which you can find in Program Files → Racket → DrRacket. On Mac OS, double click on the DrRacket icon.
GRacket, which is a GUI variant of racket to the degree that the system distinguishes them. On Unix, the executable is called gracket, and single-instance flags and X11-related flags are handled and communicated specially to the racket/gui/base library.
To exit Racket, type "(exit)". If you prefer to use DrRacket to write your code, you must start your code with a language declaration.
I don't believe you need to step outside of the executable here. Try this:
#lang racket
(require syntax/modread)
;; define a namespace anchor to attach a namespace to:
(define-namespace-anchor anchor)
;; define a namespace for expansion:
(define target-namespace (namespace-anchor->namespace anchor))
(define program-to-compile
"#lang racket
(+ 3 4)")
;; go ahead and expand
(with-module-reading-parameterization
(λ()
(parameterize ([current-namespace target-namespace])
(expand
(read-syntax
"bogus-filename"
(open-input-string program-to-compile))))))
I think I'm correct when I say that Racket is singularly clean in its ability to provide the compiler to running programs in a disciplined way.
If your goal is just to compile some racket expressions, you can do that just with either compile
or compile-syntax
. An example file would be:
#lang racket
(require rackunit)
(define tests
(list #'(+ 1 "3")
#'(void void)
#'(string-append 4)))
(for/list ([t (in-list test)])
(check-exn exn:fail?
(lambda () (compile t))))
Where exn:fail?
is whatever exception you are looking for.
Furthermore, if you have some common syntax context you want to run your test in, you can use #`
#,
. So your code would end up something like this:
#lang racket
(require rackunit)
(define tests
(list #'(+ 1 "3")
#'(void void)
#'(string-append 4)))
(for/list ([t (in-list test)])
(check-exn exn:fail?
(lambda () (compile #`(module anonymous racket
#,t)))))
Finally, if your code is stored on your computer, you can use John's solution, while using file->string
to convert the file into a string.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With