[Grace-core] Immutability in Grace

Paucard, Charlie P charlie.paucard10 at imperial.ac.uk
Thu May 15 09:16:12 PDT 2014


James - to answer your questions:

The repository is indeed at https://github.com/cgizmo/minigrace. I'm not sure I mentioned this last time, but the interesting files are:
 _ gracelib_threads.* - pthread state, startup and destruction routines
 _ gracelib_msg.* - thread mailboxes
 _ gracelib_gc.* - threaded(-ish) modification of the GC
 _ actors_prim.c - Grace module for low level actor functions (spawn, poll, post, etc.)
 _ actors.grace - Thin "Erlang like" wrapper around actors_prim, to see what it would look like

> Ok yep. In general I prefer the idea of annotations to new language constructs.
> I can see how defs could be used in immutable objects - but surely not vars?

Since def/var represent the mutability of the reference, the "is immutable" annotation would apply to the referred data. Then it would be valid to have a "var x is immutable" point to immutable objects, as long as that "var" was not itself within an immutable scope.

> - (in that sense I think immutable is also *brand*
> - look at the grace brands paper in the GracePapers/Brands svn direction under review, not yet accepted anywhere.

I have read the Grace brands paper, but I don't think the implementation is present in minigrace yet.


Regarding the two immutability proposal ("immutable rules - static version" and "immutable rules - dynamic version" in your previous email), both would require some sort of knowledge about methods to ensure that they do not modify the state (the "purity" annotation).

As far as I can tell, neither approach would be able to make any deductions about the purity code without the help of the user, since there is no simple way of knowing (especially with the foreign C modules) whether data will be modified or not. I'm not sure how one would go about omitting annotations (to "give some static checking when warranted", in the spirit of gradual typing) and still have the system throw a runtime error when necessary. Because of this, I fail to see how the dynamic approach could be applied in this case.

On another note, I think it be possible to solve the problem that Michael brought up by further restricting the definition of pure methods to "referentially transparent". The issue regarding inheritance, as far as I understand it, would disappear as that code would simply not be allowed.

I do not think it would be too problematic a restriction, because objects that need to travel could then be structured in a "data object"/"IO wrapper object" way.

method makeDataObject {
  object {
    // I am immutable
    def x = 1
    method size { x } // Referentially transparent
    // post(otherThread, self) - not referentially transparent, not allowed
  }
}

method makeDataObject2 {
  object {
    // I am immutable
    inherits makeDataObject
    def y = 2
    method size { y } // Referentially transparent
  }
}

method makeIOObject(dataObject) {
  object {
    // Not immutable anymore
    post(otherThread, dataObject) // Safe
  }
}

Since the IO wrapper does not directly depend on the data, it can just be re-wrapped around the dataObject by the other thread on arrival to access its functionality. Of course, the wrapper will only have read-only access to the data, so any impure method operating on the fields of the dataObject will need to make a copy.

Charlie

Le 15 mai 2014 à 11:56:39, James Noble (kjx at ecs.vuw.ac.nz<mailto:kjx at ecs.vuw.ac.nz>) a écrit:

> So I have added Tim to CC...

oops sorry. In fact this can go to Gracecore, really:
if anyone doesn't get two copies of this email, then they should sign up to grace-core:
I've set reply-to grace-core

>> I copied in an older email from me below
>>
>> there are at least two different ways we could layer immutability on top of existing Grace objects.
>>
>> A) immutable rules - static/algebraic/implementation version (cribbed from newspeak as per email below)
>>
>> * immutable object/class can have no vars (fields), only defs, methods (& types ?)
>> * All its defs must contain immutable objects.
>> * it can't close over any vars
>>
>> OR
>>
>> B) immutable rules - dynamic/coalgebraic/specifcation version (I think some systems have done this, like constrainedBeanShell or something, obcure dynamic ownership langauge we did 10+ years ago)
>>
>> * any method request on an immutable must be evaluted "purely"
>> * any attempted to read a field (i.e. a var) in pure mode raises an error
>>
>> the dynamic rule is nice in that it's gradual; put "is immutable" on any object you're defining,
>> and the runtime must check. The catch is you now have to compile methods differently for
>> immutable and non-immutable objects - probably best to just follow Newspeak and say
>> that immutable objects must inherit from ImmutableObject...
> I don't think an immutable object is necessarily the same thing as an
> object whose methods are completely pure, even conceptually.

I guess it depends on what we mean by "immutable" doesn't it?

one definition is: requesting a method from an immutable object
with the same arguments (for some suitable definition of "the same")
always returns the same result. (carefully ignoring side effects).

Bart Jacobs The Elder has looked at this coalgebraically
but I don't think his treatment covers every practical situation.

>> in order to give some static checking (when warranted) you could add in an immutable annotation
>> on both objects and types, that would work like this:
>> - immutable objects/classes may be annotated "as immutable"
>> - it's an error to annotate as immutable if your object class doesn't meet the immutable rules we picked above
>> - types can be annotated as immutable too, in which case they only match immutable objects
>> - (in that sense I think immutable is also *brand*
>> - look at the grace brands paper in the GracePapers/Brands svn direction under review, not yet accepted anywhere.
>>
>> Charlie - does this help?
>> OK, that's probably asking a bit much, so: does this make any sense?
> You also have to deal with inheritance somehow. I'm not sure which way
> addresses that better.

the obvious rule is that immutables can only inherit from immutables.

> I can inherit from something that looks like it's immutable where I
> wrote it and have my object be mutable,

so the "something" can be immutable, and now your thing is mutable.

> and then there are the cases
> Andrew's pointed out where you get nondeterministic uninitialised-field errors:
> Any immutability design has to at least think about how it plays with those.

yes there are issues with initialisation where our naive rule doesn't always do what you like.
I'll only be nondeterministic when you have threads - I see that as an issue of threading.
Notably, Charlie's working with an actor model which could finesse some of these issues.

James

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailhost.cecs.pdx.edu/pipermail/grace-core/attachments/20140515/9479f8e9/attachment.html>


More information about the Grace-core mailing list