A Minimalistic Module System for Scheme

August 30, 2008 at 7:59 pm | In scheme | 1 Comment
Tags: ,

I like scheme.

I really, really like scheme.

Unfortunately, it seems like a lot of the time the only way to get worthwhile things done in scheme is to abandon the conceptual purity and the elegance, all of the things that make scheme as wonderful as it is.

I figure I’m as good a person as any to try and fix at least a little of that.

The first (second actually, but more about that in the next post) step toward that is some sort of cross-implementation module system. As far as I know, the only such systems in existence so far are SLIB and Snowfort. While both of these are wonderful systems, they overshoot the mark, in my opinion. SLIB aims to be a complete all-singing all-dancing library system, and Snowfort integrates all kinds of package management with the simple act of breaking a program up into modules.

Well, that’s the beauty of lisp, isn’t it? If you need something, you can just code it yourself.

So I did. The preliminary result is only 19 lines of code, 6 of which are simply a function to build an alist from a key list and a value list. It can also double as a simple object system if you want to use it that way.

Its usage is simple. There are two macros, provide and module. Provide is basically the same as module, but anonymous, so it needs no documentation other than to say that you omit the name.

;;; simple-module-example.scm
;;; Show off the usage of simple-module.scm
;;; By Will Donnelly

;; This program is free software. It comes without any warranty, to
;; the extent permitted by applicable law. You can redistribute it
;; and/or modify it under the terms of the Do What The Fuck You Want
;; To Public License, Version 2, as published by Sam Hocevar. See
;; http://sam.zoy.org/wtfpl/COPYING for more details.

(load "simple-module.scm")

;; (module <name> (<exports> ...) <body> ...)
(module mod-name (foo incr)
  (define foo 37)
  (define i 10)       ; i cannot be accessed directly
  (define (incr)
    (set! i (+ i 1))
    i))
(mod-name 'foo) ; => 37
((mod-name 'incr)) ; => 11
((mod-name 'incr)) ; => 12
((mod-name 'incr)) ; => 13

That’s all you have to do to use it. The code inside the module system is about as simple as that too.

;;; simple-module.scm
;;; A minimalistic module system for scheme
;;; By Will Donnelly

;; This program is free software. It comes without any warranty, to
;; the extent permitted by applicable law. You can redistribute it
;; and/or modify it under the terms of the Do What The Fuck You Want
;; To Public License, Version 2, as published by Sam Hocevar. See
;; http://sam.zoy.org/wtfpl/COPYING for more details.

(define (make-alist names values)
  (if (equal? (length names) (length values))
      (if (> (length names) 0)
          (cons (cons (car names) (car values)) (make-alist (cdr names) (cdr values)))
          '())
      #f))

(define-syntax provide
  (syntax-rules ()
    ((_ (exports ...) body ...)
     ((lambda ()
        body ...
        (define export-alist
          (make-alist '(exports ...) (list exports ...)))
        (lambda (symbol)
          (cdr (or (assoc symbol export-alist) '(#f . #f)))))))))

(define-syntax module
  (syntax-rules ()
    ((_ name (exports ...) body ...)
     (define name (provide (exports ...) body ...)))))

Just load that code into your scheme interpreter, and you have a simple module system. That’s all there is to it.

1 Comment »

RSS feed for comments on this post. TrackBack URI

  1. Very cool post. I like that you included the code for the world to use. I’ll definitely be checking back here more often.

    Michael Schade
    http://www.lifesketchedout.com/


Leave a comment

XHTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <pre> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Blog at WordPress.com. | Theme: Pool by Borja Fernandez.
Entries and comments feeds.