MIT/GNU Scheme in Org mode
Table of Contents
1. An error occurs
Evaluating Code Blocks in Emacs Org mode with MIT/GNU Scheme seems to result in an error.
Below, we describe the error and attempt a solution. First, we set geiser-default-implementation so that Org mode selects the MIT/GNU Scheme implementation.
(setq geiser-default-implementation 'mit)
2. The error
Below is a Scheme code block in Org mode consisting of the
expression 12.
#+begin_src scheme 12 #+end_src
We evaluate it using the command org-babel-execute-src-block (C-c
C-c). It should result in the value 12 being inserted in a results
block under the code block. However, nothing is inserted in the
results block and emacs *Message* buffer displays:
Executing Scheme code block at position 1... Starting Geiser REPL ... [3 times] /home/user-foo/prj-1 couldn't be added to load path Mit REPL up and running! evaluating: (:eval (:scm (begin ;; -*- geiser-scheme-implementation: mit -*- 12))) Error during redisplay: (jit-lock-function 1209) signaled (wrong-type-argument markerp nil) Code block evaluation complete (took 0.5s).
Note: org 9.6.27 and mit-scheme 12.1 were used.
3. Debug
On evaluating the code block, Org mode communicates with the
REPL. In order to inspect this communication, we set a breakpoint on
entry of function geiser-eval--send/wait to see the REPL request
and another breakpoint on entry of
geiser-con--process-completed-request to see the REPL response. To
set breakpoints, use debug-on-entry either interactively or by
evaluating the below elisp.
(debug-on-entry #'geiser-eval--send/wait) (debug-on-entry #'geiser-con--process-completed-request)
With breakpoints setup, we evaluate the same Org code block and
the debugger gets invoked (we only need the c debugger command).
3.1. Debug REPL request
The debugger gets invoked on entry of geiser-eval--send/wait two
times. The second time is what we are interested in, when Scheme code
is about to be sent out for evaluation. At this point the
*Backtrace* buffer shows us the stack frame as follows:
* geiser-eval--send/wait ((:eval (:scm "(begin ;; -*- geiser-scheme-implementation: mit -*-\n12\n)")) 10000)
Arguments to the function show the Scheme code about to be sent to the REPL is:
(begin ;; -*- geiser-scheme-implementation: mit -*- 12)
Note that Org mode inserted the text ;; -*-
geiser-scheme-implementation: mit -*-.
This is a Scheme comment inserted by Org mode before sending code to the Scheme REPL for evaluation.
3.2. Debug REPL response
Next, we use the debugger command to continue (c), allowing Org
mode to send out the request to the REPL. On entry of function
geiser-con--process-completed-request the stack frame is as
follows:
* geiser-con--process-completed-request
(((:id . 2)
(:string .
"(geiser:eval '#f '(begin ;; -*- geiser-scheme-implementation: mit -*-\n12
\n))")
(:continuation . #f(compiled-function
(s)
#<bytecode -0x14344455333cef8e>))
(:buffer . #<buffer *temp*>)
(:connection t
(:filter . comint-output-filter)
(:tq
((nil "\\(\n\\([0-9]+ ([^)]+) => \\)\\)\\|\\(
\n\\([0-9]+ error> \\)\\)"
#1 . geiser-con--process-completed-request))
#<process Mit REPL> . #<buffer tq-temp-Mit REPL>)
(:tq-filter . #f(compiled-function
(p s)
#<bytecode 0x1d386f750742cefb>))
(:eot . "\\(\n\\([0-9]+ ([^)]+) => \\)\\)\\|\\(
\n\\([0-9]+ error> \\)\\)")
(:prompt . "[0-9]+ ([^)]+) => ")
(:debug-prompt . "[0-9]+ error> ")
(:is-debugging . 0)
(:count . 2)
(:completed . #<hash-table eql 0/65 0x158ffe450cd9>)))
#("\n;Unexpected read restart on: #[textual-i/o-port 38 for console]
\n;To continue, call RESTART with an option number:
\n; (RESTART 2) => Return to read-eval-print level 2.
\n; (RESTART 1) => Return to read-eval-print level 1.
\n\n3 error> " 0 229
(charset iso-8859-1)))
It shows that the REPL responded with:
;Unexpected read restart on: #[textual-i/o-port 38 for console] ;To continue, call RESTART with an option number: ; (RESTART 2) => Return to read-eval-print level 2. ; (RESTART 1) => Return to read-eval-print level 1. 3 error>
3.3. Manual REPL attempt
The same error also occurs when we manually evaluate this code in a
REPL. To try it, we run the mit-scheme REPL in a terminal and
evaluate the below code.
(begin ;; -*- geiser-scheme-implementation: mit -*- 12)
It prints the same error. Here it is, shown below. Note that it also
prints the correct result of evaluation (;Value: 12).
;Unexpected read restart on: #[textual-i/o-port 12 for console] ;To continue, call RESTART with an option number: ; (RESTART 1) => Return to read-eval-print level 1. 2 error> ;Value: 12 2 error>
On excluding the comment, the error is no longer printed.
3.4. Conclusion
We conclude that the Scheme comment causes the mit-scheme REPL to print an error. This Scheme comment is:
;; -*- geiser-scheme-implementation: mit -*-
Note that this comment is understood by emacs. It is a method of specifying emacs File Variables.
Anyways, in order to use Org mode with MIT scheme, let us attempt a fix in the Org mode source code.
4. Fix
In the Org mode source code, find the function
org-babel-scheme-execute-with-geiser in file ob-scheme.el and
delete the code which inserts the Scheme comment. This is just one
line shown below. Delete this line:
(insert (format ";; -*-geiser-scheme-implementation: %s -*-" impl))
We evaluate the edited function definition for it to take effect in the current emacs process. (Alternatively, we could restart emacs)
Lastly, we evaluate the same example Org code block which is as follows:
#+begin_src scheme 12 #+end_src
This time the result is correctly inserted in the results block under the code block as shown below:
#+begin_src scheme 12 #+end_src #+RESULTS: : 12
We are now able to evaluate MIT Scheme in Org code blocks.
5. Side effects
It seems safe to exclude the Scheme comment from being sent to the REPL. After all, a comment is meant to be ignored during evaluation. However there might have been a reason for Org mode to insert the comment in the first place. Hence we do not know the side effects of this fix.