[plt-scheme] `shared' syntax confusing
Hi,
Matthew Flatt <mflatt at cs.utah.edu> writes:
> 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.
I'm not quite sure what you mean by that. The approach in
general allows any computation. The implementation I posted
didn't have the letrec* semantics that shared has, but the
following simplified version does, and catches some trivial
cases of exposed placeholders:
(define-syntax shared-build
(syntax-rules ()
((shared-build ((vars t1s t2s exprs) ...) ((var expr) rest ...) body ...)
(shared-build
((vars t1s t2s exprs) ... (var t1 t2 expr)) (rest ...) body ...))
((shared-build ((var t1 t2 expr) ...) () body ...)
(let ((undef (letrec ((x x)) x)))
(let ((t1 (make-placeholder undef)) ...)
(let ((var t1) ...)
(let ((t2 undef) ...)
(begin
(set! t2 expr)
(set! var t2)
(placeholder-set! t1 var))
...
(set! var (if (eq? var t1) undef (make-reader-graph var))) ...
body ...)))))))
It's also portable R[56]RS, given suitable implementations
of placeholders and `make-reader-graph'.
> But it exposes the intermediate placeholder value [...]
> Also, it doesn't take advantage of the ability to mutate some values,
> such as vectors [...]
> or mutable structs
These are limitations in `make-reader-graph' that I was
unaware of. One could write a version of that procedure
which did traverse and replace all placeholder values,
including inside mutable structures. Alternately you could
use a post-processor to patch these in.
> 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.)
This is not true. My implementation allows
(shared ((a (append (list 1 2 a 3) a))) a)
Both implementations give an error for
(shared ((a (append a a))) a)
which is unavoidable because this has no meaningful semantics.
--
Alex