Solution to ex­er­cise 1.3 of Lisp in Small Pieces

Created: Sun Jan 6 15:34:18 CET 2019

Last mod­i­fied: Sun Feb 3 03:59:38 CET 2019


My lisp book­shelf just got up­graded with the ar­rival of Lisp in Small Pieces as of Christmas 2018.

Lisp Bookshelf

(Yes I posted this on Lainchan a while ago.)

I’m cur­rently do­ing the ex­er­cises of chap­ter 1. Learning the whole code listings was­n’t so hard as I ini­tially ex­pected; af­ter a while you instinctively re­mem­ber the func­tions you need and their sig­na­tures.

So, back on topic,

Given the fol­low­ing de­f­i­n­i­tion of extend, we were to re­de­fine both lookup and update!.

(define (extend names values env)
  (cons (cons names values) env))

The mech­a­nism that ver­i­fies if both names and values have the same length is thus moved in lookup.

Note that we added a new (optional) ar­gu­ment to lookup so that it may act like update!. Because of this, our de­f­i­n­i­tion of update! is dramatically sim­pli­fied.

(define (lookup name env . set?)
  (define (lookup-b names values)
    (if (pair? names)
        (if (pair? values)
            (if (eq? (car names) name)
                (if (null? set?)
                    (car values)
                    (begin
                      (set-car! values (car set?))
                      (car values)))
                (lookup-b (cdr names) (cdr values)))
            (error 'lookup "Not enough values" values))
        (if (pair? values)
            (error 'lookup "Too much values" values)
            #f)))
  (if (pair? env)
      (let ((x (lookup-b (caar env) (cdar env))))
        (or x (lookup name (cdr env))))
      (error 'lookup "No such binding" name)))

(define (update! name new-value env)
  (lookup name env new-value))

Seeing it in ac­tion

(You’ll have to email me an SSH pub­key to get git-clone ac­cess to my repos­i­to­ries.)


git clone 'git@104.248.92.108:lisp-in-small-pieces'
cd 'lisp-in-small-pieces/chapter1'
petite # or chezscheme9.5
# > (load "evaluate.scm")
# > (load "environment_1-3.scm")
# > (evaluate '(+ 1 2) (extend '(- + *) (list - + *) env.initial))
# 3
# > (exit)

source code