Seeking review and comments on R/W tags
martijnverburg at gmail.com
Thu Jun 15 19:38:44 UTC 2017
Looks like some interesting research! I'll confess I haven't got the JVM
knowledge to comment in depth apart from my earlier observations that this
will need to be a patch against Java 10+ in order to be reviewed at the
I'm assuming that use of reflection or runtime bytecode modification could
still 'break' the predicates here and I'd have a preference of not
introducing further syntax to the Java developer (i.e. If a way could be
found to do a majority of this via annotations then I think it would cause
Please note I Am Not A JVM Expert (IANAJE), so take my comments with a
large dose of salt.
On 16 May 2017 at 18:18, John Crowley <jdcrowley at gmail.com> wrote:
> Hi All,
> I’m looking for some help to review a proposal.
> For a while now I’ve been working toward the goal of providing *declarative
> immutability *in Java - by having Read/Write tags on variables,
> references, methods, and generics*. *(Similar, but more extensive, than
> the *const* keyword in some languages.)
> Things have progressed to the point that a few more (expert) eyes would be
> appreciated to review and comment on whether this is feasible and desirable.
> A short summary follows, but everything is available here -
> - A document with a complete description,
> - A modified (Java 8) compiler which implements the initial portion of
> the concept (the *Report Card* lists what is supported).
> - A README file which describes where everything is on this drive.
> A very condensed description ….
> *The Problem*
> *Variables* can be protected by making them *private* and using
> *getters/setters* to control access - but at the cost of complexity,
> additional code, and runtime overhead.
> *Object instances* are a more severe problem - once anyone has a
> reference, they can modify any visible variable, and call mutating methods.
> When calling a *method* on an instance, the caller does not know if that
> method mutates that instance (or some referenced instance).
> *The Proposal*
> A set of single-character *tags* is proposed - W = writable, R =
> read-only - that can be appended to variable definitions, types
> (references), methods, and generics (more below).
> *Variable declarations *may have 2 tags - the first controls *outsiders* and
> the second *the owner*. (The *owner* is defined as the innermost context
> which declares the variable.) For example,
> public Date lastActivity:RW = new Date()
> specifies that the *owner *(the declaring class) may assign a new Date
> instance to *lastActivity*, but no *outsider* may. Even stronger,
> public Date lastActivity:RR = new Date()
> specifies that neither an outsider nor the owner may change the Date
> instance referenced by *lastActivity* (equivalent to the *final* keyword).
> The remaining problem is that anyone can change the semantic value by *lastActivity.setTime(….).
> *This can be controlled by tags on the *type* specification:
> public Date:RW lastActivity:RR = new Date()
> where the *Date:R* portion specifies that an *outsider* cannot modify any
> visible variable in the *target instance* and can invoke only* read-only
> methods* (myMethod:R).
> The *owner* may update the instance - presumably to update the timestamp
> of the last activity processed. (The *owner* of an *instance* is the
> context which instantiates that instance.)
> This is a strong API definition - *outsiders* know that they may create
> and retain a local reference and it will always refer to the same instance,
> and the *owner* has been able to make the information public with the
> assurance that no one else can tamper.
> (Note that if the variable were *private* with a *getter*, then all *outsiders
> *would have to invoke a method, and to be safe the *owner* must return a
> *cloned* instance.)
> *Methods* and their *parameters* may also be tagged. *myMethod:R* specifies
> that *myMethod* does not modify the instance (or any internally
> referenced instance) - and this is validated by the compiler. *myMethod(Date:R
> myParameter, …) *considers the passed Date instance as read-only within
> the method. If the method is tagged as R, then all parameters must also be
> tagged as R (the compiler infers this for untagged parameters, an explicit
> W tag is an error).
> Extending these tags to *generics* allows control at all levels of the
> declaration. Assume that a *class Message…* exists, then
> specifies that *outsiders* may not modify the List (add/delete elements)
> nor mutate any Message within the list. The *owner* may do both - e.g.
> add new Messages to the List, update a Message when it is acknowledged, etc.
> A final tag of *P (= Pure)* may also be attached to a type declaration -
> *Date:P* - and ensures that *no *mutable reference exists to this
> instance - it will be immutable throughout the application. Important
> information for any developer, and allows the compiler to utilize all
> possible optimizations.
> As a last example, consider:
> public Map:RW<Date:P, List:RW<Message:RW>> history:RR = new Map<Date,
> which is a (live) history of all of the Messages processed on a given day
> (assumption: the HH:MM:SS.sss portion of the Date is zeroed).
> This tells any user that the Map is live, the key (Date) is Pure (good for
> the key of a Map), and the List and Messages will be updated as events
> occur. The *history* variable will always reference the same Map. The
> compiler will flag any attempt by an outsider to modify anything at any
> level, and will also flag an attempt by the owner to use a Date key which
> is not immutable. (In a multi-threaded environment, synchronized versions
> of Map, List, and Message would be necessary.)
> The modified compiler enforces most of the above at compile time - so it
> appears that implementation is feasible.
> Key questions remain where review by outside experts is needed:
> - Is the syntax complete? Unambiguous?
> - Are the semantics complete? Are there reasonable coding paths which
> lead to contradictions? Is there any path where a readonly tag can be
> converted to a mutable tag?
> - Is this useful to the developer? Does it produce more robust code?
> Better APIs? Fewer LOC? Better runtime performance?
> Thanks for your help,
> *John Crowley*
> Westport, CT
More information about the valhalla-dev