[plt-scheme] `shared' syntax confusing
At Tue, 11 Nov 2008 02:24:20 +0900, Alex Shinn wrote:
> What about post-processing the values instead of predicting
> the shape? The following seems to work fine for me:
>
> (define-syntax shared
> (syntax-rules ()
> ((shared ((var expr) ...) body ...)
> (shared-build () ((var expr) ...) body ...))))
>
> (define-syntax shared-build
> (syntax-rules ()
> ((shared-build ((var tmp expr) ...) ((var2 expr2) rest ...) body ...)
> (shared-build ((var tmp expr) ... (var2 tmp2 expr2)) (rest ...) body
> ...))
> ((shared-build ((var tmp expr) ...) () body ...)
> (let ((tmp (make-placeholder #f)) ...)
> (let ((var #f) ...)
> (set! var (let-syntax
> ((var (make-set!-transformer
> (lambda (stx)
> (syntax-case stx (set!)
> ((set! id val) #'(set! id val))
> (id #'tmp)))))
> ...)
> expr)) ...
> (placeholder-set! tmp var) ...
> (set! var (make-reader-graph var)) ...
> body ...)))))
There are trade-offs in what you can express with this approach and the
one we're using.
Your approach would automatically work with `list*' --- or with any
function that does not inspect its arguments and constructs a result
using only pairs, vectors, and boxes.
But it exposes the intermediate placeholder value, as in
(define-struct a (x))
(shared ([a (make-a a)])
(a-x a))
Also, it doesn't take advantage of the ability to mutate some values,
such as vectors, as in
(shared ([a (vector (make-a a))])
a)
or mutable structs, as in
(define-struct b (x) #:mutable)
(shared ([b (make-b b)])
(b-x b))
I can't say whether either of these drawbacks is actually a significant
problem. The `shared' in `scheme/base' is designed to produce
`#<undefined>', though, where it might otherwise have to expose
placeholders (to avoid expose implementation details), and it works
with examples that exploit mutation (mainly to preserve compatibility
with the pre-4.0 `shared', which always used mutation).
In any case, I've added `list*' and `append' support to `shared' in
`scheme/base'. (For both of our approaches, `append' works only with
graph references within its final argument.)
Matthew