[m-dev.] Unique Modes and Transaction Logic

Paul Bone paul at bone.id.au
Wed Jul 23 14:57:49 AEST 2014


On Tue, Jul 22, 2014 at 10:15:37PM -0400, Marcus Troyka wrote:
> On 07/22/2014 07:45 PM, Paul Bone wrote:
> > I thought we'd covered this:
> >     + An object with internal state, breaks referrential transperancy.
> >     + An object with threaded state, does not break referrential
> >       transperancy.
> >
> > Typically a class based OO system uses internal state, And I had previously
> > thought (possibly incorrectly) that a prototype based OO system typically
> > uses threaded state.
> >
> >
> Just because an object has "internal state" does not make it impure.
> Because it abstracts away a lot of implementation details it might look
> that way, but all the objects are really doing is making it easier to
> thread state. An object is really just a data structure, not unlike a
> tuple, and when you make a deceptively simple call like:

If that state can be modified by a call that breaks referrential
transperancy then it's impure.  (This also applies to structures).

X1 = object.getX();
object.doSomething();
X2 = object.getX();

If it's possible that X1 and X2 are different then this is impure.


> >let x = myObject.doSomething(myargs)
> 
> what you're really saying is:
> 
> >let myclass_decompose(myclass_data_structure) =
> >    let some_variable = %..extract some variable from the data structure..%
> >    and some_other_variable = ""
> >    ...
> >    in
> >        let doSomething(args) = %..implementation..%
> >        in
> >    doSomething(myargs) %-the actual method call-%

Yes, if the object were a structure and I did:

X1 = getX(structure);
doSomething(structure);
X2 = getX(structure);

Then that is also impure.


> all of which is 100% pure. doSomething will typically either return a
> value, or recompose a new object data structure and then return that.

Okay, so it appears we've gotten our wires crossed about what we're talking
about again.  Yes, if you do either of those things then it is pure.  Which
is why:

    + An object with internal state, breaks referrential transperancy.
    + An object with threaded state, does not break referrential
      transperancy.

Remember that internal state means that the state is hidden and if it
changes then referential transparancy is broken.

> > Then the pointer to the list is dereferenced to retrieve the pointer
> > to the tail of the list (Xs). So we've created a new pointer (Xs).
> > Then we make the recursive call. I'm doing a proof-by-induction so
> > what I do now is assume that the base case is the only possible thing
> > that can happen because it's the only thing I have uniqueness
> > information about. For the base case we know from earlier that
> > uniqueness is preserved, in this case it is preserved that there is a
> > single alias of Xs (the whole list) and we are tracking that
> > reference. The final action of this clause is to add 1 to Len, this
> > doesn't affect uniqueness at all.
> Hmm, after thinking on this I don't think that's correct. A "unique
> input" means that the input is effectively different every time the
> function is called (implicitly, at least), and would be equivalent to
> di.

Didn't you ask me/us what ui means in the context of Mercury?  And now
you're answering your own question by telling us how Mercury defines ui?

> 
> Also, I believe that should have been:
> 
> length(List, Len) :-
> 	length_inner(List, 0, Len).
> 
> length_inner(List, Accum, Len) :-
>         if List = []
> 	then Len = Accum
> 	else List = [_ | Xs], length_inner(Xs, Accum+1, Len). 

That's one option, both implementations are correct, yours is tail
recursive.  I choose the simplest option to illistrate my point.  Splitting
hairs over the choice of possible implementations is not helpful in the
discussion of uniqueness.

> >AIUI prototypes still involve resolving method calls at runtime.
> 
> Some prototyping systems do resolve method calls at runtime (objective-C
> does also, even though it's mainly just OO), just like it is common to
> defer type checking to runtime, but it isn't necessary. Lissac is a
> prototyping language that's completely compiled and resolves all types
> and method calls at compile time (although lisaac is imperative and not
> pure functional):
> Lisaac on wikipedia <http://en.wikipedia.org/wiki/Lisaac>
> Lissac Home Page <http://alioth.debian.org/projects/lisaac/>

Okay cool.


-- 
Paul Bone



More information about the developers mailing list