Clementson's Blog

Bits and pieces (mostly Lisp-related) that I collect from the ether.

November 2003
Sun Mon Tue Wed Thu Fri Sat
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30
Oct  Dec

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:

Being more accustomed to Common Lisp, getting used to Scheme requires a number of mindset changes and I'll probably document some of these in this weblog as I progress with the language.

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:
  1. Start up a bash shell in Emacs (I use Windows with the Cygwin utilities)
  2. cd to the PLT collects directory
  3. Run: find . -name '*.s*' -exec etags -a --language=scheme --regex="/[ t]*(def[a-z-]+[ t]+(.*)/1/" {} ;
  4. 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.

emacs Copyright © 2004 by Bill Clementson