Skip to content
Create a gist now

Instantly share code, notes, and snippets.

Embed URL


Subversion checkout URL

You can clone with
Download ZIP

Polymorphism in Scheme via compile time dispatch

Here's an example of polymorphism in C++:

int nth ( int a[] , int i ) { return a[i] ; }

double nth ( double a[] , int i ) { return a[i] ; }

One way to think of this is that there are two functions called nth. One can be called with an int array and the other can be called with a double array. The function that is called is determined at compile time by looking at the type of the expression of the first argument.

Scheme doesn't have such a facility built into it by default. One problem is that variables and expressions aren't usually typed and so it's hard to perform a dispatch based on type at compile time.

Chez Scheme has support for associating arbitrary data with identifiers. So in theory, it's possible to achieve something like C++'s compile time polymorphism.

Let's make a Scheme version of nth which works with vectors or strings:

(define-syntax nth
  (lambda (stx)
    (lambda (lookup)
      (syntax-case stx ()
        ( (nth seq i)
          (let ((seq-type (lookup #'seq #'type)))
            (cond ( (eq? seq-type 'vector)
                    (syntax (vector-ref seq i)) )
                  ( (eq? seq-type 'string)
                    (syntax (string-ref seq i)) )))) ))))

Now let's test it out. Define abc to be a vector:

> (define abc '#(a b c))

Declare it to be of type vector:

> (define-property abc type 'vector)

Call nth on abc:

> (nth abc 0)

Let's try calling nth on variables which are inside a let:

> (let ((a '#(1 2 3))
        (b "123"))
    (define-property a type 'vector)
    (define-property b type 'string)
    (list (nth a 0)
          (nth b 0)))
(1 #\1)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.