define-record for Gambit 
Author Message
 define-record for Gambit

  Is there code somewhere to implement define-record and variant-case on MacGambit 2.0? All of the implementations I have found use macros, which MacGambit does not support. Other than that MacGambit seems very nice, but I need variant-case.

  Is there a free/shareware Macintosh scheme which supports macros? I'm on the verge of ordering MacScheme (its only $70 for the interpreter), but is there anything else available?



Wed, 03 Jan 1996 02:50:45 GMT  
 define-record for Gambit

Quote:

>   Is there code somewhere to implement define-record and variant-case on MacGambit 2.0? All of the implementations I have found use macros, which MacGambit does not support. Other than that MacGambit seems very nice, but I need variant-case.

>   Is there a free/shareware Macintosh scheme which supports macros? I'm on the verge of ordering MacScheme (its only $70 for the interpreter), but is there anything else available?

MacGambit does have a macro facility, ##define-macro, though I'm not sure
if it performs the same way as macro definitions in other implementations.
A "readme" file on MacGambit gives the following description:

Quote:
>(##define-macro (name parm...) <body>)

>  Define the name as a macro special form which expands into `body'.
>  The scope of the declaration extends to the end of the body it is in
>  or to the end of the program if it is at toplevel.

-Jesse


Sat, 06 Jan 1996 23:37:15 GMT  
 define-record for Gambit

Quote:

>  Is there code somewhere to implement define-record and
> variant-case on MacGambit 2.0? All of the implementations
> I have found use macros, which MacGambit does not support.
> Other than that MacGambit seems very nice, but I need variant-case.

I wrote the following macros ten days ago, because several
of us here at Taligent are going through EOPL for fun.  We have
not needed to use these yet, so they are only superficially tested.

I was chagrined to learn MacGambit does not document ##define-macro
in its online help.  Instead, it is described in a text file
that accompanies the compiler sources (available by ftp).  I still
had to guess the semantics for this form.

The interesting part in the macros below is the use of eval to
evaluate definitions in the global environment, because MacGambit
does not have define-top-level-value.

;;; file macgambitmacros.scm
;;; MacGambit macros implementing records for the book:
;;;
;;; "Essentials of Programming Languages", Daniel P. Friedman,
;;;   Mitchell Wand and Christopher T. Haynes, MIT Press, 1992.
;;;
;;; (C) Copyright 1993 David McCusker

(##define-macro (define-record rec-name rec-fields)
  `(let*
    ((sym string->symbol)
     (str symbol->string)
     (cat string-append)
     (vec-len (+ 1 (length ',rec-fields)))
     (name ',rec-name)
     (name-str (str ',rec-name))
     (make-name (sym (cat (str 'make-) name-str)) )
     (name? (sym (cat name-str "?")))
     (index 0))
    (eval
      `(define ,make-name
        (lambda values (apply vector ',name values))))
    (eval
      `(define ,name?
        (lambda (obj)
          (and (vector? obj)
            (= (vector-length obj) ,vec-len)
            (eq? (vector-ref obj 0) ',name)))))
    (for-each
      (lambda (f)
        (set! index (+ index 1))
        (let* ((name->field (sym (cat name-str "->" (str f))))
          (problem (cat (str name->field) ": bad record")))
          (eval
            `(define ,name->field
              (lambda (obj)
                (if (,name? obj)
                  (vector-ref obj ,index)
                  (error ,problem obj)))))))
      ',rec-fields)
    name))

(define every?
  (letrec
    ((all?
      (lambda (proc list)
        (if (pair? list)
          (if (proc (car list))
            (all? proc (cdr list))
            #f)
          (if (null? list) #t (error "every?: not a list" list))))))
    all?))

(##define-macro (variant-case record-var . clauses)
  (let*
    ((sym string->symbol)
     (str symbol->string)
     (cat string-append)
     (exp (gensym))
     (type? (lambda (name) (list (sym (cat name "?")) exp)) )
     (good?
       (lambda (c)
         (and (pair? c)
           (or (eq? 'else (car c))
             (and (symbol? (car c))
               (pair? (cdr c))
               (list? (cadr c))
               (every? symbol? (cadr c)))))))
     (check-clause-syntax
       (lambda (c)
         (if (not (good? c))
           (error "variant-case: expected syntax (name field-list ...)"
c))))
     (make-clause
       (lambda (c)
         (let*
           ((n (str (car c)))
            (n->f (lambda (f) (list f (list (sym (cat n "->" (str f)))
exp)))))
           (if (eq? 'else (car c))
             c
             (list (type? n)
               (cons 'let (cons (map n->f (cadr c)) (cddr c)))))))))
    (for-each check-clause-syntax clauses)
    `(let ((,exp ,record-var))



Sun, 07 Jan 1996 04:30:03 GMT  
 
 [ 3 post ] 

 Relevant Pages 

1. Modulo defined over the Reals (Gambit)

2. Bindings visible in Gambit define-macro forms

3. user defined records?

4. Final SRFI 9: Defining Record Types

5. SRFI 9: Defining Record Types

6. REQ: Ways of defining constant records

7. Defining Variable Length Record

8. Variable length records (How to define/read)

9. Can TPB be defined outside defining modules?

10. shadows of define and define-syntax

11. define in define-syntax

12. define-macro -> define-syntax

 

 
Powered by phpBB® Forum Software