Search code examples
emacsracketsicpmit-schemegeiser

SICP: Evaluate Racket into REPL with Emacs and Geiser


Working through SICP using Emacs, Geiser, and MIT Scheme, I decided to switch over to Racket in order to properly do the exercises in section 2.2.4 involving the Picture Language.

Configuration

I got a setup together that works for MIT Scheme and Racket using the following ~/.emacs configuration:

(require 'package)
(add-to-list 'package-archives
         '("melpa" . "https://melpa.org/packages/"))
(package-initialize)

(setq geiser-mit-binary "/usr/bin/scheme")
(setq geiser-racket-binary "/usr/bin/racket")
(setq geiser-active-implementations '(mit racket))
(add-to-list 'auto-mode-alist '("\\.rkt\\'" . geiser-mode))

Workflow with MIT Scheme

Here's my workflow for working with MIT Scheme:

First, I open a file (fib.scm) using emacs fib.scm. I'm asked to pick the Scheme implementation, which I answer with mit.

Second, I write my fib function, press C-c C-z to open a REPL.

Third, I switch back to the code buffer with C-x o and evaluate it using C-c C-b.

Fourth, I switch to the REPL buffer with C-x o and evaluate some expressions.

This it how it looks like:

MIT Scheme with Geiser in Emacs

Workflow with Racket

Here's my (intended) workflow for working with the SICP language of Racket:

First, I open a file (fib.rkt) using emacs fib.rkt. Interestingly, I'm not asked to pick a Scheme implementation.

Second, I write my fib function, but use #lang sicp in the first line. Then I open the REPL using C-c C-z.

Third, I switch back to the code buffer with C-x o and evaluate it using C-c C-b, which gives no error message, but prints => #<void> at the very bottom.

Fourth, I switch back to the REPL buffer with C-x o, where I fail to evaluate an expression like (fib 3):

  2 racket@> (fib 3)                                                                       
  3 fib: undefined;                                                                        
  4  cannot reference an identifier before its definition                                  
  5   in module: top-level                                                                 
  6   context...:                                                                          
  7    body of top-level                                                                   
  8    /usr/share/racket/collects/racket/repl.rkt:11:26

This it how it looks like:

Racket with Geiser in Emacs

What am I doing wrong? Is it the configuration, is it the way I use it?

Example with sicp-pict

When I run the following code using the Racket workflow from above, the picture of Einstein is properly displayed:

#lang sicp
(#%require sicp-pict)
(paint einstein)

So my setup is not entirely broken…

Addendum

Having re-installed the geiser-racket package, I'm now able to start a REPL. I'm also able to evaluate the entire buffer using C-c C-b, which prints => #<void> to the bottom of the screen.

However, when I try to actually invoke a function, I get this error:

  1 Welcome to Racket v8.6 [cs].                                                                          
  2 racket@> (fib 3)                                                                                      
  3 +: contract violation                                                                                 
  4   expected: number?                                                                                   
  5   given: #<procedure:fib>                                                                             
  6   context...:                                                                                         
  7    /usr/share/racket/collects/racket/private/norm-define.rkt:52:83: body of top-level                 
  8    /usr/share/racket/collects/racket/repl.rkt:11:26

The error in the Racket REPL

Edit: Oh dear, it was a simple syntax error... my bad! Everything is fine now!

working fib implementation


Solution

  • To finish things up, I just post the steps I have taken to get everything to run:

    Use melpa instaed of melpa-stable (~/emacs):

    (require 'package)
    (add-to-list 'package-archives
             '("melpa" . "https://melpa.org/packages/"))
    (package-initialize)
    

    Refresh the packages after re-opening Emacs:

    M-x package-refresh-contents
    

    Install racket-mode:

    M-x package-install RET racket-mode
    

    Install the package geiser-racket:

    M-x package-install RET geiser-racket
    

    Extend your Geiser config (~/emacs):

    (setq geiser-mit-binary "/usr/bin/scheme")
    (setq geiser-racket-binary "/usr/bin/racket")
    (setq geiser-active-implementations '(mit racket))
    

    Start using the picture language:

    #lang sicp
    (#%require sicp-pict)
    (paint einstein)
    

    Open it in Emacs:

    emacs ../examples/einstein.rkt
    

    Start a Racket REPL and evaluate the whole buffer:

    C-c C-z
    C-x o
    C-c C-b
    

    An image of Einstein should appear.