Introduction

The ABS language

ABS is an actor-based, object-oriented, executable modeling language. Its prime features are:

Algebraic user-defined data types and side effect-free functions

All data (except the state of objects and future variables) is immutable, and functions are free of side effects. This makes understanding and reasoning about models easier.

User-defined data types are used for data modeling instead of objects, so ABS models are typically smaller than their Java counterparts.

A syntax that is close to Java

Programmers familiar with Java can easily learn the ABS language.

Distributed, actor-based semantics

Method calls are asynchronous and create a new process in the target. Processes are scheduled cooperatively and run within the scope of one object. Futures are used to synchronize with and get the result of another process.

Interfaces for specifying object behavior

Similar to Java, the behavior of a class is defined by implementing zero or more interfaces with their corresponding methods.

Safe concurrency

Processes run cooperatively within one object and do not have access to other objects’ state, and data structures are immutable. The language semantics avoids most common error causes of concurrent systems (aliasing, insufficient locking).

Distributed computing

The combination of asynchronous method calls, immutability and strong encapsulation makes it easy to model distributed systems.

A formal semantics and compositional proof theory

ABS is designed to be amenable to program analysis and verification. A variety of tools (deadlock checker, resource analysis, formal verification) exist.

Non-goals

Languages are eco-systems, and a language containing all possible features will be easy to use for no one. The following areas are currently under-served by ABS:

Parallel computing

Algorithms relying on multiple processes operating on mutable state, e.g., from the domain of scientific computing, can only be expressed in roundabout ways.

Close-to-the-metal programming

ABS is not designed to be a systems programming language.

The ABS actor and concurrency model

As mentioned, ABS method calls are asynchronous and create a new process in the target, while the caller process continues to run in parallel, as shown in Figure Process call semantics. At point ①, P1 issues an asynchronous call to some object residing on Cog 2. In response, Cog 2 creates a new process P2; P1 and P2 can run in parallel. At point ②, P1 needs the result of the method call and suspends itself. At point ③, P2 finishes and returns a value. Cog 1 then reactivates P1 to continue execution.

Process call semantics

Process call semantics

The paragraph above elides some details. An asynchronous method call produces a future variable, which is used both to synchronize with the callee process and to get the result. Future variables are first-class objects that can be passed along, so several processes can synchronize on the same future.

The processes created by method calls are scheduled cooperatively and run within the scope of the target object, that is, this evaluates to the object. All Objects are contained in a COG (Concurrent Object Group). Each cog runs one process at a time, while processes on different cogs run in parallel, as shown in Figure Processes running inside their cogs. This means that each cog is a unit of concurrency and is in charge of scheduling the processes running on its objects. Each process runs until it suspends itself (see Await (statement) and Unconditional release: suspend) or terminates, at which point the cog chooses the next process to run.

Processes running inside their cogs

Processes running inside their cogs

A new cog is created by creating an object with a new expression (see Figure Creating an object in a new cog).

Creating an object in a new cog

Creating an object in a new cog

An object in an existing cog is created via the new local expression (see Figure Creating an object in the same cog).

Creating an object in the same cog

Creating an object in the same cog

Error propagation and recovery in ABS

ABS models exceptional (unforeseen and erroneous) situations using exceptions. This section gives an overview of the language constructs that deal with exception propagation and recovery.

Exceptions occur when a process cannot continue normal execution, e.g., when trying to divide by zero or when no pattern in a case expression matches the given value. Exceptions can also be thrown by the modeler via the throw statement: Throw. Exceptions thrown implicitly or explicitly are propagated and handled in the same way.

The modeler can define new exceptions; see Exceptions.

Exceptions can be caught and handled locally, i.e., in a lexically enclosing try-catch-finally block in the same method (see Handling exceptions with try-catch-finally). In that case, the process continues execution and will eventually produce a return value to its future.

In case of an unhandled exception, the future of the process does not receive a return value; instead, it will propagate the unhandled exception to the caller (or any process that tries to get its value). When evaluating f.get on a future that carries an exception instead of a normal return value, the exception will be re-thrown; it can be handled as usual via try-catch or left to propagate up the call chain of futures.

Additionally, terminating a process in the middle of execution might leave its object in an inconsistent state. To recover from this, ABS uses recovery blocks (see Classes). Unhandled exceptions are handed to the recovery block, which can take appropriate action to re-establish the class invariant and/or send asynchronous messages to other objects.