ELENA Programming Language: Programming with ELENAAlex Rakov, Feb 2010
To start programming with ELENA it is good to understand the basic concepts behind it. This article describes general ideas and features of the language. It is presumed that the reader is familiar with common concepts and terms of object-oriented programming(OOP).
Agreement on terms
Firstly let us define the term "class" as a statement describing the object and the term "object" as an instance of the class located in the memory. In most cases both terms could be used in the text with the same meaning.
Secondly let us define the term "method" as a way how the object reacts to the message sent by others (or itself) to it. "Message" in this case is a named operation (request) which could be accompanied with a parameter (message variable). So then in the text the phrase "send a message" is used it is equivalent of the phrase "call a method by sending the appropriate message". The mapping between methods and messages is defined in the class virtual method table(VMT). If no mapping was found the operation is considered to fail.
Mutation is defined as a runtime change of the object behavior on the level of its VMT. Static one is a mutation which is defined in the class itself (class roles, horizontal inheritance), dynamic one is an external modification (group and broadcast objects, dynamic object extension).
General featuresBeing a pure object-oriented(OO) language with late binding ELENA (like SmallTalk) has no types, interfaces or any other attributes of structural programming. Practically all referring entities in the language are objects. Any variable is a reference to the object allocated in the program heap. The literal and numeric constants are references to the objects located in the static memory as well (unlike C# or Java). Moreover any reference to the class name is a reference to the object (in fact it is the normal way how to create objects in ELENA). That is why classes have no special methods called constructor. Due to the garbage collection there are no destructors as well. Unlike many other object-oriented languages ELENA does not support the concepts of special "class" methods and fields (which are in principle equivalent to "normal" functions / variables in none oo-languages). Furthermore the language requires that the message could have only one parameter (for the message without explicit parameter a reference to the special object nil is used).
A class may declare the alternative ways to react to the message (by declaring roles with these particular methods) and switch them (by taking these roles). A class functionality could be extended with a set of external classes (run / design - time mutation).
Finally ELENA introduces the concept of message chains. The code could be considered as a chain of messages where executing of every next message depends on the result of previous one. When one of messages is failed (mostly either the object has no appropriate method or deliberately breaks the execution) the chain considered as broken. It is possible to declare alternative chains which are executed if previous ones are broken. So then the chain is broken the control goes to the closest alternative chain. If no alternative chains is declared the program is finished. (it is roughly similar to the exception handling routine in languages like C++).
Late bindingELENA is a language with late binding. It means that the actual type of variable (class reference) could be defined only during the program run-time. It makes it harder to find and fix the errors from one side and eliminates all mess with type-casting, multi-inheritance (of interfaces) from other side. So effective programming with ELENA (or in fact with any dynamic OO language) is not possible without taking this feature into account.
The concept of late binding is introduced to achieve the real code polymorphism but it makes the program more complex (by increasing the number of possible object interactions). To minimize this side effect we could use two techniques namely protocols and code patterns.
A protocol (do not confuse it with the concept of interface) is a set of possible actions which could be done with the class which claims to support it. In reality this means that the protocol is a simple list of messages for which we define the expected actions. The class may not support all the messages in the protocol. It may support several protocols or none of them.
Code pattern is a special object implementing particular algorithm with provided parameters. For example an array enumeration could be implemented as a code pattern where an array and an action for each array item (in ELENA it is object too) are parameters. A code pattern has no knowledge about the parameters except the protocols they should support. Usually they implement well defined algorithms which could be used in combination with each other (e.g. combination of an array enumeration with comparing the values could be used to search a value in the enumerable list or array).
So if we actively use the code patterns and correctly implement the protocols the number of possible object interactions is relative small. Moreover if we limit the number of public messages (in fact the number of interaction between objects belonging to different modules) the system becomes more structured (on the level modules).
Message chainsELENA is a language with a reduced operational set. Practically the only supported operation is sending a message to the object with a parameter. Conditional (#if) statement extends this operation with possibility to use multi-statement blocks and loop (#loop) one just repeats it until it fails. The only way to control the flow is message chaining.
An ELENA program code is a sequence of actions (sending a message) enclosed in square brackets (Unlike Smalltalk the sub code is a sequence of action as well). The execution of every next action happens only if the previous one was successful. Otherwise the control goes to the closest alternative action and the flow continues. So we have a number of alternative chains of messages all leading to the program end.
Alternative message chains are used in ELENA not only for handling exceptional situation but (and mostly for) conditional branching. The program code could explicitly break the execution (by sending fail message) to indicate the negative result of the method.
Reduced class interfacesOne of the basic idea behind ELENA language is a concept of reduced class interface. It assumes that there is only limited way to interact with the object on the base of protocols supported by it. Any class method should perform an atomic operation, be quite small and support only one parameter. Moreover the strong concept of reduced class interfaces limits the possible operations between classes (belonging to different modules) to the small list of well-defined messages (verbs). The method can not have more than one parameter. As a result the method parameter tends to become an active partner. The method has to ask the parameter to return the required information, so the method caller has some control of the method work (in combination with dynamic mutation we could have real two-way interaction).
So how could any complex task be implemented? The answer is cooperation. Any "complicated" operation should be broken into several "simple" ones on the base of the principle "I know how - you know when". So the concept leads us to the situation where any task have to be solved only as a result of combined work of several "tiny" objects with limited public protocol (number of supported public methods). The objects may form a temporal group object or act alone. The most of the object interaction will be private so the external object may treat them as a black box system.
For example the edit box control may support only one public protocol to set or get a text value. To show / hide it we should use the special adapter implementing the same public protocol (methods set and get) but with the control visibility and so on.
In general the "systems with the reduced interfaces" tend to have bigger number of classes with simpler interfaces then the "normal" ones and more actively cooperate with each others to solve any possible task.
Class Mutation: RolesELENA language introduces several "brand new" features, one of them is roles (or static mutation). This feature allows classes to have several sets of methods (or several different ways to react to them).
It is desirable that the way how the class reacts to the method depends on its internal state. Though the total number of different object states is big enough we could always select several extreme ones (such as an empty string, unassigned container). Such cases could be implemented as class roles which could contain the code which is applicable only in this situation so no need to check for this extreme state throughout the class code. Only in the place where this state could be changed (copying the literal value, assigning the object) we will check the situation and apply (shift in ELENA term) these roles or return to normal one (shifting to "default" role).
In most cases the bulk of the code would not be affected so there could be only several quite simple roles. But in some situation the whole code is divided between roles. E.g. Boolean variable could have two (or three) roles: true, false values (and undefined one). It is possible to override the roles in the child class (though at the moment you need to override all role methods).
The operation of applying role is quite simple and affect any object reference (because the actual VMT reference is changed; that's why we could speak about the mutation). There is no big code overhead (except an extra VMT) and roles should be actively used instead of extra checking in the code. It is a good practice to recognize the code which has some extreme cases and put it into the appropriate roles (so we will get at the end very small, if no at all, code duplication). The rest of the code should be still implemented in the main body.
Class Mutation: "Any" handlersAnother interesting ELENA feature is the possibility to declare a class extension. It allows the object to override some messages at run-time (so we could speak about the dynamic mutation).
"Any" handler is a special method which redirects any unhandled message (i.e. messages which are not mapped in the class or its base classes) to the specified target. The target could be a single object (actually mutation) or collection (some sort of multiple inheritance). There are two types of redirecting to the collection: group and cast modes. In case of group mode the message is redirected to the first member of the collection which has the appropriate method (extending). For the second type the message is sent to all collection members (broadcasting).
There are number of places where the "any" handler concept could be applicable starting from code sharing (horizontal multi-inheritance) to the dynamic object mutation. It does not create a big code overhead and is actively used throughout ELENA library code and samples. For example it could be used to create a container class which in most cases is invisible (messages are redirected to the content) but still allows to change its content (via private messages so no name conflict is possible). So it could be passed to the code expecting the content without any modification which could be an advantage if it in turn passes the parameter to the third part code (e.g. if we wish to extend the communication line between two parts of the system without rewriting the layer between them) and so on.
ConclusionIn general due to the interface limitation ELENA tends to avoid the complicated method logic (so called "spaghetti" code). It is actively reused (due to shared objects, horizontal inheritance). The number of inter-module references is limited. It avoids excessive inheritance with the help of class extension / dynamic mutations. The number of objects is quite big and most of them actively interact with each other (the number of inter-class calls are much higher then inner-class ones). Due to its dynamic nature the code is polymorphic and could be modified in run-time.
P.S.ELENA is not only the experimental but actively developing language. So it may happen that a part of the article could be obsolete and modified time to time to reflect the current changes. If you become interested in the language please visit this page to see the current language concept.
Copyright (c) Alex Rakov, 2006-2010