Telescript Technology: An Introduction to the Language

Copyright 1996 by General Magic.



Introduction

Today's networks&emdash;especially public networks&emdash;pose an insurmountable barrier to the development of communicating applications. These are applications that have a functional need to distribute themselves among both the computers of individual users and the servers, the computers that users share. Such distribution is not possible in practice for reasons of logistics, portability, and safety.

General Magic has developed a software technology that overcomes those barriers. That technology, Telescript™technology, enables the creation of a new breed of value-added network that supports the development of communicating applications by making the entire network an open platform for developers. Although conceived for a new breed of consumer electronics product, the personal intelligent communicator (PIC), Telescript technology is equally at home in more familiar settings, for example, the personal computer.

A companion white paper, Telescript Technology: The Foundation for the Electronic Marketplace, provides a technical overview of the Telescript technology and presents the vision of an electronic marketplace based upon it. A second paper, Telescript Technology: Scenes from the Electronic Marketplace, explores a variety of communicating applications that could, but do not yet, exist. These are scenes from the electronic marketplace of the future. This paper introduces the Telescript language, the central element of the technology. It explains, by example, how the marketplace is constructed.

This paper has four main sections. The first, intended especially for those who haven't read the companion papers, provides an abbreviated overview of Telescript technology. The second provides a description of the Telescript object model, upon which an understanding of any Telescript program depends. The third and fourth sections present and describe two Telescript programs.

Telescript technology will appear initially in products and services offered by Apple, AT&T, Cable & Wireless, France Telecom, Fujitsu, Matsushita, Mitsubishi, Motorola, Northern Telecom, NTT, Oki, Philips, Sanyo, Sony, and Toshiba.


Telescript Technology Overview

The Electronic Marketplace

Telescript technology integrates an electronic world of computers and the networks that link them. This world is filled with Telescript places occupied by Telescript agents. In the electronic world, each place or agent represents an individual or organization in the physical world, its authority. A place's or agent's authority is revealed by its telename, which can't be falsified.

Diagram of the Marketplace

A place, but not an agent, has a teleaddress, which designates the place's location in this electronic world and reveals the authority of the individual or organization operating the computer in which the place is housed.

The typical place is permanently occupied by an agent of the place's authority and temporarily occupied&emdash;visited&emdash;by agents of other authorities. (This situation is so common that the Telescript language allows this one agent's functionality to be incorporated in the place. A separate agent is not required.) A theater ticketing place, for example, might be occupied by a ticketing agent able both to provide information about theater events and to sell tickets to those events. The ticketing place might be visited by agents of other authorities wishing to avail themselves of the service the ticketing agent offers.

A Telescript agent is a computer program&emdash;in modern terms, a software object&emdash;with the unusual ability to transport itself from one place in this electronic world to another. The place to which an agent travels may be either in the same computer as the place from which it travels or in a different computer. In the latter case, the agent's travel involves the use of a network.

An agent travels to obtain a service that is offered remotely. A user's agent, for example, might travel to the ticketing place, from a place in the user's personal communicator, to obtain theater tickets from the ticketing agent. In general, one agent travels to first meet and then interact with another agent. The agents interact programmatically using object-oriented techniques.

We describe the electronic world that Telescript technology enables as an electronic marketplace because it provides a setting in which the agents of the providers and consumers of goods and services can find and interact with one another. Varied forms of electronic commerce are possible as a result.

The Telescript Language

The centerpiece of Telescript technology is a computer language for remote programming developed by General Magic. The Telescript language supplements systems programming languages such as C and C++; it does not replace them. Only the parts of an application that require the ability to move from one place in a network to another&emdash;the agents&emdash;are written in the Telescript language. Telescript technology not only makes such movement possible, but it also makes it safe.

The Telescript language is communication-centric. Just as PostScript™is designed for describing complex images, and Mathematica™for performing complex mathematics, the Telescript language is designed for carrying out complex networking tasks: navigation, transportation, authentication, and so on.

Agents travel using the Telescript language's go instruction. (More preceisely, go is an operation, rather than an instruction.) The agent need merely present a ticket that identifies its destination. An agent executes go to get from one place to another. After an agent executes go, the next instruction in the agent's program is executed at the agent's destination, not at its source. Thus, the Telescript language reduces networking to a single program instruction.

A ticket designates either a particular place by name, any place of a specified authority, any place at a specified address, any place at an address of a specified authority, or any place of a specified class, that is, any place providing a specified service. These constraints can be imposed in combination.

