Interpreter Project Boot

This is part two in my Build an Interpreter series. The project is setup now and I named it Ringo because he was the most laid-back Beatle.

I've set it up as a gem using the Bundler gem template. Very handy, that.

Progress

There is not very much to show yet. The exercises in chapter one are mostly to get the reader up to speed with recursion. I did my best to write these methods without using any standard Ruby Library code.

The exercises are mostly operations on lists, which is a data type that doesn't exist in Ruby. I used Arrays as a replacement because they are the closest kind of data set as far as I can tell.

I wound up adding a few standard Scheme primitive methods just to make the code read a little better. For example, the Scheme list-length method is defined as:

(define list-length
  (lambda (list)
    (if (null? list)
      0
      (+ 1 (list-length (cdr list))))))

The cdr method is a standard Scheme method that returns a list minus the first element. Basically, if the list is empty or null return zero, otherwise add one to the result of calling list-length on the list minus the first element.

In Ruby you can perform the same cdr operation with list.slice(1, list.size). It started to get messy having that slice code all over the place, so I created a tidy Ruby version of cdr.

def cdr(list)
  # Exception handling occluded.
  list.slice(1, list.size)
end

I also added car, and cons, so now the Ruby code reads very much like the original Scheme.

def length(list)
  return 0 if list.nil? || list.empty?
  return 1 + length(cdr(list))
end 

I made a tag in the repository for chapter one so anyone can see what the code looks like at this point.

Moving Forward

I have to say it has been interesting getting my brain wrapped around all of the recursion so far. It is one thing to generally grasp the concept of recursion, and something else entirely to sit down and try to write it.

I'm looking forward to Chapter Two which looks like it covers describing abstract data types and creating interfaces for those data types.