I am closer to finishing Simply Scheme. I have completed almost all the regular chapters.
Most of the other people who have github repos for Simply Scheme have not gotten as far as I have. It’s me, buntine, and some guy in New Zealand named MengSince1996. I might go back to the poker project in chapter 15 and finish that; then it will just be me and Meng. As soon as I get through chapter 24.
To be honest, I am not too clear that I learned a whole lot. I admit, some of the exercises were pretty hard, but overall a lot of the main concepts were not new to me. I had done a few other Scheme tutorials before Simply Scheme, and I have been working with Clojure on and off for a while, so I was already familiar with higher-order functions.
I did learn more about recursion, especially tail recursion. I tried to make all my recursive functions tail-recursive. This made them longer that the non-recursive versions, but I think it is a good practice to get into. Recursion is not a hard concept, but I still think it helps to go through exercises like, “Do this weird thing with recursion.”
There was an answer on Stack Exchange about tail recursion; someone wrote that you should prefer using higher-order functions, and go with tail recursion as a last resort. I assume this person was referring to the built-in higher-order functions, like map, reduce and filter. Simply Scheme threw a lot of things at you where the Big Three would not work (like filtering out the first instance of a predicate but leaving any others). Sometimes you just gotta recur.
Interestingly, I think that the Big Three themselves rely on recursion. I have not been able to find the Common Lisp or Racket implementations of the Big Three, but I did find a page for a course at Aalborg University in Denmark that gives source code for the Big Three: there is one page with map and filter, and another page with reduce. Chapter 19 of Simply Scheme also gives the Big Three, with some hints in Chapter 14. The definitions in Simply Scheme and on the Aalborg page are not tail-recursive. I made versions that are tail-recursive.
I did get a bit tripped up with lists. There were a few times I sent a function a pair instead of a list. (Yes, I know this could be a problem if I go forward with most Lisps; the Clojure community seems to prefer vectors over lists.) The way the Lisp family handles lists is different than any other language. I think in most languages, you add stuff to the end. In Lisps, although many Lisps have “append” functions, I think the preferred way to make lists is to use “cons” to add to the front.
It is interesting the way languages use the same word to mean different things, or different words for the same thing. An array in C, C++ or Java does not exist in Ruby (at least, not when I was using it). What Ruby calls an array is like a list in Java. Clojure lists are like Common Lisp/Scheme lists, and vectors in Lisps are like lists in Java. I should probably find a book on data structures and learn more about this stuff.
Maybe I was ready for SICP from the beginning.
Image from the Escorial Beatus, a 10th century manuscript of ‘Commentary on the Apocalypse‘, written in the 8th century by Beatus of Liébana; image from Arachne, licensed under Creative Commons License (BY-NC-ND 3.0).