Another instruction available to the Telescript programmer is meet, which enables one agent to meet another. The agent presents a petition, which identifies the agent to be met. An agent executes meet whenever it wants assistance. By meeting, the agents receive references to one another that enable them to interact as peers using object-oriented programming techniques.

A petition designates either a particular agent by name, any agent of a specified authority, or any agent of a specified class, that is, any agent providing a specified service. These constraints can be imposed in combination.

The Telescript Engine

A Telescript agent or place is powerless in the absence of a Telescript engine, which implements the Telescript language by interpreting programs written in it. General Magic has developed two implementations of the Telescript language. One of these two engines is designed for personal intelligent communicators, the other for public services.

Any Telescript engine&emdash;at least conceptually&emdash;has three application program interfaces (APIs) through which the engine draws upon the resources of the computer platform on which it runs. The storage API provides access to the platform's nonvolatile store, which the engine uses to preserve agents in the face of a crash. The transport API provides access to the platform's communication media, which the engine uses to send agents to other engines, and to receive agents from other engines. The external applications API, finally, allows the bulk of an application written, for example, in C to create and interact with the parts written in the Telescript language, the agents and places.


Telescript Object Model

Objects

Like many modern programming languages, the Telescript language is object-oriented. In fact, like the first object-oriented language, Smalltalk, the Telescript language is deeply object-oriented. That is, every piece of information, no matter how small, is an object. Thus, even a Boolean is an object.

The language distinguishes between an object's external interface and its internal implementation of that interface. An object's interface comprises attributes and operations. An attribute, an object itself, is among an object's externally visible characteristics. An object can get or set its own attributes and the public, but not the private, attributes of other objects. An operation is a task that an object performs. An object can request its own operations and the public, but not the private, operations of other objects.

An operation may require objects as arguments and may return a single object as its result. An operation, however, may decide to throw an exception, rather than return. The exception, an object, is caught at a higher level of the Telescript program, to which control is thereby transferred.

An object's implementation comprises properties and methods. A property, an object, is among an object's internal characteristics. An object's properties, collectively, constitute its dynamic state. An object can directly get or set its own properties, but not those of other objects. A method is a procedure that performs a requested operation, or that gets or sets an attribute.

Classes

Like many object-oriented programming languages, the Telescript language focuses on classes. A class is a "slice" of an object's interface, combined with a related "slice" of its implementation. An object is an instance of a class.

Certain classes form a tree whose root is the Object class. Other classes merely adorn the tree. A class's superclasses comprise the root and the classes that lie between the class and the root. A class is a subclass of each superclass. A class may have an immediate implementation superclass that differs from its immediate interface superclass, but this is rare in practice. An object's interface or implementation comprises those of the classes of which the object is a member. An object is a member of its class and its superclasses.

The Telescript language includes many predefined classes, which are general in purpose. In addition, the Telescript programmer can define other, user-defined classes for specific applications. The Telescript programs in this paper define several user-defined classes using a variety of predefined classes. (This paper uses the predefined Agent, Class, Class Name, Dictionary, Event Process, Exceptions, Integer, Meeting Place, Nil, Object, Part Event, Permit, Petition, Place, Resource, String, Teleaddress, Telename, Ticket, and Time classes and various subclasses of Exception (e.g., Key Invalid).)

A class may include both an operation (or attribute), in its interface, and a method for that operation, in its implementation. Any of the class's implementation subclasses, however, may provide methods, too. A method in one class overrides a method in a superclass. By escalating the operation, a method can call upon the overridden method of the most immediate superclass. The "^()" language construct escalates an operation, supplying no arguments.

The initialize operation of the Object class deserves special note. The Engine requests this operation of each new object during the object's construction. The object's class and its implementation superclasses provide methods, as required, to initialize the object's properties. Each method escalates the operation. Thus, all methods are engaged, and all properties are initialized.


The Electronic Warehouse

The two Telescript programs in this paper together enable this scene from the electronic marketplace. A shopping agent, acting for a client, travels to a warehouse place, checks the price of a product of interest to its client, waits if necessary for the price to fall to a client-specified level, and returns, either when the price is at that level or after a client-specified period of time. The scene, while the agent is in the warehouse, is illustrated below.

Diagram of the Electronic Warehouse

