Home > Scheme > Unifying define-struct

Unifying define-struct

My initial impression of Lisp in whole and Scheme in particular is that lists are used as general-purpose data structure. But sometimes it could be more convenient to access structure member by name, not just by “cddar”. Writing accessor functions manually is long and boring way. While reading HtDP I discovered “structures” – the thing I was looking for. Declaring structure automatically generates constructor and selector functions. However, structures are not portable between Scheme implementations. Compare:

Scheme implementation syntax
PLT (define-struct structname (field1 field2))
ChezScheme (define-structure (structname field1 field2))
Gambit (define structure name field1 field2)

So, writing portable code which uses structures was not possible for me.

Later I understood that “define-struct” is often mplemented using Scheme macro facility. It automatically generates code for constructor and selector functions which you otherwise whould write yourself, so it is just a “productivity feature” on top of Lisp basic primitives. But, since “define-struct” is a macro, then I also can use macros to make a common definition for “define-struct”!

I decided to use PLT syntax as common. After that I needed some macroses which will convert my common syntax to syntax which already implemented on each platform. Of course, PLT doesn’t require any special transformer. So, I’ve started to learn macro language. I can’t say I became a master, but my aim is achieved.

Here is a R5RS-style macro for ChezScheme, which works fine:

(define-syntax define-struct
  (syntax-rules ()
    ((define-struct name (fields …)) (define-structure (name fields …)))
  )
)

Unfortunatelly, my macro for Gambit is not working:

(define-syntax define-struct
  (syntax-rules ()
    ((define-struct name (fields …)) (define-structure name fields …))
  )
)

Problem with Gambit is that it doesn’t support define-syntax natively. You need to (load “syntax-case”). But then aboveshown macro is executed, it reports error which I don’t know how to fix.

Gambit also has Common Lisp-like macro facility called “define-macro”. After some time I came with following, which seems to work:

(define-macro (define-struct name fields)
  (cons ‘define-structure (cons name fields))
)

Now I have unified syntax, and can write code which will work on any of those implementations.

Advertisements
Categories: Scheme
  1. No comments yet.
  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: