[plt-scheme] Units and macros
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