I'm Learning Scheme Again
Sunday, November 2, 2003
I've decided to start learning Scheme again. I had played around with it for a while a couple of summers ago when I was teaching my daughter how to program but never got seriously involved with learning the language. When teaching my daughter, I had decided to follow the text of the How to Design Programs book (a really excellent introduction to programming - ostensibly aimed at High School students but also used in some university classes). The book was written by members of the PLT Scheme team, a group of (mostly) academics who have also created the PLT Scheme family of Scheme implementations. These include DrScheme (an interactive, integrated Scheme programming environment), MzScheme (a console-based command-line version), and MrEd (a graphical UI-based command-line version).
This time around, I looked at a number of Scheme implementations but finally decided that the PLT Scheme implementations were the best ones for me to learn Scheme with. There were a number of reasons for this:
- It has an excellent learning environment in DrScheme so (although I prefer Emacs for most Lisp-related coding) I can make use of DrScheme's pedagogical features as well while learning the language
- The MzScheme implementation works well in Emacs
- It is being actively maintained and enhanced
- There appears to be a lot of 3rd party development centered around PLT Scheme
- I had already used the PLT Scheme implementations before and had found them to be robust and well-documented
My usual approach to learning a language (actually the same approach with either a computer or a natural language) is "total immersion". I try to read and understand as much as possible, experiment a bit, then re-read the bits I didn't understand previously. I read a lot of good code to try to understand the idioms in the language. Eventually, I identify a mini-project that will let me exercise what I've learned.
My first hiccup with the language was on the weekend. I was looking at some code samples and wanted to locate the definition of a function. "No problem" I thought, "I'll just use Emacs' tagging functionality". Initially, I just ran etags on some local Scheme files and was able to use their definitions without any problem. Then, I decided to tag all of the Scheme "collections" that are included as part of PLT Scheme so that I could easily jump to the source of any "built-in" functions. This is where I encountered a problem. PLT Scheme has it's own module system (roughly similar in function to CL or Java packages) and the Emacs etags utility doesn't understand about definitions that are contained in PLT Scheme modules. "No problem" I thought, "I'll just construct a custom regexp that will pick up definitions in a module". So, as Jamie Zawinski would say, I then had two problems! Actually, it wasn't too bad - I'm not a regexp expert; however, I eventually got one constructed that kinda, sorta worked. At least, it erred on the side of picking up too many definitions as I just tagged anything that had a "(def" in front of it. Admittedly, this was a bit of a "shotgun" approach and it offended my sense of aesthetics so I decided to swallow my pride and get some help from some more experienced schemers.
I posted a question to the PLT Scheme mailing list suspecting that there was a simple solution to my problem. After all, dynamic and static tagging is quite common and the concept has been around for yonks. Also, Common Lisp and Java both have introspection capabilities that many editiors will take advatage of, so I was hopeful that I wouldn't need to use a Tag-based solution at all. I was a bit surprised to find out that no standard solution existed. I got some helpful advice and one person actually had some Scheme code to generate PLT Scheme tags; however, there were no standard solutions available. In the end, I decided to just go back to using my etags-with-a-custom-regexp approach. Eventually, as I get better with Scheme, I'd like to write a dynamic Scheme definition lookup for Emacs that would traverse up the modules and requires and locate a source definition based on only those definitions that are exposed. This would be more accurate than a static tagging mechanism and would not require that any separate tag-generation process be run. Eli Barzilay posted some nice code that would probably be a good starting point for this.
Oh well, for the time being, I'll continue to use my etags-with-a-custom-regexp approach. For anyone who's interested (or who can suggest either a better regexp or an alternative approach), here's what I do:
- Start up a bash shell in Emacs (I use Windows with the Cygwin utilities)
- cd to the PLT collects directory
- Run: find . -name '*.s*' -exec etags -a --language=scheme --regex="/[ t]*(def[a-z-]+[ t]+(.*)/1/" {} ;
- End result: a TAGS file in the PLT collects directory with tags for all definitions in all collections. When I'm working with code in another directory, I just tag the files in that directory and then use both TAGS files (the project-specific one and the collects one) to find definitions. Sometimes there are duplicate definitions and I have to use Emacs' tags search capabilities to find the alternative definition.

