Lumiera  0.pre.03
»edit your freedom«
tree-mutator-attribute-binding.hpp File Reference

Go to the source code of this file.

Description

Special binding implementation for TreeMutator, allowing to map tree diff operations onto native object attributes.

TreeMutator is a customisable intermediary, which enables otherwise opaque implementation data structures to receive and respond to generic structural change messages ("tree diff").

Each concrete TreeMutator instance will be configured differently, and this adaptation is done by implementing binding templates, in the way of building blocks, attached and customised through lambdas. It is possible to layer several bindings on top of a single TreeMutator – and this header defines a building block for one specific kind of layer, used to bind object fields through "setter" lambdas.

architecture considerations

Together with the (tree-mutator-collection-binding.hpp), the attribute binding is the most relevant building block – yet it is special in several respects. There is kind of a "impedance mismatch" between the concept of an "attribute", as used in the context of diff messages and »External Tree Description«, and the nature of data fields as used within the imperative or object oriented implementation: the latter is rooted within a class definition – which is conceived as a type, a conceptual entity used for construction of code, yet not really embodied into the actual code at execution time. Thus, with respect to the behaviour at execution, the structure defined through typing and classes appears as static backdrop. This leads to the consequence, that, on a generic (unspecific) level, we don't have any correlate to the notion of ordering and sequence, as found within the diff language.

On the other hand, this very notion of ordering and sequence is essential to the meaning of "diff", as far as collections of "children" are involved. This leaves us with the decision, either to increase complexity of the diff language's definition and concept, or to accommodate this discrepancy within the binding implementation. Deliberately, the whole concept of a "diff language" builds onto the notion of layered semantics, where the precise meaning of some terms remains a private extension within specific usage context. There is a lot of leeway within the language, and the correct usage protocol is linked to the actual scope of usage. We need the diff language to be a connecting medium, to link some remote partners based on a locally shared common understanding of structure.

And so we use the same approach when it comes to "attributes": We'll assume that the partners connected through diff messages are structurally compatible – thus any "change" message emitted at one side is assumed to basically make sense on the receiving side. Consequently, the binding of an "attribute" to an object or data field will either ignore or reject any specifics about field order. It will reject an explicit demand to re-order a field, and it will silently pass down other notions related to ordering – down to lower "onion layers" of the concrete binding. So it depends on the concrete setup of the data binding (TreeMutator), if some expression in diff language will be deemed incompatible – which happens when in the end no "onion layer" of the concrete binding was able to absorb and comply to the MutationMessage.

Another architectural consideration is relevant to the way attribute bindings are constructed: we rather construct a separate binding for each individual attribute, instead of building a collective binding for all attributes of a given object. This gives us the benefit of a simple and flexible solution plus it avoids the overhead of managing a collection of attribute definitions (which would likely cause a heap allocation for storage). The downside is that we loose any coherence between attributes of "the same object", we loose possible consistency checks and we get a linear search for access to any attribute binding. Moreover, we cannot protect against creation of a nonsensical binding, e.g. a binding which ties the same attribute several times in contradictory fashion. The client code constructing the concrete TreeMutator needs to have adequate understanding regarding mode of operation and "mechanics" of such a binding.

Remarks
for sake of completeness an alternative binding option should be mentioned: Attributes could be represented as a map of (key,value) pairs and then bound via the STL collection binding. This way, all the attributes of an "object" would be treated as coherent unit, within a single "onion layer". However, such a layout tends to run against the conventions and the protocol of the diff language and should be confined to cover some corner cases (e.g. to support an open ended collection of custom properties)
Note
the header tree-mutator-attribute-binding.hpp was split off for sake of readability and is included automatically from bottom of tree-mutator.hpp
See also
tree-mutator-test.cpp
TreeMutator::build()

Definition in file tree-mutator-attribute-binding.hpp.

#include "lib/error.hpp"
#include "lib/symbol.hpp"
#include "lib/diff/gen-node.hpp"
#include "lib/diff/tree-mutator.hpp"
#include "lib/format-string.hpp"
#include "lib/idi/entry-id.hpp"
#include <utility>

Classes

class  AttributeBindingBase< PAR >
 Generic behaviour of any binding to object fields (attributes). More...
 
class  ChangeOperation< PAR, CLO >
 
class  MutationOperation< PAR, MUT >
 

Namespaces

 lib
 Implementation namespace for support and library code.