The InstantView Script language
InstantView is a programming language with which business applications can be written in a structured way with minimal formalism. As an interpreted language with loose coupling and declarative interface description, it is ideally suited for agile software development with short development cycles. InstantView scales from simple one-liners to the structure of complex applications.
To be able to map this complexity, InstantView is used as part of the ClassiX architecture for particularly volatile, business and specific aspects of the application, while the CyberEnterprise provides stable, generic functionality. At the same time, InstantView is primarily intended to work semantically instead of technically: the developer should be able to think in a process-oriented way instead of dealing with technology. By learning a script language, the entire application can be created for all end devices. This separation gives a clearer structure as to which changes are to be made to the application in which part.
When calling from one module to another, the recipient can be changed at will for both the undirected messages and the directed provider calls.
Predefined semantic slots are a combination of the hard data fields of classes and the underspecified slots in prototypical languages: Each object can have individual data fields, but these are preassigned with a meaning and thus describe themselves.
In order to map connections between objects, the developer does not have to formulate JOINs, but can simply use an appropriate expression to describe the connection from one object via its member or other relations to the other in a navigating way. Such a description can be used, for example, to fill surface fields and save their contents.
Similar to HTML, the interface in InstantView is declared in its final state instead of being assembled as is usual with GUI toolkits. So it describes what you want to get, not how to get there. By reading the description, it is immediately clear how the interface will look like later and adjustments are easier.
In InstantView all components can be specialised without having to change the behaviour of the base. For example, the functionality of a procedure can be adapted in a derivation or interface elements can be added declaratively.
An interpreted language means: no compiler, no build process, therefore fast development cycles. Furthermore, statements can be dynamically assembled and executed.
Access from InstantView to the database is transaction-based: Only when a transaction has been completed is it written to the database. However, this happens without the intervention of the InstantView developer and without an object-relational mapping.
The central buffer in InstantView is the stack. This means that no variables need to be used and calls to procedures, which can also have several return values, can be easily chained.
- Interaction with the GUI
- Parameter stack
- Garbage Collection
- Interaction with model objects
- Interaction with the object manager
- Message passing
- Further topics
The immediately visible part of InstantView® are window objects, of which there are currently 30 different ones. Window objects have action lists that define the dynamics of the application in response to events. There are system events and freely defined messages (the latter are an important software technical means of structuring complex applications into independent modules).
Window resources and actions are defined using InstantView® - a simple language designed to meet the needs of rapid application development, so that even the non-informatics user who is primarily interested in the application can work with the model objects. InstantView®(Script) should be easy to understand and use - in this respect perhaps comparable to BASIC. Simple, manageable constructs are preferred to elegant but complicated solutions:
- There are no type agreements. Variables have the character of a container, which can contain numbers, strings, objects etc. InstantView® ensures that operations are only executed according to type - if necessary, an error message is generated. If one of the arithmetic operators +, -, * and / is applied to an object, the object must decide whether the operation is meaningful and executable or is rejected with an error message.
- Logically related values (objects, numbers, strings) can be combined as a vector.
- Instructions have a maximum of two constant parameters that specify the desired operation in more detail. Variable parameters are conveyed via a stack and the result of an instruction is stored on the stack.
- The elements of the stack are the same containers that are used for variables. Why a stack? Firstly, because it is a very simple concept. Even those who have never been involved in programming can easily imagine an InstantView® instruction as a machine that takes something from a stack in the first cycle (from the top, of course!), then executes the desired task and finally places the result on the remaining stack. One disadvantage should not be concealed: the Postfix notation. To add a and b, instead of the usual notation a + b, now a b + must be written (because '+' takes both operands from the stack and then puts the result there). However, complex arithmetic expressions should be calculated within the member functions of the objects. Of course you have to consider the constantly changing occupancy of the stack. This can be annoying if you keep intermediate results over several statements. But for that there are variables! Less obvious are the following advantages of the stack architecture: Subroutines in InstantView® are user-defined statements - certainly a better concept than the GOSUB technique in BASIC, but - just like in BASIC - without the need to deal with the passing of parameters (call by value versus call by reference). InstantView®'s message passing in combination with the stack mechanism allows to bring any data to the receiver very easily and elegantly with a message.
- To structure a programme (locally), there are the well-known constructs: Alternative(if, else), cycle formation(do, while, loop), selection(case) and composition(user defined statements).
- Modules divide larger applications. Each module creates its own namespace for variables and user-defined statements. Modules have all the properties of object orientation:
- Encapsulation: Different modules communicate via messages that form the interface of a module to the outside world. To encapsulate modules, only the accepted messages need to be known.
- Inheritance: Further modules can be derived from a module. The derived module inherits the window resources and actions defined in the base module in order to supplement or overwrite them by redefinition.
- Polymorphism: All inherited actions behave polymorphically (actions are virtual).
Modules are the software building blocks at the highest level of abstraction. An application can be put together from them immediately. External module definitions were introduced to support even very large applications.
An intelligent mapping between window and model objects controls the data exchange between model and surface. The visualisation of the model data becomes simple and effective(FillWindow, DrainWindow). The connection between view and model is described by an access expression, with which, among other things, relations can be traced and functions can be called.
Most InstantView® model classes have the ability to hold dynamic data - slots - in addition to the data statically defined by the C++ class definition. InstantView® ensures that slots appear as 'normal' data members. Slots can appear in an access expression or can be used in the formulation of a query. The mapping between model and user interface takes into account the fact that a slot does not necessarily have to be present in all instances of a class(volatile window objects).
InstantView® is an interpreted language. Applications described in InstantView® are translated into an internal format that can be interpreted very quickly at runtime when the program starts.
InstantView® script describes, among other things, window resources that are transformed into real Windows window objects and thus brought to display on the screen. Messages received from the GUI are translated into logical events (i.e. into the system events provided by InstantView®). Logical events start the algorithms described in action lists.
Like any other event-driven program, InstantView® dwells in a program cycle, waiting for messages from the base system (MS Windows). As soon as the user presses a button, selects a menu item or does something similar, InstantView® receives a message for the window object concerned (the button, the menu item, ...) and translates it into a logical (and therefore platform independent) event. Then the action list of the window object is searched.
If there is a sequence of instructions bound to the logical event, this sequence should of course be executed. This is also done, but not immediately. Under certain circumstances a time-consuming process could start now - but InstantView® answers a message of the basic Windows system at this moment! Therefore the action is decoupled in time: the InstantView® instructions pass a queue. This diversion is transparent for the InstantView® programmer, but allows him to define any action for a system event without worrying about time conditions.
The following figure shows the connection message - logical event - action for a window with button. If the button is pressed, the title of the window changes, in our simple example the title "My Window" is put in brackets:
InstantView® script instructions exchange parameters and results via a stack. Each instruction consumes a precisely defined selection of stack entries and then stores its results there. The following figure shows the stack allocation for the previous example:
InstantView® automatically removes data left on the stack by an event-triggered instruction sequence. The data that is on the stack or held by variables occupies memory. This memory is freed up when entries are removed from the stack or variables are assigned different values. From time to time, InstantView® starts a garbage collection process that reclaims such memory areas.
For elementary data types (integers, strings, multiple strings, ...) this is done automatically; there is no reason to take note of this process at all. But also the memory once occupied by a transient object X should be released. The garbage collection algorithm cannot - at least in this release - determine whether X is referenced by another (transient) object Y. As long as X and Y are on the stack or variables are assigned, everything is fine. If then only X becomes free, Y contains a reference to a non-existent object after the next garbage collection. There are two ways to prevent this:
- ensure that the referenced object X is kept in a variable (as long as Y exists)
- Exclude X explicitly from the garbage collection (see CreateTransObject) and release it later yourself (with DeleteObject) This problem also affects (transient) objects as return value of a function: The signature specified in the MDI determines whether InstantView® excludes the object from the garbage collection or not.
Model objects are instances of classes written in C++, and therefore there is no inherent ability to access data and methods at runtime (with non-C++ code). However, InstantView® needs exactly such access. Therefore model classes can be extended by a Data Dictionary(DDI) and a Method Dictionary(MDI).
InstantView® has instructions that bring data from an object to the stack, or vice versa, save data from the stack to an object. The DDI describes which relations between objects can be created with InstantView® (and thus guarantees referential integrity). It is the basis for the intelligent mapping between model object and window surface via access expressions (see FillWindow and DrainWindow).
With the instruction Call, functions of an object can be called if they are entered in the MDI. This also applies to function calls within an access expression.(Both DDI and MDI of a class are automatically generated with utility GENDDI).
If InstantView® wants to create / delete a persistent object, start a query etc., it does not request these services directly from the object-oriented database but relies on the object manager. ClassiX® divides the database into layers and domains, objects can even be stored in different physical databases.
The layout of a database is described in the file CLASSIX.INI, which the object manager reads during the initialisation phase. Only the object manager 'knows' where an object of a certain class must be stored and where it can be found again.
If a message is sent (with SendMsg), InstantView® first searches the action lists of all modules, then all window objects for instructions associated with the sent message. Found instructions are executed immediately - without the diversion via a queue. Only the currently open Windows and their child objects can receive a message. Consequently, if a message is to open a window, the corresponding instructions must be assigned to either a module or another window already on the screen. The window object sending a message can also belong to the receivers of this message.
How does a message convey further information? The first statement of a sequence activated by a system event sees an empty stack. This does not necessarily apply to the first of the instructions triggered by a message. For each receiver the exact stack occupancy that SendMsg has found is displayed. SendMsg takes all entries from the stack. The receivers of a message can return their stack to the sender with the instruction ReturnStack.
The same instruction sequence can be triggered by system events and messages. As with system events, the receivers of a message may also leave data on the stack (InstantView® automatically removes it).
SendMsg distributes its message like a circular. If you want to set up a protocol where the receiver answers the sender directly (eliminating all other potential listeners), the primary message must contain the sending window object in addition to any other data. A window object is placed on the stack with the widget instruction. The receiver can now reply specifically with SendMsg(,DIRECT).