[racket] iterative lazy space-safe or not?
From: Eli Barzilay <eli at barzilay.org>
> > > Most of the hit is due to doing the right thing wrt exceptions:
> > > when there's an exception when a promise is forced, the exception
> > > is stored as the "value" and will be re-raised when forced again.
> >
> > Yes. I believe this is right thing to do and I think (or want to
> > think) that other languages, OCaml, Scala, F# or whatever, do the
> > same. (I'll have to check myself...)
>
> I'll be interested in what you'd find out.
I'll get back to you about it.
> > But the penalty is incurred only when an exception is raised during
> > the initialization; am I correct? I.e, if the initialization is
> > successful, no cost is incurred due to this.
>
> It's when the promise is forced (the important part).
Hmm... I did not know installing exception handlers costs.
But at any rate, I do not think I'll be willing to give up this semantics
of memorizing exceptional behavior.
> > Will you explain how/why it is fragile? It looks conceptually
> > simple.
>
> Well, there were several problems that lead to memory leaks, which
> means that it's hard to know about them, and it's hard to catch them
> (I often resort to debugging with a process monitor). The code itself
> has a number of subtle details that are important and easy to mess.
It's well-thought-out rather than fragile, I would say :)
Simplicity never means easy for me.
> > You rewrite
> >
> > let rec x = y, y = M in E[x]
> >
> > into
> >
> > let rec x = M, y = x in E[x]
> >
> > The two graphs must be extensionally equivalent.
>
> (The racket code is not doing any rewrites, so I don't see how that's
> related.)
I thought this is roughly what the implementation does:
In the first term x points to y and y points to M,
in the second, x points to M and y points to x.
(You kind of swap the pointers;
so if y is not free in M nor E[x], it can be garbage-collected immediately.)
Keiko