Dual methods in concept-oriented programming vs. capturing and bubbling in JavaScript
Uncategorized 2 feedbacks »JavaScript is a prototype-based language (like Self) the main use of which consists in implementing web applications by adding behavior to HTML pages. A page is represented as a tree of elements, called DOM model, where each element has one parent and many child elements. The most important distinguishing feature of prototype-based languages is that they do not use classes and parents are shared parts of children. JavaScript implements an event-based model. Events are created and processed in the context of DOM elements. For example, if a DOM element represents some kind of panel then click events will be associated with this element and then processed by a handler attached to it.
Since DOM elements are nested the main question is in which direction events should be processed: downwards in the direction of child elements or upwards in the direction of the root element. The first (downward) event propagation strategy where parent event handlers have precedence over child handlers is referred to as capturing. The second (upward) event propagation strategy where child handlers have precedence over their parents is referred to as bubbling. For example, if we click a button within a panel then which of them will process this event first: the button (child) handler or the panel (parent) handler? These two opposite approaches were implemented in different browsers: Netscape chose the capturing (downward) model and Microsoft chose the bubbling (upward) model. The W3C event model supports both strategies so that event processing consists of two phases: first capturing down to the target element and then bubbling back up to the parent element.

Concept-oriented programming (COP) is similar to prototype-based languages in that objects in this model also exist in a hierarchy. The difference is that COP is a class-based approach where classes are used in a generalized form and called concepts (hence its name). Interestingly, COP has a novel method invocation model which is similar to the event propagation model in JavaScript via capturing and bubbling. This model is based on dual methods where each method is defined two times and these two implementations are referred to as incoming and outgoing methods. Incoming methods are executed when they are called from outside (from the parent). Outgoing methods are called when they are called from inside (from the child). Such a composition means that incoming methods intercept all incoming calls while outgoing methods intercept all outgoing calls. Essentially, incoming methods implement what capturing does in JavaScript while outgoing methods implement what bubbling does.
An advantage of dual methods is that there is only one predefined sequence of access which is controlled by two types of methods. If we do not want to intercept an event during capturing then we simply do not define the corresponding incoming method and this level will be transparent. And if we do not want to continue (capturing or bubbling) then we simply do not call the next method in the sequence. So it can be viewed as a method-based analogue of the event-based JavaScript model where instead of two-phase event processing two kinds of methods are used responsible for processing requests propagating in two opposite directions. The same mechanism in COP is used for reverse overriding and for modeling aspects. Note also that the capturing model is also analogous to inner methods in the Beta programming language.
Links:
Bubbling and capturing
Introduction to Events
Event order
Values are opposed to objects because they have opposite properties, that is, values are not objects and objects are not values. For example, a value is immutable element which is passed by-copy (by-value) while objects are passed by-reference. In programming languages, values are normally stored in stack while objects are allocated in heap. Values are visible from and used by only this context while objects can be shared by many contexts. Values do not have a location in space (reference) while objects are characterized by a permanent reference.
Since OOP is about objects, values are not fully supported in this programming paradigm. In particular, the main purpose of classes in OOP consists in describing object types rather than value types. The only thing that is supported in most programming languages are primitive values with primitive types like integers. Another very important use of values supported in most OO languages is referencing. However, we are not able to create application-specific values and application-specific references -- they have a platform-specific format and behavior. (One exception is C++ where classes can be used for describing both values and objects.)
In the concept-oriented programming (COP), both values and objects are first class citizens with the same rights. It is not simply a decorative enhancement but the recognition of the importance of values. Values in COP can account for a great deal or even most the program complexity.
For modeling values and objects COP introduces a novel programming construct, called concept. Concept is defined as a couple of two classes: one reference class and one object class. Reference class describes values while object class describes objects. (We call it reference class because the main role of values is a reference.) What is really new here is that these two classes cannot be used separately, that is, reference class and object class is one whole. The change of paradigm is that programming is reduced to manipulating value-object couples. In this context, COP informally relates to OOP as complex numbers relate to real numbers in mathematics. If in OOP elements have only one constituent -- an object, then in COP an element has always two constituents -- one value and one object, which are informally analogous to two constituents of complex numbers (imaginary and real part).
The next change is that inclusion relation is used instead of classical inheritance. In OOP terms, this means that a base element (value-object couple) may have many extensions. If values are used as references, then it is a basis for describing application-specific hierarchical address spaces like conventional postal addresses. For example, assume that concept Street is included in concept City which in turn is included in Country. After that each element is represented by a reference consisting of three segments: country (high), city (middle), street (low). This complex reference is a value which represents a complex object. The main different from OOP is that one country (base) can be shared among many cities (extensions) which in turn can be shared among many streets. Elements in COP are living in a hierarchical space (described by concept inclusion hierarchy) while in OOP they are living in a flat space although their classes are hierarchically ordered.
COP Article: Informal Introduction into the Concept-Oriented Programming
COP forum: http://conceptoriented.org/forums/index.php
In programming, we used to think of references are something primitive and platform-specific that is provided by the compiler as a means for representing objects. In contrast to objects, which have domain-specific structure and behavior, references do not expose their structure and do not show any activity. We use objects represented by references as if they were directly accessible and programming is reduced to modeling exclusively objects while references are absolutely passive elements.
But what if we assume that references, like objects, may have arbitrary domain-specific structure and behavior? Shortly, we will get a novel approach, called concept-oriented programming (COP). References in COP are as important as objects because both can modularize domain-specific structure and behavior. The first question here is what advantages we will get by using active references? Here are some applications where it could be useful:
- Modeling domain-specific address space rather than adapting platform-specific surrogates. Indeed, why not to use domain-specific references directly in the program to identify its objects? It is simpler and more natural.
- Modeling cross-cutting concerns. An important observation about references is that their functions cross-cut many classes of objects. For example, when a Java object is being accessed, JVM executes one and the same procedure independent of the object class. If references could be modeled from the program then we could use them to execute functions which are common to many object classes.
- Modeling persistent, remote and transactional objects. References could be responsible for implementing intermediate functionality which is specific to these uses. For example, each time an object is about to be accessed, its reference will load its state from persistent storage or send the request to its remote location or start a transaction.
COP Article: Informal Introduction into the Concept-Oriented Programming
COP forum: http://conceptoriented.org/forums/index.php

