hughperman / pure-lang

Automatically exported from code.google.com/p/pure-lang
0 stars 0 forks source link

Feature request: weak_refs #81

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
From mailing list:

> > If I had some structure that on the face of it calls for cyclical
> > references, but weak references were available, I could make sure that
> > the references in one direction were always weak. Then I could use my
> > cyclical structure normally, and the "cycle" would still be collectable.
> > I don't see why this is less useful just because objects are collected
> > immediately upon going out of scope.
> 
> No, this specific case should be easy to implement. Will it be good
> enough to have this work for explicit expression references ('ref')?
> Then we just need a 'weak_ref' function which works like 'ref' but
> doesn't increment the reference count of the pointee.
> 
> The only potential problem I see is that the interpreter will collect
> "temporaries" (terms with a reference count of zero) when it gets back
> to the command prompt after doing an evaluation. So a weak reference
> will only survive this if there's also a strong reference to the same
> term at this time. But I guess that this should always hold in the
> cyclic structure use case.

Yes, please could we get exactly this? Four patterns of behavior suggest 
themselves:

let r = weak_ref value;
...
// pattern 1
get r; // returns either {} or the smatrix {value} (and if value is itself a 
matrix, it's properly nested)

// pattern 2
get r; // returns either Nothing or Just value, for some new constructors (or 
ML version: None, Some value)

// pattern 3
get r; // either returns value or throws an error

// pattern 4
get r; // either returns value or stays unreduced

I think pattern 4 would be hard to use, given that value might itself sometimes 
be an unreduced
application of get.

I'd most like pattern 1. 

Original issue reported on code.google.com by dubious...@gmail.com on 20 Jun 2012 at 2:02

GoogleCodeExporter commented 8 years ago
Thinking about how to build weakdicts on top of these, I think it'd be 
efficient if a weakref had a strongly held "note" field as well as its weakly 
held "value" field. (Python implements their weakdicts this way. It saves 
creating a different sentry closure for each key,value pair in the weakdict. 
Just one generic sentry closure can be used, which makes use of the weakref's 
"note" field. Python calls this field "key".) So the signature might look like 
this:
  let r = weak_ref value note; // just set note to () if you don't want it
  get r; // returns {} or {value}
  get_note r; // always returns the original note
No put function needed or wanted.

Original comment by dubious...@gmail.com on 20 Jun 2012 at 1:30

GoogleCodeExporter commented 8 years ago
Actually, this would be better:
  let r = weak_ref value note sentry; // just use () for note if you don't want it
                                      // and use void for sentry if you don't want it
  // we ask for the sentry during construction, because we provide the following guarantee:
  let r2 = weak_ref value2 note2 sentry2;
  // now r === r2 (and they also hash the same) just in case (original) value === (original) value2 && note === note2 && sentry === sentry2
  // and we can determine that r === r2 even after value has been collected

  get r; // as before
  get_note r; // as before
  get_sentry r; // returns the sentry originally supplied

Original comment by dubious...@gmail.com on 20 Jun 2012 at 2:05

GoogleCodeExporter commented 8 years ago
Alas, I don't see how the expression references we have in the primitives 
module could be made to support any of the desired behaviours that you propose 
here.

My idea was to simply add a weak_ref function which would create a reference 
like ref, but not actually count a reference to the pointee. But that doesn't 
really work either. The idea was to use that in cyclic things like:

let x = ref ();
let y = weak_ref (2,x);
put x (1,y);

Unfortunately, the weak reference on (2,x) doesn't solve the problem, y itself 
would have to be a weak reference, and I'm afraid that this just doesn't work 
without special support from the runtime system.

Sorry, my bad. I guess we have to go back to the drawing board. The simple 
solution that I was hoping for doesn't exist.

Original comment by aggraef@gmail.com on 20 Jun 2012 at 4:34

GoogleCodeExporter commented 8 years ago

Original comment by aggraef@gmail.com on 20 Jun 2012 at 4:35

GoogleCodeExporter commented 8 years ago
I think I see how to do it with the materials already in the C API. I'll let 
you know.

Original comment by dubious...@gmail.com on 21 Jun 2012 at 8:25

GoogleCodeExporter commented 8 years ago
OK, this can be marked as closed (if you like my solution). It does need robust 
testing though.

Original comment by dubious...@gmail.com on 22 Jun 2012 at 4:23

GoogleCodeExporter commented 8 years ago
Ok, closing the issue, as requested.

Original comment by aggraef@gmail.com on 23 Jun 2012 at 10:04