This page is part of the web mail archives of SRFI 53 from before July 7th, 2015. The new archives for SRFI 53 contain all messages, not just those from before July 7th, 2015.
At Tue, 23 Mar 2004 10:00:18 -0800 (PST), campbell@xxxxxxxxxxxxxxxxxxxxxxxxxxx wrote: > > > > - Very little is mentioned about hygiene, which I'm worried about. > > > - Very little is mentioned about shadowing. > > > > I'll see if I can come up with something intelligent to say about this. > > I expect the reason you're avoiding those mentions is that you're > assuming the underlying SYNTAX-RULES implementation deals with them, > but I think this is a dangerous assumption that could potentially cause > _very_ unportable code. But syntax-rules hygiene can already be broken, and computation-rules just gives you more ways to do so. What more can be said? As an example, suppose we want to implement with-slots from CLOS: (with-slots (name1 name2 ...) obj ...) where name1 is bound to (slot-ref obj 'name1) in the body of the form. For the sake of those not using a CLOS-like system we'll use the following for our examples: (define (slot-ref obj slot) (vector-ref obj (case slot ((a) 0) ((b) 1) ((c 2)) ((d 3))))) (define my-obj #(1 10 100 1000)) First we want a syntax-replace macro: (define-syntax-computation syntax-equal? (computation-rules () ((syntax-equal? (h1 . t1) (h2 . t2)) (syntax-if (syntax-equal? h1 h2) (syntax-equal? t1 t2) (syntax-return #f))) ((syntax-equal? #(h1 t1 ...) #(h2 t2 ...)) (syntax-if (syntax-equal? h1 h2) (syntax-equal? (t1 ...) (t2 ...)) (syntax-return #f))) ((syntax-equal? x y) (syntax-eq? x y)))) (define-syntax-computation syntax-list->vector (computation-rules () ((syntax-list->vector ls) (syntax-do (rev <- (syntax-reverse ls)) (syntax-list->vector rev #()))) ((syntax-list->vector () #(v1 ...)) (syntax-return #(v1 ...))) ((syntax-list->vector (h . t) #(v1 ...)) (syntax-list->vector t #(h v1 ...))) )) (define-syntax-computation syntax-replace (computation-rules () ((syntax-replace from to (h . t)) (syntax-if (syntax-equal? (h . t) from) (syntax-return to) (syntax-do (h1 <- (syntax-replace from to h)) (t1 <- (syntax-replace from to t)) (syntax-return (h1 . t1))))) ((syntax-replace from to #(h t ...)) (syntax-if (syntax-equal? #(h t ...) from) (syntax-return to) (syntax-do (h1 <- (syntax-replace from to h)) (t1 <- (syntax-replace from to (t ...))) (syntax-return (syntax-list->vector (h1 . t1)))))) ((syntax-replace from to s) (syntax-if (syntax-equal? s from) (syntax-return to) (syntax-return s))) )) Then the implementation is straightforward: (define-syntax-computation with-slots-computation (computation-rules () ((with-slots-computation () obj . body) (syntax-return (begin . body))) ((with-slots-computation (slot1 slot2 ...) obj . body) (syntax-do (inner1 <- (with-slots-computation (slot2 ...) obj . body)) (inner2 <- (syntax-replace slot1 tmp inner1)) (syntax-return (let ((tmp (slot-ref obj 'slot1))) inner2)))))) (define-syntax with-slots (syntax-rules () ((with-slots slots obj . body) (syntax-run (with-slots-computation slots obj . body))))) And our example works as expected: (syntax-inspect (with-slots-computation (a b c) my-obj (+ a b c))) => (let ((tmp (slot-ref my-obj 'a))) (let ((tmp (slot-ref my-obj 'b))) (let ((tmp (slot-ref my-obj 'c))) (begin (+ tmp tmp tmp))))) (with-slots (a b c) my-obj (+ a b c)) => 111 The nested tmp bindings don't interfere with each other as expected. If we bind tmp in the body we're safe as well: (with-slots (a b c) my-obj (let ((tmp 5)) (+ a b c))) => 111 Macros inside the body may safely expand into forms using tmp or any of the replaced symbols: (define-syntax add (syntax-rules () ((add) 0) ((add x) x) ((add x y z ...) (let ((a (+ x y))) (add a z ...))))) (with-slots (a b c) my-obj (let ((tmp 5)) (add a b c))) => 111 Also rebinding the slot names in the body works as you would expect: (with-slots (a b c) my-obj (let ((a 5)) (add a b c))) => 115 The bad news? The above computations take about 10 _minutes_ each on Petite Chez. I would not want to try this on MzScheme if it was "very slow" in comparison to Chez! -- Alex