Re: XS: possible to have side effects?

Subject: Re: XS: possible to have side effects?
From: James Clark <jjc@xxxxxxxxxx>
Date: Sun, 08 Jun 1997 04:56:00 +0700
At 12:10 07/06/97 -0400, you wrote:
>Capturing:
>==========
>James Clark wrote:
>> - it is captured by an expression specifying a characteristic value; eg in
>> the following it would be an error if foo modified x:
>
>So that I understand the proposal more fully, could you please describe
>the difference between "captured by" and "used in"? 

By "captured by" I just mean "free in", ie a variable that is used inside a
characteristic expression but bound outside it.

(let ((x (whatever))
  (make foo
    bar: (let ((y (whatever))
            (baz x y))))

x is free in the characteristic expression, but y isn't, so baz can mutate y
but not x.  This restriction is needed because the semantics of
characteristic expressions are very like:

(let ((x (whatever))
  (make foo
    bar: (lambda ()
           (let ((y (whatever))
            (baz x y)))))

with the closure getting evaluated at a later, unspecified point when the
flow object tree is built.  Just as with a closure, the values of the free
variables are saved when the make expression is evaluated.
 
>Vectors:
>========
>Your mail seemed to imply that you are considering adding vectors to
>DSSSL. I'm not quite sure I understand the relationship between vectors
>and mutability. Why didn't ISO DSSSL have them and why would we consider
>them for an XS with side effects?

I didn't think vectors were very useful without vector-set!.  With
side-effects we can allow vector-set!, so they start being useful.

>Lazy Evaluation:
>================
>> 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.
>
>But how large is the effort required to provide two complete
>implementations of node-list-map and map-constructor? I don't see these
>two procedures as critical, but I do want to know what the actual
>likelihood of having lazy implementations of these are if side-effects
>were permitted.

Actually I now see a better solution to this.

My proposal involves adding a primitive operation to the language which is
to make an object and all objects reachable from that object read-only.  Now
when that operation is applied to a closure it must make read-only the
values saved for all the free variables in the closure (needed because of
something like

(define x
  (let ((v (vector 1))
    (lambda ()
      v))

).  So we can preserve the ability to keep map-constructor and
process-node-list lazy simply by specifying that they make their procedure
argument read-only.

>First-Class Modes:
>==================
>> 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.
> 
>Keep in mind our other ideas about first-class modes. In some cases the
>inability to pass information down the "construction-rule tree" is
>painful. We should think carefully before we make it difficult or
>impossible to change DSSSL in the future to allow information to be
>passed through a (process-children).

I don't think this proposal would make it impossible to introduce
first-class modes. 

Given something like this:

(let ((x (whatever))
  (call-with-mode
    (mode
      (element P (foo x)))
    process-children)))

we simple specify that evaluating the mode expression makes the values of
the free variables (x in this case) read-only.

James


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


Current Thread