I would like to set the language in the REPL on the fly, with #lang
, not using \"-I\" command-line argument. But this gives me the error \"read: #lang not enabled i
; foo.rkt
#lang whatever
"hi"
is basically the same as
(module foo whatever
"hi")
So as a quick hack you could probably slice off the #lang
line, grab the lang out of it, and stuff the rest of the buffer inside of the (module ...)
form before comint-send-input
-ing it.
Even easier, if you don't mind saving the buffer to disk, first: Just send over ,enter /path/to/file.rkt
to the REPL buffer, or if you're not using XREPL, (enter! "/path/to/file.rkt")
.
Also, it's worth mentioning a few Racket-related modes:
One of them might already do what you want, or, you could peek into how they work (each takes a somewhat different approach to this).
[Edit]
I can't get C-x C-b
to work with #lang
either.
But a buffer containing #lang
can be sent to a REPL started from Geiser with C-c C-a
. This is Switch to REPL and Enter Module from the Geiser drop down menu. If I have a buffer for bugsy.rkt:
;; bugsy.rkt
#lang racket
(define k 6)
(define j 7)
(define (f lhs rhs)
(+ lhs rhs))
Typing C-c C-a
gives me this in the REPL:
racket@> ,enter "<filepath>/bugsy.rkt"
racket@bugsy.rkt>
I can then access the module in the REPL:
racket@bugsy.rkt> k
6
racket@bugsy.rkt> (f 3 4)
7
If I want to switch to a different module [or buffer of a file] I can use the ,enter
command in the REPL:
racket@bugsy.rkt> ,enter "clyde.rkt"
racket@clyde.rkt> ,enter "bonny.rkt"
racket@bonny.rkt>
There is an example of the ,enter
command in the documentation. Look above the Dinosaur.
[Original]
According to the Racket documentation #lang
has very simple syntax, the reader essentially bootstraps a language syntax from whatever follows the space character after #lang
. This means in some sense that #lang
is not in Racket's [or any other language's] syntax. Instead it is a implementation feature of the reader which forms part of the larger "Racket" development ecosystem.
Geiser [and presumably Quack and racket-mode] handle this by parsing #lang
in elsip before passing code to the Racket REPL. In Geiser, the work is done in geiser-racket.el.
The parsing function is at line 132:
(defun geiser-racket--language ()
(or (cdr (geiser-racket--explicit-module))
(save-excursion
(goto-char (point-min))
(if (re-search-forward "^#lang +\\([^ ]+\\)" nil t)
(geiser-syntax--form-from-string (match-string-no-properties 1))))
"#f"))
And it is called by geiser-racket--geiser-procedure
on line 166.
(defun geiser-racket--geiser-procedure (proc &rest args)
(case proc
((eval compile)
(format ",geiser-eval %s %s %s"
(or (car args) "#f")
(geiser-racket--language)
(mapconcat 'identity (cdr args) " ")))
((load-file compile-file)
(format ",geiser-load %S" (geiser-racket--find-module)))
((no-values) ",geiser-no-values")
(t (format ",apply geiser:%s (%s)" proc (mapconcat 'identity args " ")))))
That may give you a starting point for rolling your own code if one of the existing Emacs modes does not meet your needs.
I had a really hard time wrapping my head around this using Racket & Geiser to go through SICP with #lang sicp
. Finally figured it out. Based on all the good answers above, these are comments to remind myself of what to do and why:
#lang sicp
;;C-c C-a loads #lang module into REPL (save before loading)
;;C-u C-c C-z is faster than C-c C-a
;;https://docs.racket-lang.org/sicp-manual/index.html
;;https://stackoverflow.com/questions/21008623/setting-language-with-lang-in-the-repl
(#%require sicp-pict)
(paint einstein)
Racket and Geiser are two amazing pieces of software, almost gave up but it was worth the effort to get this working. Thanks to all for the good work and helping us learn.