As programmers, we know that any object has a representative, called reference. For decades objects have relied exclusively on references provided by the compiler which in turn used the underlying environment, some kind of standard library or middleware for their generation and management. For example, the compiler could use global heap where allocated objects are represented by a system-specific memory handle. Objects could be represented by remote references generated by EJB container like JBoss or WebLogic. In Java, references are generated by JVM. Other interpreters are using their own run-time environment and hence their own specific references. Thus most contemporary programming languages have one common property:
References are not integral part of the program and cannot be adapted to the purposes of this application and this problem domain
In other words, in conventional programming languages we are destined to use only standard references and their access mechanisms provided by the available hardware, OS, middleware or library. There is no easy possibility to develop application-specific references for this concrete domain as integral part of this program.
The system can be then viewed as divided into two layers:
- The first layer is responsible for generating/managing references and providing object access procedure
- The second layer is the program itself where these references are used independent of the peculiarities of the first layer
Almost all exiting programming paradigms isolate these two layers so that programming is reduced to the second layer. This means that the programmer can develop objects and their methods but is not able to influence how these objects are represented and how they will be accessed. Concept-oriented programming (COP) is a novel approach to programming which changes this view and allows for describing both layers within one program. COP makes references first-class citizens of the object world by retaining the transparency of access (isolation of the layers). References and objects have equal rights in a concept-oriented program. In particular, COP is based on using a new programming construct, called concept, which is defined as a couple of two classes: one reference class and one object class. As a consequence, both references and objects have arbitrary domain-specific structure and behaviour. COP also uses inclusion relation instead of classical inheritance. (Concepts and inclusion generalize classes and inheritance, respectively.)
One of the main advantages of COP is that the programmer can develop domain-specific containers with a virtual address space where objects will live. In other words, the programmer can implement functions which normally belong to hardware, OS, middleware, run-time environment or a library. Another interesting application consists in modeling cross-cutting concerns.
One interesting observation about computer programs is that something always happens during object access behind the scenes which means that any object access inevitably entails execution of some code which is not part of this program. Thus object access is necessarily indirect because it needs some intermediate procedure which is responsible for finding the real location of the represented object.
For example, if we have a reference to a bank account object of class Account then it can be accessed as usual by calling its methods:
Account account = findAccount("Alexandr Savinov");
double account.getBalance(); // Object access
Here one method invocation is responsible for accessing this object and getting the current balance. Although here we have the illusion of instantiations action and direct access, it is wrong to think that getting balance is a kind of primitive operation which is executed immediately after this method has been called. In fact, if it is a Java program then JVM will have to resolve this reference into memory handle which in turn will have to be locked and a physical address will be obtained. If it is a remote reference then this request will have to be serialized and transferred over the network using some protocol. It might also happen that this reference represents a persistent object and then its state will have to be retrieved from some storage. There are also many other examples and use cases but the main observation is that
There is always some intermediate code executed implicitly behind the scenes during object access and this code is referred to as dark matter of the program

