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.

6. Related links