This section presents and describes the Telescript program that implements the warehouse. The program takes the form of three user-defined classes: Warehouse, Catalog Entry, and Price Reduction. The following section will present the Telescript program that implements the shopper. Beyond the paper's scope are the construction of the warehouse; the client's construction and commission of the shopper, at the beginning of the scenario that is about to unfold; and the client's debriefing of the shopper, at the scenario's end.

Catalog Entry

The user-defined Catalog Entry class implements each entry of the warehouse's catalog, which lists the products the warehouse offers for sale. Implicitly, this class is a subclass of the predefined Object class.

A catalog entry has two public operations (each is discussed individually later in this section) and two public attributes. The product attribute is the name of the product the catalog entry describes; the price attribute is its price.

CatalogEntry: class =
(
  public
     see initialize
     see adjustPrice
     product: String;
     price: Integer; // cents
  property
     lock: Resource;
);

Constructing a Catalog Entry

The special initialize operation initializes the three properties of each newly constructed catalog entry. The product and price properties, set by the Engine to the operation's arguments, hold the product and price attributes. The lock property is initialized to a new resource by the operation's method.

initialize: op (product: String; price: Integer) = // cents
{
  ^();
  lock = Resource()
};

A catalog entry uses a resource to serialize price modifications made using its adjustPrice operation. A Telescript resource enables the definition of what some languages call critical conditional regions. Here, the resource prevents, for example, the warehouse and an agent of the warehouse's authority from changing a product's price simultaneously and, as a consequence, incorrectly.

Adjusting a Price

The public adjustPrice operation changes the product's price by the percentage supplied as the operation's argument. A positive percentage represents a price increase, a negative percentage a price decrease.

adjustPrice: op (percentage: Integer)
throws ReferenceProtected =
{
  use lock
  {
    price = price + (price*percentage).quotient(100)
  }
};

A catalog entry, as previously mentioned, uses a resource to serialize price modifications. Here the "use" construct excludes one agent (or place) from the block of instructions in braces, so long as another is executing them.

The operation may throw an exception. If the catalog entry is protected from modification, the Engine throws a member of the predefined Reference Protected class. If the shopper tried to change the price, this would be the result.

Warehouse

The user-defined Warehouse class implements the warehouse. This class is a subclass of the predefined Place and Event Process classes.

A warehouse has three public operations; each is discussed individually later in this section.

Warehouse: class (Place, EventProcess) =
(
  public
    see initialize
    see live
    see getCatalog
  property
    catalog: Dictionary[String, CatalogEntry];
);

Constructing the Warehouse

The special initialize operation initializes the one property of a newly constructed warehouse. The catalog property, set by the Engine to the operation's argument, holds the warehouse's catalog. Each catalog key is assumed to equal the product attribute of the corresponding catalog value.

initialize: op (
  catalog: owned Dictionary[String, CatalogEntry]) =
{
  ^()
};

A predefined operation beyond the scope of this paper is used to construct a new place. If an agent or place that is not permitted to construct a warehouse tries to do so, or if the place in which the warehouse is to be erected&emdash;places are nested&emdash;blocks construction, the operation throws an exception.

Operating the Warehouse

The special live operation operates the warehouse on an ongoing basis. On the first of each month, unbeknownst to its customers, the warehouse reduces by 5 percent the price of each product in its catalog.

