hamacs/ha-programming-scheme.org
Howard Abrams 01a0958e6f Update the copyright year
This really was a lark to see if I could change ALL the files using
woccur and a regular expression. Quite please with how simple that was.
2023-02-23 09:35:36 -08:00

190 lines
5.8 KiB
Org Mode
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#+TITLE: Programming in Scheme for SICP
#+AUTHOR: Howard X. Abrams
#+DATE: 2022-03-01
A literate programming file configuring Emacs.
#+begin_src emacs-lisp :exports none
;;; ha-programming-scheme --- Configuration for Scheme. -*- lexical-binding: t; -*-
;;
;; © 2022-2023 Howard X. Abrams
;; Licensed under a Creative Commons Attribution 4.0 International License.
;; See http://creativecommons.org/licenses/by/4.0/
;;
;; Author: Howard X. Abrams <http://gitlab.com/howardabrams>
;; Maintainer: Howard X. Abrams
;; Created: March 1, 2022
;;
;; This file is not part of GNU Emacs.
;;
;; *NB:* Do not edit this file. Instead, edit the original literate file at:
;; /Users/howard.abrams/other/hamacs/ha-programming-scheme.org
;; And tangle the file to recreate this one.
;;
;;; Code:
#+end_src
* Introduction
First, install MIT-Scheme, the Lisp dialect used throughout the SICP book:
=brew install mit-scheme= or =sudo apt install mit-scheme= .
#+begin_src sh
brew install mit-scheme
#+end_src
Or better yet, lets use Guile:
#+begin_src sh
brew install guile
#+end_src
* Geiser (Scheme Interface)
The [[https://www.nongnu.org/geiser/][geiser project]] attempts to be the interface between Emacs and all the Schemes in the world. Since I cant decide which to use, Ill install/configure them all.
#+begin_src emacs-lisp
(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))
#+end_src
** Org Mode
:PROPERTIES:
:header-args:scheme: :session *scheming* :results value replace
:END:
Do we need a Scheme work for Org Babel? According to [[https://orgmode.org/worg/org-contrib/babel/languages/ob-doc-scheme.html][this document]], we just need to make sure we add the =:session= variable to start the REPL.
#+begin_src emacs-lisp
(use-package ob-scheme
:straight (:type built-in)
:config
(add-to-list 'org-babel-load-languages '(scheme . t)))
#+end_src
Since the version of Scheme hasn't been updated with the deprecation, and subsequent removal of =org-babel-get-header=, we include it here:
#+begin_src emacs-lisp
(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)))
#+end_src
Lets test it out by defining a variable:
#+begin_src scheme
(define a 42)
#+end_src
And simply using it:
#+begin_src scheme :var b=8
(+ a b)
#+end_src
#+RESULTS:
: ;Value: 50
And what about Scheme-specific stuff needed for SICP?
#+begin_src scheme
(inc 42)
#+end_src
** Install SICP
:PROPERTIES:
:header-args:scheme: :session sicp :results value replace
:END:
Lets get the book available as an Info page:
#+begin_src emacs-lisp
(use-package sicp)
#+end_src
Still having difficulty getting the Scheme REPL to output the results back into this document. Lets try Racket...
Normally, I would just [[info:SICP][read the book]], however, if we want to read the [[file:~/.emacs.d/straight/build/sicp/sicp.info][sicp.info]] file, we need this, at least, temporarily:
#+begin_src emacs-lisp
(add-to-list 'auto-mode-alist '("\\.info\\'" . Info-mode))
#+end_src
* Racket
Actually, lets do this with [[https://racket-lang.org/][Racket]]:
#+begin_src sh
brew install racket
#+end_src
While Racket, as a Scheme, should work with Geiser (below), lets also get [[https://racket-mode.com/][racket-mode]] working:
#+begin_src emacs-lisp
(use-package racket-mode
:config (setq racket-program "/usr/local/bin/racket"))
#+end_src
Can we get Racket working with Org?
#+begin_src emacs-lisp
(use-package ob-racket
:straight (:host github :repo "DEADB17/ob-racket")
:after org
:config
(add-to-list 'org-babel-load-languages '(racket . t)))
#+end_src
** Try It Out
:PROPERTIES:
:HEADER-ARGS:racket: :session racketeering :results value replace :lang racket
:END:
Working for values?
#+begin_src racket
(* 6 7)
#+end_src
#+RESULTS:
: 42
Working for output?
#+begin_src racket :results output replace
(define str-1 "hello")
(define str-2 "world")
(define all (string-join (list str-1 str-2) ", "))
(display (string-titlecase all))
#+end_src
#+RESULTS:
: 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
:PROPERTIES:
:header-args:racket: :session *rsicp* :results value replace :lang sicp
:END:
If using [[https://docs.racket-lang.org/sicp-manual/SICP_Language.html][Racket for SICP]], install the SICP language:
#+begin_src sh
raco pkg install --auto --update-deps sicp
#+end_src
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:
#+begin_src racket
(inc 42)
#+end_src
#+RESULTS:
: 43
* Technical Artifacts :noexport:
Let's =provide= a name so we can =require= this file:
#+begin_src emacs-lisp :exports none
(provide 'ha-programming-scheme)
;;; ha-programming-scheme.el ends here
#+end_src
#+DESCRIPTION: A literate programming file configuring Emacs.
#+PROPERTY: header-args:sh :tangle no
#+PROPERTY: header-args:emacs-lisp :tangle yes
#+PROPERTY: header-args :results none :eval no-export :comments no mkdirp yes
#+OPTIONS: num:nil toc:nil todo:nil tasks:nil tags:nil date:nil
#+OPTIONS: skip:nil author:nil email:nil creator:nil timestamp:nil
#+INFOJS_OPT: view:nil toc:nil ltoc:t mouse:underline buttons:0 path:http://orgmode.org/org-info.js