[plt-scheme] Units and macros

From: Jens Axel Soegaard (jensaxel at soegaard.net)
Date: Sun Dec 7 17:49:23 EST 2008

Hi all,

Below the macro with-ring doesn't give the result I want.
The macros with-ring-ver2 and with-ring-ver3 give the
correct result, but are actually correct?

/Jens Axel


#lang scheme

(provide ring^)

(define-signature ring^
  (member?
   inj
   zero
   zero?
   one
   one?
   +
   *
   =))

(require (prefix-in mz: scheme))

(define (make-Zn@ n)
  (unit
    (import)
    (export ring^)    
    (define member? integer?)
    (define (inj z)
      (unless (integer? z) (error))
      (modulo z n))
    (define zero 0)
    (define (zero? o) (and (integer? o) (mz:= o 0)))
    (define one 1)
    (define (one? o) (and (integer? o) (mz:= o 1)))
    (define (+ a b) (modulo (mz:+ a b) n))
    (define (* a b) (modulo (mz:* a b) n))
    (define = mz:=)))


(define Z5@ (make-Zn@ 5))
(let ()
  (define-values/invoke-unit Z5@
    (import)
    (export ring^))
  (+ 5 2))  ; => 2


(define-syntax (with-ring stx)
  (syntax-case stx ()
    [(_ ring-unit expr ...)
     #'(let ()
         (define-values/invoke-unit ring-unit
           (import) (export ring^))
         expr ...)]))


(with-ring Z5@
  (+ 5 2))  ;=> 7
;            but expected 2

(define-syntax (with-ring-ver2 stx)
  (syntax-case stx ()
    [(_ ring-unit expr ...)
     #`(let ()
         #,(syntax-local-introduce
            #'(define-values/invoke-unit ring-unit
                (import) (export ring^)))
         expr ...)]))

(with-ring-ver2 Z5@
  (+ 5 2))  ;=> 0 as expected


(define-syntax (with-ring-ver3 stx)
  (syntax-case stx ()
    [(_ ring-unit expr ...)
     #`(let ()
         (define-values/invoke-unit ring-unit
           (import) (export ring^))
         #,@(syntax-local-introduce
             #'(expr ...)))]))

(with-ring-ver3 Z5@
  (+ 5 2))  ;=> 0 as expected



Posted on the users mailing list.