Setting language with #lang in the REPL

天涯浪子 提交于 2019-12-03 11:24:00

问题


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.


回答1:


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




回答2:


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




回答3:


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.



来源:https://stackoverflow.com/questions/21008623/setting-language-with-lang-in-the-repl

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!