Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Setting language with #lang in the REPL

Tags:

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 in the current context".

Is there a command-line switch that I'm missing? Or maybe a ",metacommand" I can use? The reason I need this is because I would like to be able to send an Emacs buffer to the Racket REPL, but that won't work if the file starts with #lang.

like image 391
Davor Cubranic Avatar asked Jan 08 '14 23:01

Davor Cubranic


People also ask

How do I switch to English mode?

Press "Alt-Shift" to toggle between language modes without accessing the Language Bar. As an example, if you only had two languages installed, pressing "Alt-Shift" would immediately return you to English mode.


2 Answers

[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"
[email protected]>

I can then access the module in the REPL:

[email protected]> k
6
[email protected]> (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:

[email protected]> ,enter "clyde.rkt"
[email protected]> ,enter "bonny.rkt"
[email protected]>

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.

like image 143
ben rudgers Avatar answered Oct 14 '22 04:10

ben rudgers


; 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:

  • Geiser
  • Quack
  • racket-mode (I'm guilty for this one)

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).

like image 27
Greg Hendershott Avatar answered Oct 14 '22 05:10

Greg Hendershott