The Little Schemer
Many little exercises with little test suites written in racket.
||A string of characters (not containing parenthesis or starting with numerics)|
||A series of S expressions separated by spaces enclosed in parenthesis|
||A series of numeric characters (excluding floating point numbers)|
||Any of the above|
||A list containing no lists as children|
||A list containing only numbers|
||A 3 item list, the 1st and 3rd entries are also
||A list of atoms containing no duplicates|
||A list of length 2|
||A set of pairs|
||A relation where the first element of each pair forms a set|
||A lambda which compares two s expressions for equality|
||A S expression representing a computation|
Sometimes we write functions with parameters that take multiple types, there are some conventions for these types.
|Paramter naming convention||Implicit types|
*-lambdas: Recurse over a list.
multi-lambdas: Recurse over a list performing an action multiple times.
&co-lambdas: Recurse over a list performing the collector lambda each time.
Total vs Partial
(Relevant from chapter 9 onwards)
Total functions are guaranteed to terminate however partial functions may not
terminate. Total functions are referred to as
natural and partial as
We assume the existence of the following functions:
We write a lot of functions using the primitive functions we've been given.
(eq? a1 a2)- Checks equality of non-numeric atoms. (builtin)
(eqan? a1 a2)- Checks equality of atoms and numbers.
(eqlist? l1 l2)- Checks equality of two lists.
(equal? s1 s2)- Checks equality of two S-expressions. (builtin)
(rember* a l)
(occur* a l)
(insertR* new old l)
(insertL* new old l)
(subst* new old l)
(member* a l)
(eqlist? l1 l2)
(member? a lat)
(rember a lat)
(insertR new old lat)
(insertL new old lat)
(subst new old lat)
(subst2 new o1 o2 lat)
(multirember new old lat)
(multiinsertR new old lat)
(multiinsertL new old lat)
(multisubst new old lat)
(pick n lat)
(rempick n lat)
(occur a lat)
(multiinsertLR new oldL oldR lat)
(looking a lat)
(keep-looking a sorn lat)
(+ n m)
(- n m)
(× n m)(note this is a unicode multiplication sign and not the letter x)
(> n m)
(< n m)
(= n m)
(↑ n m)
(÷ n m)
(tup+ tup1 tup2)
(subset? set1 set2)
(eqset? set1 set2)
(intersect? set1 set2)
(intersect set1 set2)
(union set1 set2)
(build s1 s2)
Where a function returns a function, I have noted the parameters of the
returned function after a
-> followed by a
_ to represent the anonymous
(rember-f test?) -> (_ a l)
(eq-c? a) -> (_ x)
(insertL-f test?) -> (_ new old l)
(insertR-f test?) -> (_ new old l)
(insert-g seq) -> (_ new old l)
(multirember&co a lat col)
(a-friend x y)
(new-friend x y)
(latest-friend x y)
(last-friend x y)
(multiinsertLR&co new oldL oldR lat col)
(evens-only*&co l col)
Tables are composed of entries which are pairs of lists (of the same length), the first list is names, the second is values thus representing the binding of names to values.
Lookup lambdas take a
-f lambda that runs in the case the
not found in the entry/table. The lambda is passed the
name that was
(new-entry names values)
(look-up-in-entry name entry entry-f)
(extend-table entry table)
(look-in-table name table)
e stands for expression.
(meaning e table)
(*const e table)
(*quote e table)
(*identifier e table)
(*lambda e table)
(*cond e table)
(*application e table)
(evcon lines table)
(evlis args table)
(apply-primitive name vals)
(apply-closure closure vals)
(apply fun vals)
- Fork the repository.
- Add function(s) with associated test suite(s).
- Run tests with
- Add an entry to the README with the function, it's signature and purpose. Hyperlink the function name to the source of the function.
- Commit with a description of the function added.
- Rebase onto the main branch.