1.1. SIMPLICITY, EXPRESSIVENESS, AND PERFORMANCE 7
Support for objects
The bank accounts example illustrates a general point, namely, that in Maude it is very easy to
support objects and distributed object interactions in a completely declarative style with rewrite
rules. Although such object systems are just a particular style of system modules in which object
interactions (through messages or directly between objects) are expressed by rewriting, Maude
provides special support for object-based programming and for fair execution of object-based
applications (see Chapter 8). Furthermore, the Full Maude extension provides special syntax
in object-oriented modules (see Chapter 17). Such modules directly support object-oriented
concepts like objects, messages, classes, and multiple class inheritance. Moreover, the support
for communication with external objects (see Section 8.4) allows Maude objects to interact
by message passing with internet sockets and, through them, with all kinds of other external
objects, such as files, databases, graphical user interfaces, sensors, robots, and so on. All this
is achieved without compromising Maude’s declarative nature: interaction with normal Maude
objects and with external objects can both be programmed with rewrite rules. Using internet
sockets as external objects, it is also easy to develop distributed implementations in Maude,
where a “soup” of objects and messages is not realized just as a multiset data structure in a
single sequential machine, but as a “distributed soup,” with objects and messages in different
machines or in transit.
Reflection
This is a very important feature of Maude. Intuitively, it means that Maude programs can
be metarepresented as data, which can then be manipulated and transformed by appropriate
functions. It also means that there is a systematic causal connection between Maude mod-
ules themselves and their metarepresentations, in the sense that we can either first perform
a computation in a module and then metarepresent its result, or, equivalently, we can first
metarepresent the module and its initial state and then perform the entire computation at the
metalevel. Finally, the metarepresentation process can itself be iterated giving rise to a very
useful reflective tower. Thanks to Maude’s logical semantics (more on this in Section 1.2), all
this is not just some kind of “glorified hacking,” but a precise form of logical reflection with a
well-defined semantics (see Chapter 11 and [25, 26]). There are many important applications
of reflection. Let us mention just three:
• Internal strategies. Since the rewrite rules of a system module can be highly nondeter-
ministic, there may be many possible ways in which they can be applied, leading to quite
different outcomes. In a distributed object system this may be just part of life: provided
some fairness assumptions are respected, any concurrent execution may be acceptable.
But what should be done in a sequential execution? Maude does indeed support two
different fair execution strategies in a built-in way through its rewrite and frewrite
commands (see Section 5.4). But what if we want to use a different strategy for a given
application? The answer is that Maude modules can be executed at the metalevel with
user-definable internal strategies
5
(see Section 11.6). Such internal strategies can be de-
fined by rewrite rules in a metalevel module that guides the possibly nondeterministic
application of the rules in the given “object level” module. This process can be iterated
in the reflective tower. That is, we can define meta-strategies, meta-meta-strategies, and
so on.
• Module algebra. The entire module algebra in which parameterized modules can be com-
posed and instantiated becomes expressible within the logic, and extensible by new mod-
ule operations that transform existing modules metarepresented as data. This is of more
5
That is, internal to Maude’s logic, in the sense of being definable by logical axioms.