live: sponsored op (cause: Exception|Nil) =
{
  loop {
    // await the first day of the month
    time: = Time();
    calendarTime: = time.asCalendarTime();
    calendarTime.month = calendarTime.month + 1;
    calendarTime.day = 1;
    *.wait(calendarTime.asTime().interval(time));
 
    // reduce all prices by 5%
    for product: String in catalog
    {
      try { catalog[product].adjustPrice(-5) }
      catch KeyInvalid { }
    };
 
  // make known the price reductions
  *.signalEvent(PriceReduction(), 'occupants)
  }
};

The Engine requests the live operation of each newly constructed place. The operation, in this case, gives the warehouse a life of its own. The warehouse sponsors the operation, that is, performs it under its own authority and subject to its own permit. The operation, on the first of each month, reduces by 5 percent the price of each product the warehouse carries, and signals the event to any agents occupying the warehouse at the time. The "*." construct directs the request for the signalEvent operation to the warehouse itself. A Telescript event is an incident or condition one agent or place reports to another.

Getting the Catalog

The public getCatalog operation returns a reference to the warehouse's catalog. Unless the agent or place requesting the operation is of the warehouse's authority, the reference protects the catalog from modification. The latter is likely, for example, when the shopper requests the operation.

getCatalog: op () Dictionary[String, CatalogEntry] =
{
  if sponsor.name.authority == *.name.authority {catalog}
  else {catalog.protect()@}
};

One agent or place can determine the authority of any other agent or place with which it interacts. Using the "sponsor" construct, the warehouse obtains a reference to the agent (or place) under whose authority the catalog is requested. After comparing its own name attribute to the agent's, the warehouse returns either a protected or an unprotected reference to the catalog.

Price Reduction

The user-defined Price Reduction class implements each event represented by the warehouse's reduction of a product's price. The warehouse notifies any agent that happens to occupy the warehouse at the time of the reduction of such an event. This class is a subclass of the predefined Event class.

PriceReduction: class (Event) = ();


The Electronic Shopper

This section presents and describes the Telescript program that implements the shopper. The program takes the form of two user-defined classes, Shopper and Product Unavailable.

Shopper

The user-defined Shopper class implements the shopper. This class is a subclass of the predefined Agent and Event Process classes.

A shopper has four public operations and two private ones; each is discussed individually later in this section.

Shopper: class (Agent, EventProcess) =
(
  public
    see initialize
    see live
    see meeting
    see getReport
private
    see goShopping
    see goHome
property
    clientName: Telename; // assigned
    desiredProduct: String;
    desiredPrice, actualPrice: Integer; // cents
    exception: Exception|Nil;
);

Constructing the Shopper

The special initialize operation initializes the five properties of a newly constructed shopper. The clientName property, set by the operation's method to the telename of the agent or place requesting the shopper, designates its client. The desiredProduct and desiredPrice properties, set by the Engine to the operation's arguments, hold the name of the desired product and its desired price. The actualPrice property, not set at all initially, holds the actual price of the desired product, if and when the shopper succeeds in its mission. The exception property, set by the operation's method to a nil initially, explains why the shopper failed in its mission, if and when it does.

initialize: op (
  desiredProduct: owned String;
  desiredPrice: Integer) =
{
  ^();
  clientName = sponsor.name.copy()
};

A predefined operation beyond the scope of this paper is used to construct a new agent. If an agent or place that is not permitted to construct a shopper nevertheless tries to do so, or the place the shopper is to initially occupy blocks the shopper's construction, the operation throws an exception.

Operating the Shopper

The special live operation operates the shopper on an ongoing basis. The operation takes the shopper to the warehouse and later brings it home. It does these things using the private goShopping and goHome operations. Eventually, the operation succeeds and, as a result, the agent terminates.

live: sponsored op (cause: Exception|Nil) =
{
  // take note of home
  homeName: = here.name;
  homeAddress: = here.address;
 
  // arrange to get home
  permit: = Permit(
    (if *.permit.age == nil {nil}
    else {(*.permit.age *90).quotient(100)}),
    (if *.permit.charges == nil {nil}
    else {(*.permit.charges*90).quotient(100)})
  );
 
  // go shopping
  restrict permit
  {
    try { *.goShopping(Warehouse.name) }
    catch e: Exception { exception = e }
  }
  catch e: PermitViolated { exception = e };
 
  // go home
  try { *.goHome(homeName, homeAddress) }
  catch Exception { }
};

The Engine requests the live operation of each newly constructed agent. The operation, in this case, gives the shopper a life of its own. Using the "here" construct, the operation records, as variables of the operation's method, the telename and teleaddress of the place to which the shopper must later return. Using the "restrict" construct, the shopper limits itself to 90 percent of its allotted time and money, holding the remaining 10 percent in reserve so that the shopper can get home, even if its work takes more time or money than anticipated. The shopper catches and records exceptions, including the one that would indicate that the shopper had exceeded its self-imposed permit.

Going Shopping

The private goShopping operation is requested of the shopper by the shopper itself. By means of this operation, the shopper goes to the warehouse, checks the price of the desired product, waits, if necessary, either for the price to fall to or below the desired level or for a client-specified period of time to elapse. In the first case, the shopper records the product's actual price.

goShopping: op (warehouse: ClassName)
throws ProductFailure =
{
  // go to the warehouse
  *.go(Ticket(nil, nil, warehouse));
 
  // show an interest in prices
  *.enableEvents(PriceReduction(*.name));
  *.signalEvent(PriceReduction(), 'responder);
  *.enableEvents(PriceReduction(here.name));
 
  // wait for the desired price
  actualPrice = desiredPrice+1;
  while actualPrice > desiredPrice
  {
    *.getEvent(nil, PriceReduction());
    try
    {
      actualPrice =
      here@Warehouse.getCatalog()[desiredProduct].price
    }
    catch KeyInvalid { throw ProductFailure() }
  }
};

This operation takes the shopper to the warehouse using the go operation. The shopper provides a ticket identifying the class of its destination, but it doesn't identify the telename or the teleaddress. In an electronic marketplace of even moderate size, or encompassing two or more warehouses, this approach would not suffice. Arriving at the warehouse, the shopper expresses an interest in the price reduction event, which it knows the warehouse will signal (to prime the pump, the shopper signals itself of one such event). Each time it learns of a price reduction, the shopper checks the price of the desired product and, if the price reduction was insufficient, waits for another.

The operation may throw an exception. If the warehouse doesn't carry the desired product, the Engine throws a member of the user-defined Product Failure class. If the product were nonexistent, this would be the outcome.

Going Home

The private goHome operation is requested of the shopper by the shopper itself. By means of this operation, the shopper goes back to the place it started, where it meets with its client. The meeting gives the client a chance to request the shopper's getReport operation. When the client later parts from the shopper, ending the meeting, the operation succeeds.

goHome: op (homeName: Telename; homeAddress: Teleaddress) =
{
  // drop excess baggage
  *.disableEvents();
  *.clearEvents();
 
  // go home
  *.go(Ticket(homeName, homeAddress));
 
  // meet the client
  *.enableEvents(PartEvent(clientName));
  here@MeetingPlace.meet(Petition(clientName));
 
  // wait for the client to end the meeting
  *.getEvent(nil, PartEvent(clientName))
};

This operation takes the shopper home, again using the go operation. The shopper provides a ticket identifying both the telename and the teleaddress of its destination. Before leaving the warehouse, the shopper withdraws its interest in price reductions; it discards any price reductions of which it may have been notified but upon which it has not yet acted (by discarding any unprocessed signals, the agent lightens its load). Upon arriving home, the shopper meets with its client. The shopper supplies a petition identifying the client by telename. Before requesting the meeting, the shopper arranges to be signaled when the meeting ends and then waits for this to occur.

Meeting with the Shopper

The special meeting operation, which the Engine requests whenever another agent requests a meeting with the shopper, enables the shopper to accept or decline the request. The shopper always does the latter. As previously seen, the shopper itself initiates its eventual meeting with its client.

meeting: sponsored op (
  agent: protected Telename; // assigned
  _class: protected ClassName!;
  petition: protected Petition) Object|Nil
throws MeetingDenied =
{
  throw MeetingDenied();
  nil
};

The operation may throw an exception. Indeed, the shopper throws a member of the predefined Meeting Denied class if it is ever asked for a meeting.

Getting the Shopper's Report

The public getReport operation returns the actual price of the desired product. The actual price is less than or equal to the desired price.

getReport: op () Integer // cents
throws Exception, FeatureUnavailable =
{
  if sponsor.name != clientName
    { throw FeatureUnavailable() };
  if exception != nil
    { throw exception };
  actualPrice
};

The operation may throw an exception. If the agent or place requesting the operation is not the shopper's client, the operation's method throws a member of the predefined Feature Unavailable class. If the shopper failed in its mission, the method throws a member of the predefined Exception class.

Product Unavailable

The user-defined Product Unavailable class implements the exception the shopper may use to report to its client that the desired product proved unavailable at the desired price. This class is a subclass of the predefined Exception class.

ProductUnavailable: class (Exception) = ();


Telescript Products

The Telescript technology is embodied in two products offered by General Magic. Both involve the Telescript engine for services and servers.

The Telescript Developer's Kit (TDK), available for several different platforms, comprises object code for the Telescript engine and for platform-specific implementations of its APIs. This product includes the tools, sample programs, and documentation required to use Telescript technology to create communicating applications. The product is aimed at developers of such applications.

The Service Provider Kit (SPK) includes the tools, sample programs, and documentation required to build, test and deploy Telescript-based public services. This product is targeted at network operators.

Additionally, General Magic has developed a communicating application that enables personal, intelligent, multimedia messaging. Parts of the application run on personal intelligent communicators, the sources and destinations of messages. Other parts run on servers, which house the mailboxes through which messages are routed. This work, along with the Telescript software that underlies it, is the basis for AT&T PersonaLinkSM Services, a consumer messaging service, which began operation in 1994. Arising from this work, additional electronic-mail-specific products will become available from General Magic.