[plt-scheme] `shared' syntax confusing

From: Alex Shinn (alexshinn at gmail.com)
Date: Mon Nov 10 20:57:10 EST 2008


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 ...)
        ((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) ...)
                 (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.


Posted on the users mailing list.