Archive for October, 2006

Portable Scheme

One thing about moving from one scheme implementation to another is that useful functions that were available in the old one are not available or work differently to the new one. For example, in chicken:

(let ((n 1))
  (print "n is [" n "]"))


n is [1]

In mzscheme it prints

print: expects 1 to 2 arguments, given 3: "n is [" 1 "]"

The obvious solution to this is to write a function that performs the appropriate action on all schemes. This can be a simple wrapper on a scheme that provides the function natively. I’ve had to do this before when writing software in C++ that needed to be portable between different OSes but I somehow didn’t expect it with scheme. Probably my experience with the single implementation language, Perl has spoiled me here. Anyway, despite the fact that I haven’t written much scheme, I’m starting to build a small library with these little utility functions. As long as I code to the library, it should make my scheme easier to port to different versions.

(define (chop line)
  (substring line 0 (- (string-length line) 1)))

(define (print-ln . args)
  (for-each display args)

(define (read-lines-from-port p)
  (let ((lines '()))
    (let while ()
      (let ((line (read-line p)))
        (unless (eof-object? line)
          (set! lines (cons line lines))
    (reverse lines)))

(define (read-lines file)
  (let* ((p (open-input-file file))
         (lines (read-lines-from-port p)))
    (close-input-port p)

The next thing to do, is to work out how to put this in a probably mzscheme module so I can simply require it from my scripts. I can’t imagine it will be too difficult.


Read Full Post »