On 22 March 2011 16:33, Jonathan S. Shapiro <[email protected]> wrote: > The problem is that even when it is subject to lifetime safety, and even > when we consider only the single-threaded case, an init-only field is not > immutable.In order for the output of length() to be stable it needs to be > immutable.
Could you please elaborate on the issue here? On 23 March 2011 00:12, Ben Kloosterman <[email protected]> wrote: > I will bite … Isnt this another reason why we should have member inline > functions and constructors for structs to create quasi classes ( maybe if > keyword class must have a constructor) ? Not for polymorphism but the > encapsulation helps eg if the type is not accessible till the constructor > is finished then all or some fields and the type itself may be immutable > and its trivial to guarantee this.. even for stack / static data….. I think. I feel that member functions for access control is one of the many ways in which the concept of 'the object' has been conflated. It is simple, but it doesn't compose, and sometimes it really needs to, where you find yourself in a situation where the function needs to be a member (for purposes of access) of more than one object. Typically people seem to hack around such things by making more things public or package access. And yet, it *does* compose better than init-only fields. These divide the world of code into the constructor, where 'this' is not properly an instance of the class, and other code, which must not initialise these fields. In reality, the object may go through several states where subsequent attributes are effectively immutable; but the only way to represent this within the type system is to construct a new instance of a similar class, with the appropriate attributes made final. Within the region system that I use, we can only talk about a field as immutable on some specified domain. This means that the function that mutates fields of an interfering region may never be called on an object of interfering region. You could have a similar (if less precise) reasoning with effect types, but I don't think that kind of approach works well in the presence of separate, AOT compilation. What I think would work better is typestate or dependent types. If you wanted to limit the scope to init-only fields, you might do it like this. A function may mention what fields it expects to be constant on that domain. For each (SSA) field of type X, require a fixed set immutable(X), the set of fields that must be bound and immutable. Ensure that, at each point of mutation, immutable(X) is consistent with which methods have been called and which methods may be called. Handle abstraction over callsites in the usual way. It makes sense (in the absence of rigour :) that these types are a strict generalisation of classical init-only fields, and is only slightly weaker than acyclic state machines provided by member functions (as the type system does not consider any external descriminator), but it does weaken the reliance on access control in that case. Alternatively, the concept of access could can be made more first-class, which seems neater to me, but I don't know if there is any active research in that area (Friends of C++ have probably scared anybody who would do such research away). -- William Leslie _______________________________________________ bitc-dev mailing list [email protected] http://www.coyotos.org/mailman/listinfo/bitc-dev
