Spritely Institute publishes a Scheme Primer

-- Wed 06 July 2022

We are pleased to announce that we have published a new Scheme Primer! (PDF) (source) We primarily wrote this for the benefit of people approaching Spritely's technology who were unfamiliar with Scheme, but since the lack of a good Scheme introductory document is a common complaint, we hope this is a useful contribution in general and a gift to the wider programming language community.

The primer is about 28 pages of printed paper and can be read at different levels of depth. A quick read, skimming over the explanatory sections, can be enough to give the experienced programmer just enough information to get to programming quickly. For example, since Guile is known for having a truly excellent reference manual but lacks a more hand-holding tutorial, we hope this document will fill such a gap.

A more careful read could take a full afternoon or day, but will unveil many deeper aspects of computer science theory. Although considerably shorter, A Scheme Primer draws on, but highly compresses, material from other well loved sources of programming literature such as Structure and Interpretation of Computer Programs (a good web rendering here and) and The Little Schemer. In that tradition, A Scheme Primer ends with a flourish: an implementation of Scheme in Scheme written in a mere 30 lines of code:

(define (env-lookup env name)
  (match (assoc name env)
    ((_key . val)
     val)
    (_
     (error "Variable unbound:" name))))

(define (extend-env env names vals)
  (if (eq? names '())
      env
      (cons (cons (car names) (car vals))
            (extend-env env (cdr names) (cdr vals)))))

(define (evaluate expr env)
  (match expr
    ;; Support builtin types
    ((or #t #f (? number?))
     expr)
    ;; Quoting
    (('quote quoted-expr)
     quoted-expr)
    ;; Variable lookup
    ((? symbol? name)
     (env-lookup env name))
    ;; Conditionals
    (('if test consequent alternate)
     (if (evaluate test env)
         (evaluate consequent env)
         (evaluate alternate env)))
    ;; Lambdas (Procedures)
    (('lambda (args ...) body)
     (lambda (. vals)
       (evaluate body (extend-env env args vals))))
    ;; Procedure Invocation (Application)
    ((proc-expr arg-exprs ...)
     (apply (evaluate proc-expr env)
            (map (lambda (arg-expr)
                   (evaluate arg-expr env))
                 arg-exprs)))))

How does it work? Every line of the above is explained in the primer, so you'll just have to read to find out!

We hope you enjoy reading this document! You can submit feedback as issues to the source repository or by emailing christine@spritely.institute.

Happy scheming!