Programming in Scheme for SICP
Table of Contents
A literate programming file configuring Emacs.
Introduction
First, install MIT-Scheme, the Lisp dialect used throughout the SICP book:
brew install mit-scheme
or sudo apt install mit-scheme
.
brew install mit-scheme
Or better yet, let’s use Guile:
brew install guile
Geiser (Scheme Interface)
The geiser project attempts to be the interface between Emacs and all the Schemes in the world. Since I can’t decide which to use, I’ll install/configure them all.
(use-package geiser :init (setq geiser-mit-binary "/usr/local/bin/scheme" geiser-racket-binary "/usr/local/bin/racket" geiser-guile-binary "/usr/local/bin/guile" geiser-active-implementations '(guile mit) geiser-default-implementations '(guile)) :config (use-package geiser-mit) (use-package geiser-guile) (use-package geiser-racket))
Org Mode
Do we need a Scheme work for Org Babel? According to this document, we just need to make sure we add the :session
variable to start the REPL.
(use-package ob-scheme :straight (:type built-in) :config (add-to-list 'org-babel-load-languages '(scheme . t)))
Since the version of Scheme hasn’t been updated with the deprecation, and subsequent removal of org-babel-get-header
, we include it here:
(defun org-babel-get-header (params key &optional others) (delq nil (mapcar (lambda (p) (when (funcall (if others #'not #'identity) (eq (car p) key)) p)) params)))
Let’s test it out by defining a variable:
(define a 42)
And simply using it:
(+ a b)
And what about Scheme-specific stuff needed for SICP?
(inc 42)
Install SICP
Let’s get the book available as an Info page:
(use-package sicp)
Still having difficulty getting the Scheme REPL to output the results back into this document. Let’s try Racket…
Normally, I would just read the book, however, if we want to read the sicp.info file, we need this, at least, temporarily:
(add-to-list 'auto-mode-alist '("\\.info\\'" . Info-mode))
Racket
Actually, let’s do this with Racket:
brew install racket
While Racket, as a Scheme, should work with Geiser (below), let’s also get racket-mode working:
(use-package racket-mode :config (setq racket-program "/usr/local/bin/racket"))
Can we get Racket working with Org?
(use-package ob-racket :straight (:host github :repo "DEADB17/ob-racket") :after org :config (add-to-list 'org-babel-load-languages '(racket . t)))
Try It Out
Working for values?
(* 6 7)
Working for output?
(define str-1 "hello") (define str-2 "world") (define all (string-join (list str-1 str-2) ", ")) (display (string-titlecase all))
The interface is horrendously slow, as the :session
doesn’t seem to work, and starting up a Racket REPL takes a long time.
SICP and Racket
If using Racket for SICP, install the SICP language:
raco pkg install --auto --update-deps sicp
We now can give it a #lang sicp
(or better yet, use the :lang
header) to define certain SICP-specify features:
Let’s try this now:
(inc 42)