Why it is called dark matter of the program universe? Because it is undetectable and we know about its presence only indirectly by observing its effects. The presence of dark matter is inferred from the necessity to explain some "missing functionality" where we see that the program results in some effect but the program code has no instructions which could explain it. Moreover, even if we know that it does really exist we are still not able to affect this layer of functionality using traditional approaches programming. We cannot set the moment in time where this code will be activated. And we are not able to influence what precisely will happen during access. This layer is completely out of control. And here we come to an interesting but rather pessimistic conclusion:
There exists a layer of functionality which cannot be changed or replaced in OOP
It should be noted that of course we have a possibility to influence how object access works by changing the environment of the program such as the compiler, run-time environment, library, operating system or hardware platform. This will not change the explicitly defined behaviour of the program (business logic) but it will change how references are defined, how objects are accessed and other aspects that cannot be changed from the program itself. In other words, by putting our program in different environments we can change the implicitly executed intermediate functions -- the dark matter.
So what is the problem? The problem is that we would like to be able to influence dark matter from this same program and for that purpose we need a programming approach which would treat dark matter as integral part of this same program. We would like to be able to develop our own domain specific dark matter which is adapted for the purposes of this specific program and this specific application. Why it is important? Because we accept the following postulate:
Hidden intermediate functions executed during object access are as important as normal explicitly invoked object methods and they can account for a great deal of even most of the program complexity
If this assumption is true then the focus of programming moves to developing intermediate functions rather than end object methods. In other words, the shift of paradigm is that it is more important what happens in-between than what happens at the end (of method invocation). Any method invocation turns in this case into a sequence of intermediate actions where the method itself is only the last step. Here are some well known examples of functionality which should belong to a different layer invisible from the main layer of business logic and therefore treated as dark matter:
- Persistent layers. We want to manipulate objects as if they were normal objects but change the way how their state is managed.
- Object containers. We want to be able to develop application specific containers where objects will live by retaining the possibility to access them as if they were directly accessible objects.
- Custom memory managers. Why to use the standard heap provided by OS if we have a number of application specific requirements for this unit? It would be much more productive to develop our own memory manager which is adapted for objects of this and only this program.
- Domain specific compiler. We want to change the way how references and other constructs in our program are implemented. For that purpose we can change the compiler but it is normally either not possible or is very difficult. It would be interesting to have a possibility to develop a compiler/interpreter as an integral part of this same program.
To solve this and many other problems a new programming paradigm has been developed -- Concept-Oriented Programming (COP). Within this approach, dark matter plays central role and is made integral part of the program. In COP, the programmer is not only able to influence what happens behind the scenes but rather it is his main concern. In other words, the main task in COP is creating an application specific environment where objects will live. This includes such functionality as object representation (custom references) and object access (custom access procedures). The functionality of this domain specific environment is triggered implicitly by injecting the necessary functions into all internal objects.
It is important that COP generalizes OOP by retaining its main principles and features. COP introduces a new programming construct, called concept, which generalizes conventional classes. Concepts in COP exist within a hierarchy defined by means of inclusion relation which generalizes classical inheritance. It is also important that COP allows for describing cross-cutting concerns in a manner which is different from AOP (and even can be said to be opposite to AOP). And what is more, COP is a basis for a new data model -- Concept-Oriented Model (COM) -- by significantly decreasing the incompatibility between conventional data and programming models (impedance mismatch).
Links:
- Informal Introduction into the Concept-Oriented Programming
- Concept-Oriented Programming wiki article
- Informal Introduction into the Concept-Oriented Data Model
- Concept-Oriented Model wiki article
- Concept-oriented discussion forum
- Discussion on The Server Side
- Discussion on The Joel on Software
- Concept-Oriented Model wiki article on c2