Tuesday, May 12, 2009

DrScheme as Programmer's Scratchpad

These days, more and more, I find myself using DrScheme and it's underlying Scheme implementation PLT-Scheme, as the scratchpad of choice for capturing ideas. Consider these uses from today:

  • As glorified calculator - In this case, I needed to convert between Kbs and Gigs. I'm always forgetting a zero or something. Some trivial code like below is all it took to solve this one, once and for all.
    (define (kb->gigs n)
      (/ (/ n 1024) 1024))
  • As testing tool - I'm trying to optimize a website and I couldn't figure out why the GZip encoding wasn't being turned on for content. Rather than make do with wget and manually setting headers, I wrote up a quick function to test it out:
    (define (web-head url [headers '()])
      (let  ([lines (port->lines 
                     (get-impure-port (string->url url)
                                      (cons (format "User-Agent: ~a" (user-agent)) headers)))])
        (take-while (lambda (l)
                      (not (equal? l ""))) 
    (define (web-compression-test url)
      (web-grep "Content-Encoding" url '("Accept-Encoding: gzip, deflate")))
    ;; To test, run:
    ;; (web-compression-test "http://someurl.com")
  • As Learning Lab - one of my clients has given me a Microsoft Exchange server account. I was curious how I could access it using IMAP. A few minutes of goofing around and I had the following test function to show me when new mail arrived:
    (define (imap-check host username password folder)
      (let-values ([(conn all-messages new-messages) (imap-connect host username password folder)])
        (for/list ([entry (imap-get-messages conn (seq all-messages) '(uid header))])
          (cons (first entry) (cdr (assoc #"Subject" (extract-all-fields (second entry))))))))
    (imap-check "some.server.com" "myusername" "mypassword" "Inbox")

I'm finding that this scratchpad code tends to go from basic calculation, to capturing the knowledge as a procedure, to the creation of a prototype system.

While any programming environment that offers an interactive REPL would do for the above work, I find DrScheme especially well suited for this. Consider:

  • Having modules means that you can create a file and give whatever names you want without worry that they'll be clashes later on. Go ahead, name some functions foo and bar. And if at any point the file actually becomes useful, you can always choose to export just the public names you want to share.
  • PLT-Scheme has a large library of code to choose from. Whether it's utility functions like taking n items from a list or libraries like POP3 support, chances are, the base for what you have in mind is already there. Many of the the functions are relatively high level too. For example, compare the unix wget command to the code for grabbing the contents of a URL:

      # Unix
      wget http://www.foobar.com/
      ;; scheme
      (port->string (get-pure-port (string->url "http://www.foobar.com")))
  • The help system is excellent. I find it especially easy to search around to find just the function I'm looking for. The help system also works offline too, which means that you can keep banging out code even without a net connection.
  • The system is cross platform. Back in the day, most of what I write now as Scheme code would probably have been written as shell scripts. Even though I've got Cygwin on Windows, I still find that Shell scripting can be clunky. Writing code in DrScheme insulates me from that.
  • The integration with the REPL is well designed. Often I'm using DrScheme as little more than a shell, and the REPL does its thing well. I especially like the command history that survives shutdowns of DrScheme.

More important than any language though, is that I find myself asking - how can I capture this information in a way that can be turned into a procedure. Once you've got something as a procedure, you've got a clear and unambiguous description of it. Now that's power. Even if only a small amount of my scratchpad code is ever referred to again, it's still paying dividends.

So, what tool are you using these days to capture information? Do you have a preferred environment?


  1. I do the same thing as you now.

    If you have some stuff worth keeping, you might want to document it with the scribble/srcdoc module.

  2. Thanks for the tip Grant.

    Scribble is an impressive tool in its own right.


  3. It isn't just Scribble alone that I like, scribble/srcdoc lets you write documentation for the function, and contracts, directly in the code ala Javadoc.

    It is really nice for code that you will keep around for a while where you want to keep nice documentation.