Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

This new work on transformations together with model relay is described by JIRAS http://issues.fluidproject.org/browse/FLUID-3674http://issues.fluidproject.org/browse/FLUID-5045 and http://issues.fluidproject.org/browse/FLUID-5024. The current discussion (mostly arising on a call with Colin on Thursday 28th) relates to particular strategies to be used for writing Model Transformations "transform" elements that are used in linking together models - with the particular example taken from Infusion's Pager component which has motivated ChangeApplier work for a number of years. The 2010 ChangeApplier system of "guards" was largely designed with this use case in mind, but when the rewrite updating the Pager in Spring 2013 finally arrived, it was discovered that the system wasn't adequate. A brief sketch of the Pager's model:

...

A major goal of the model (+ model transformation) system is to be able to keep the pager's model valid without irritating state-dependent code being written by the user. The pageIndex and pageCount "guards" for the 2010 pager were written using the "validation" model familiar from many web frameworks (e.g. that abstracted by Spring Validation, etc.) but still need to be manually "scheduled" by the user in order to account for the fact that they are constraints which become invalidated by the values of other model fields. 

The FLUID-5045 work promised to supply a new and much clearer scheme for expressing these kinds of constraints, based on the "integral tendency" (see New Notes on the ChangeApplier - in this model, one doesn't supply dedicated rules for updates to model state which either accept or reject them (guards/validators) but instead only provides assertions (lenses) about the overall state of the model and its internal relationships, and expects the framework to take care of scheduling and operation of the rules. This is consistent with the spreadsheet-like "end user idiom" which is promoted e.g. by the IoC framework itself). 

There remain a number of choices as to how to best express the model transformation rules, for which looking at the Pager case continues to be instructive. Here are some of the implementations, both old and new, for reference:

...

The stark difference between approaches a) and c) and the differing interests of the communities which might author them cut to the heart of the issues we hope to address when beginning our authoring infrastructure next year (2014). During Thursday's (3028/1012/13) conversation with Colin (sadly this can't be abscribed a location such as "pupusa conversation") ideas for a tooling approach emerged which might help to get alternatives a) and c) in better contact. For those using approaches c) we might draw up a limited subset of simple JS functions (perhaps, those containing no control structures, references to other functions or use of higher-order functions) for which we supply special interconversions support. This is reminiscent of other "subsetting" approaches such as Mozilla's asm.js or ECMAScript 5's "strict mode" etc. This support could be operated by the well-known Esprima parser or otherwise. For a suitably simple vocabulary of short and simple functions, we could guarantee bidirectional conversion between form a) as produced by authors using visual or non-visual tools, and form c) as produced by coders - a form c) equivalent would also improve performance considerably.

Another important reminder from this conversation was of the visual form of the authoring process - which should always "carry the test cases along with the code". That is, that the initial authoring experience would consist of supplying some paradigmatic test cases, which would then permanently accompany the implementation, acting as both documentation and test cases. The fact that this procedure is really what is followed by real developers in any case can be seen by the cryptic comment // 10 -> 1, 11 -> 2 preceding the implementation of the function fluid.pager.computePageCount. The form of its body is already relatively obscure, although the expression return Math.max(1, Math.floor((model.totalRange - 1) / model.pageSize) + 1) is relatively readable compared to some "expressions of the art" which can be seen in the more complex regular expressions.

...