Conference: Week 1

Table Of Contents

Garbage Collection

Lisp!

1. Warmups

Self Check Questions from HW1 – all good? Questions?

2. Remove

Write a function my-remove that takes an atom and a list as input, and returns that list with all elements equal to the input atom removed, if any.

* (my-remove 'b '(a b c b d))
(a c d)
* (my-remove 'b '(a c d e f))
(a c d e f)
* (my-remove 'a '(b (a d) a d))
(b (a d) d)
* (my-remove 'a nil)
nil

Don’t use the built-in remove function!

3. Dictionary

For this question, you will implement a simple dictionary structure. We’ll represent a dictionary (or table) as a list of key-value pairs, where each pair is a list of the form (key value). For example, the table ((A 1) (B 2) (C 3) (D 4)) maps A to 1, B to 2, etc.

We’ll start with a few functions to build key-value pairs and then extract their constituent pieces:

;; build a pair from a key k and value v.
(defun pair  (k v)  (cons k (cons v nil)))

;; accessors for the key and value components of a pair (key value).
(defun key   (pair) (car pair))
(defun value (pair) (car (cdr pair)))

Here are some examples of these functions:

* (pair 'A 3)
(A 3)
* (defvar p (pair 'A 3))
P
* (key p)
A
* (value p)
3
  1. Using the definitions above, write a function table-keys that returns all of the keys associated with values in a table, and also a function table-values that returns all of the values stored in the table. These should each be single-line functions.

    ;; All keys in the table
    (defun table-keys (table) ... )
    
    ;; All values in the table
    (defun table-values (table) ... )

    Here are some examples of their use:

    * (defvar table '((A 1) (B 2) (C 3) (D 4)))
    table
    * (table-keys table)
    (A B C D)
    * (table-values table)
    (1 2 3 4)
  2. Implement table-put to add a new key-value pair to the table, and a function table-get that looks up the value associated with a given key:

    ;; Produce a new table that is the result of adding 
    ;; the key-value pair to the given table.
    (defun table-put (key value table) ...)
    
    ;; The value associated with the given key,
    ;; or nil if key is not present.
    (defun table-get (key table) ... )

    Examples:

    * (defvar table '((A 1) (B 2) (C 3) (D 4)))
    table
    * (table-get 'C table)
    3
    * (table-get 'E table)
    nil
    * (table-put 'E 5 table)
    ((E 5) (A 1) (B 2) (C 3) (D 4))

    If you add a new key-value pair for a key that already exists in the table, do not worry about deleting it. Instead, the new entry for the key “shadows” the old entry, meaning that the old entry is still there but will never be used again:

    * (defvar table '((A 1) (B 2) (C 3) (D 4)))
    table
    * (defvar table2 (table-put 'D 10 table))
    table2     ;; == ((D 10) (A 1) (B 2) (C 3) (D 4))
    * (table-get 'D table2)
    10

4. [Extra] Table History

Write a function table-history that, given a key and a table, returns a list of all values ever associated with that key, ordered from newest to oldest.

Using table2 from problem 3:

* (table-history 'A table2)
(1)
* (table-history 'D table2)
(10 4)

5. [Extra] Recursive Remove

Write a function my-recursive-remove that takes an atom and a list as input, and returns that list with all occurrences of the input atom removed, if any, including those nested inside lists:

* (my-recursive-remove 'a '(a b c d))
(b c d)
* (my-recursive-remove 'a '((a b) a (c d e a) (a a) b))
((b) (c d e) nil b))
* (my-recursive-remove 'a '((((a)))))
(((nil)))