I found ob-lisp.el use SLIME by default to evaluate lisp code. I want to use SLY to evaluate lisp code. How to change it? I found the file ob-lisp.el is short. I tried to change slime to sly. But it is not customizable. I hope to define a defcustom for it. So that user can customize it. But I don't know how to apply this into code. For example, I define a custom like this:

(defcustom org-babel-lisp-default-implement "slime")

((defcustom org-babel-lisp-implements
   '("slime" "sly")
   "A list of Lisp implements."
   :group 'org-babel
   :version "24.1"
   ;; FIXME: reference code example.
   :type listp))

Then in file ob-lisp.el. Has some places use slime. I want to make them adapt to upper defcustom value. like concate string from value or something else.

(declare-function slime-eval "ext:slime" (sexp &optional package))

(defun org-babel-execute:lisp (body params)
  "Execute a block of Common Lisp code with Babel."
  (require 'slime)
   (let ((result
          (funcall (if (member "output" (cdr (assoc :result-params params)))
                       #'car #'cadr)
                     (insert (org-babel-expand-body:lisp body params))
                     (slime-eval `(swank:eval-and-grab-output

2 Answers 2


The easiest way is to parametrize the call slime-eval, using funcall and a defvar/defcustom and take advantage use of sly's retro contrib, which allows the user to refer to the slynk pacage by the name of swank. Besides the replacing (slime-eval ...) with (funcall org-babel-lisp-eval-fn ...) the other thing we must do is to require slime or sly when appropiate. I'm using pcase but there may be a more appropriate string-case in emacs lisp.

(defcustom org-babel-lisp-eval-fn
  '("slime-eval" "sly-eval")
   "The function to be called to evaluate code on the lisp side."
   :group 'org-babel
   :version "24.1"
   :type listp)

(defun org-babel-execute:lisp (body params)
  "Execute a block of Common Lisp code with Babel."
  (pcase org-babel-lisp-eval-fn
    ("slime-eval" (require 'slime))
    ("sly-eval" (require 'sly)))
   (let ((result
      (funcall (if (member "output" (cdr (assoc :result-params params)))
               #'car #'cadr)
             (insert (org-babel-expand-body:lisp body params))
             (funcall org-babel-lisp-eval-fn
                                ,(let ((dir (if (assoc :dir params)
                                                (cdr (assoc :dir params))
                                    (if dir (format org-babel-lisp-dir-fmt dir)
                                      "(progn %s\n)")
                                     (point-min) (point-max)))))
                              (cdr (assoc :package params)))))))
     (org-babel-result-cond (cdr (assoc :result-params params))
       (condition-case nil
           (read (org-babel-lisp-vector-to-list result))
         (error result))))
   (org-babel-pick-name (cdr (assoc :colname-names params))
            (cdr (assoc :colnames params)))
   (org-babel-pick-name (cdr (assoc :rowname-names params))
            (cdr (assoc :rownames params)))))

Please note that if you have a modern enough version of org mode you can just simply do

  (setq org-babel-lisp-eval-fn #'sly-eval)
  • Yes, this is option which I added in Org Mode built-in code after I have this problem. Commented Mar 10, 2021 at 2:09
  • 1
    Thank you for this!
    – margolari
    Commented Mar 10, 2021 at 13:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.