"Gaining a deep understanding of the event process is still a challenge" (Ted Faison).
"A programming language is low-level when its programs require attention to the irrelevant" (Alan J. Perlis).
The Concept of Event
An event is something that occurs in a system and that is of interest to know or detect in order to carry out a certain process associated with that event.
The general way to specify an event is "If condition, then action".
Events can be internal and external:
An internal event is an event that occurs during the execution of a program. They can be, for example, that a variable takes a certain value or a value among a set of values, that a sequence is of a certain length, that a certain function is invoked (in general or with specific argument values), a division by zero, and so on.
External events are often associated with interactivity. The most representative example of an interactive system is a user interface, where the user is the generator of events. Each user action (mouse clicks on a button or a web link, mouse movement, selection of a menu option, pressing a key or key combination, etc.) corresponds to a given external event.
Specification in MENTAL
An event is specified by a conditional generic expression:
〈( condition → action )〉
Observations
Since it is a generic expression, it is being evaluated at all times.
Both the condition and the action can be simple or compound.
The generic expression can be parameterized or non-parameterized.
The expression that produces the event, that is, the expression responsible for the event occurring (because the condition is met), is called the source, generator or producer expression of the event.
The condition indicates the event to be detected. The expression "condition" is also called "listener expression", since it is an expression that is being evaluated at all times to see if it is verified. The condition is satisfied when it is evaluated as a non-null expression.
Action indicates the process to be performed when the condition is verified, that is, when the event occurs.
The generic expression defining the event must be specified before the possible internal expressions that can generate the event or external actions.
Process of an event
When an event occurs, the following process takes place:
The current process is paused.
The event is processed, i.e. the action associated with the event is executed.
The evaluation of the current expression is continued, unless in the previous step, a stop occurs, for example, due to the detection of an error.
Named and anonymous events
A named event is an event that is assigned a name so that it can be referred to throughout a program. The form is
(e = 〈( condition → action )〉)
where e is the name of the event.
An anonymous event is one that is defined without a name, by directly specifying the corresponding generic expression:
〈( condition → action )〉
Specific and generic events
The generic expression specifying an event can be parameterized or not:
If it is not parameterized, a concrete or specific event is specified.
If parameterized, an event category (generic event) is specified.
Examples of specific events:
Detect if a is an element of the group (sequence or set) g:
〈( a∈g → action )〉
Detect if the variable u has a value greater than 1 and less than 10:
〈( (u>1 → u<10) → action )〉
Detect whether a group g contains a, b or c:
〈( {(a∈g)? (b∈g)? (c∈g)? }↓ → action )〉
In a more compact form:
〈( {[(([a b c]∈g)?]}↓ → action )〉
Detect whether any element of a sequence s belongs to g:
〈( {[s↓∈g)?]}↓ → action )〉
Examples of generic events:
Detect if an element a belongs to a group (sequence or set).
〈( (x = {x↓}) → a∈x → action )〉
Detect a group (sequence or set) of length greater than 10:
〈( (x# > 10) → action )〉
Detect whether a simple condition is evaluated:
〈( (x → y) → action )〉
Detect whether a complete condition is evaluated:
〈( (x ← y →' z) → action )〉
Parameterized events
These are events defined by parameters. They can be, in turn, specific or generic, depending on whether they include, in turn, parameters in their definition.
In this case there are two types of parameters: those of its definition or internal (x) and external (u and v).
Relative events
The above events were of absolute (or global) type, since they affected all expressions that are evaluated. But there may be events that only apply to a certain expression. These are the relative (or local) events. They are specified by
x/〈e〉
where x is the potential source expression (event producer) and 〈e〉 is the generic expression defining the relative event.
As in the case of absolute events, relative events can be specific or generic, depending on whether or not parameters are defined.
Examples:
Prevent a variable (result of an operation) from exceeding a certain value.
(y = x*x + 7)/〈( y>1000 → (y = 1000) )〉
Prevent the result of a given function from exceeding a certain value, regardless of the argument.
A dynamic event is an event that changes during the execution of a program. It can change in many ways: by making the condition, action or both variable, by parameterizing the event, etc. Examples:
A null event is one in which the condition or action of the generic expression is null. The event is said to be null because it produces no effect:
If the condition is null, it does not matter what is specified in the action, because it will not be executed:
〈( θ → action )〉
If the action is null, it doesn't matter what is specified as a condition, because nothing will be executed:
〈( condition → θ )〉
Using a variable (as a condition or as an action), which can take a null value or a non-null concrete value, we can activate or deactivate the event, in its condition or action aspect. Examples:
In a dynamic environment, expressions can change over time. If you want to capture the event that a certain expression changes, it can be done, but you need to include additional variables that record the changes.
Example: We want to detect changes in the variable x.
Initially, before specifying the event, store the current value of x in xant (x above):
(xant = x)
After assigning a new value to x, compare the new value with the previous one and, if different, save the new value and perform the corresponding action:
Similarly, higher level events (3, 4, etc.) can also be specified.
Examples of restrictive events
We want that a given variable v during a process, never exceeds the value 10. If it is greater, it must be automatically made equal to 10.
〈( v>10 → v=10 )〉
(v = 12)
v // ev. 10
In a given sequence s of two components, initially with the value (3 7), we want the sum to always be 10, so that the second component always matches the value of the first.
Prevent a sequence s from having more than two components.
〈( (s# > 2) → (s = (s\1 s\2)) )〉
s=(a b c)
s // ev. (a b)
Security and exceptions through constraints
The constraint mechanism is applicable to security issues and for exception control. The following are examples of generic constraints (use parameters).
Division by zero.
We want to intercept divisions by zero, before they occur, and obtain in the variable error the null expression θ if there is no error or a text with the message "Attempt division by zero in exp", being exp the expression to which the division by zero is attempted to be applied. Then stop the process.
〈( (error = θ) ←' (x÷0) → ((error = "Attempt to divide by zero in " x) ■) )〉
In order to avoid memory problems, we want to prevent any sequence x from being of length greater than 1000, by preventing assignments of type (x\i = y) with i greater than 1000.
〈( ((x\i) = θ) ← i>1000 )〉
Advantages of MENTAL in Event-Driven Programming
Events are specified in a high-level language (MENTAL), which reduces complexity, making them easier to understand and maintain. The event paradigm is general, so it allows the development of software systems with this paradigm as a central axis.
It clarifies and generalizes the event concept. Event-driven programming has so far lacked a clear and universally accepted theoretical basis, unlike other paradigms, such as functional programming (based on the lambda calculus) and logic programming (based on Horn clauses).
Events can be of all kinds: to detect errors, to limit expressions, and so on. Actually, it is a meta system, which monitors what happens at the base level (the environment) and performs certain actions associated with events.
It facilitates the cohesion of each software component. Cohesion is the degree of internal connectivity between the elements of a software component.
Allows internal and external events to be specified in the same way. External events are reflected in the environment. Events can refer to any expression in the environment.
It uses a generic mechanism (the generic expression), a mechanism that is a degree of freedom and that is multifunctional. Among other things, it allows specifying independent (parameterized) or weakly coupled components. The coupling is the degree of independence between the components of a software system. The greater the coupling, the greater the complexity. The greater the cohesion, the greater the simplicity. Quality software should have as much cohesion and as little coupling as possible.
Events can be parameterized, i.e. event classes can be defined. And higher order events can be defined.
Addenda
History of events in the software
Events were born in the software world in the early 1980s with the Smalltalk language to keep the parts of a system synchronized. But two were its big drivers: 1) externally, at the user level, the graphical user interfaces of operating systems, such as Microsoft Windows; 2) internally, the emergence of Visual Basic in the early 1990s.
With the advent of the Internet, "push" systems emerged, in which users subscribe to topics that interest them and automatically receive notifications of news.
Classic implementation of an event-driven system
When event-driven programming is used as the only programming paradigm with traditional languages, program execution is determined solely by the process associated with the events. It is implemented as follows:
Code and data initializations are performed.
The events that are contemplated in the system are specified.
An "event loop" is developed, a loop that waits for an event to occur. When it occurs, it invokes the handler associated with that event, which processes it, and goes back to waiting for another event to occur.
For example, interactive word processing programs, spreadsheet programs, drawing programs, presentation programs, etc. are started and wait for the user's actions on the graphical user interface that presents the program.
In MENTAL everything is simpler and more straightforward. There is no need for an event loop because the semantics of the generic expression already performs it implicitly. And the event handler resides in the language code associated with the condition.
While the notion of event is natural, its support in programming languages is often unexpressive, non-generic, and difficult to use. Several languages support (each in its own way) event orientation, such as Visual Basic, Tcl/Tk, Java, Delphi, PowerBuilder, C#, FoxPro, Simula, etc.
Event-driven programming requires programming language-specific support. It is not a generic language resource.
Supported events are primarily associated with user interactivity. Java, for example, includes certain classes oriented to the management of interactions in a user interface.
They also support events restricted to variable values, arithmetic comparison operations and logical conditions.
They also include "listeners", i.e. mechanisms capable of recognizing particular events.
In Artificial Intelligence we do not speak of events, but of "demons", entities that are alert to the occurrence of specific events and that trigger associated actions or processes when they occur.
Bibliography
Bruey, Alfred J. Visual Basic for Beginners: A Project Approach to Event-Driven Programming. Computer Systems Consulting, 1995.
Dahl, Ole-Johan. SIMULA: A language for programming and description of discrete event systems. Norwegian Computing Center, 1966.
Faison, Ted. Event-Based Programming. Taking Events to the Limit. Apress, 2006.
Lozano Tello, Adolfo. Iniciación a la programación usando lenguajes visuales orientados a eventos. Bellisco Ediciones, 2001.
Tucker, A; Noonan, R. Programación guiada por eventos. Capítulo 10 de Lenguajes de Programación. Principios y paradigmas. McGraw Hill/Interamericana de España, S.A.U., 2003.