hamacs/ha-programming-scheme.org
2022-04-04 20:20:59 -07:00

5.8 KiB
Raw Blame History

Programming in Scheme for SICP

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, lets use Guile:

  brew install guile

Geiser (Scheme Interface)

The geiser project attempts to be the interface between Emacs and various Schemes. Since I cant decide which to use, Ill 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)))

Lets test it out by defining a variable:

  (define a 42)

And simply using it:

  (+ a b)
;Value: 50

And what about Scheme-specific stuff needed for SICP?

  (inc 42)

Install SICP

Lets get the book available as an Info page:

(use-package sicp)

And does this work?

  (inc 42)

Still having difficulty getting the Scheme REPL to output the results back into this document. Lets try Racket…

If we want to read the sicp.info file, looks like we need this, at least, temporarily:

(add-to-list 'auto-mode-alist '("\\.info\\'" . Info-mode))

Racket

Actually, lets do this with Racket:

  brew install racket

While Racket, as a Scheme, should work with Geiser (below), lets 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 (:type git :protocol ssh :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)
42

Working for output?

  (define str-1 "hello")
  (define str-2 "world")
  (define all (string-join (list str-1 str-2) ", "))
  (display (string-titlecase all))
Hello, World

The interface is horrendously slow, as the :session doesnt 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:

Lets try this now:

(inc 42)
43