XS: possible to have side effects?

Subject: XS: possible to have side effects?
From: James Clark <jjc@xxxxxxxxxx>
Date: Sat, 07 Jun 1997 10:26:09 +0700
I have been giving some thought to the issue of whether it would be
technically possible to allow restricted use of some of the non side-effect
free parts of R4RS vectors, side-effectfull operations on lists and strings,
set!, begin etc) in the DSSSL expression language without compromising the
implementability of DSSSL.

At the moment I'm focused purely on the issue of whether it is possible to
come up with a clean set of restictions.  If it is, then we can move on to
look at the issue of whether this is a good thing.  If it's not, then
there's no need to waste time discussing this.

"Clean" to me means:

- there's a coherent, non-arbitrary and easily understandable set of
restrictions

- the restrictions should be as unrestrictive as possible, and they must
sufficiently unrestrictive to be useful

- they must be enforceable by an implementation

I think I may have a workable approach to this.

The fundamental idea is that expression language objects of types that can
be mutated (strings, lists and vectors) have a dynamic read-only attribute,
just as they now have a dynamic type (the PostScript language has a similar
idea).  Mutating a read-only object is an error.  Certain objects will be
marked as read-only.  When an object is marked as read-only, the read-only
attribute of that object and all objects reachable from that object is set.
An object will be automatically marked as read-only when:

- it is bound to a top-level variable,

- it is used as an inherited characteristic value, or

- it is captured by an expression specifying a characteristic value; eg in
the following it would be an error if foo modified x:

  (let ((x (vector 1 2 3))
    (make paragraph
      font-size: (foo x)))

set! would be allowed but not on top-level variables.

I believe this is sufficient to ensure that (process-children)  and
(process-node-list) are guaranteed side-effect free.  This is because the
only outside objects that are accessible to a construction rules are
top-level variables and inherited characteristic values.

Provided (process-children) is guaranteed side-effect free, I think
implementability will not be overly compromised, and, in particular,
progressive display will still be possible: I believe the implementation
technique used in Jade (which allows progressive display) will work.

In some cases an implementation will be prevented from doing an operation
lazily which it can now do lazily unless it can prove that a procedure is
side-effect free: for example, node-list-map, map-constructor.  But provided
only that an implementation can identify any spec that is completely
side-effect free, which is very easy to do, no current spec need suffer
reduced performance.

Can anybody see a flaw in this?  (Please let's focus for the moment on the
narrow issue of whether this approach would work and whether there's a
better set of restrictions, rather than whether this is desirable, which I
think is bound up with the broader issue of alternative syntaxes.)

James








 DSSSList info and archive:  http://www.mulberrytech.com/dsssl/dssslist


Current Thread