Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Invoke `racket` in a Racket script

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.

like image 871
Ben Greenman Avatar asked Dec 13 '15 02:12

Ben Greenman


People also ask

How do I run a Racket file?

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.

What is GRacket?

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.

How do you exit a Racket?

To exit Racket, type "(exit)". If you prefer to use DrRacket to write your code, you must start your code with a language declaration.


2 Answers

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.

like image 80
John Clements Avatar answered Oct 08 '22 06:10

John Clements


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.

like image 41
Leif Andersen Avatar answered Oct 08 '22 06:10

Leif Andersen