[Next] [Previous] [Top] [Contents] [Index]

"The Cecil Language: Specification and Rationale"


Object-oriented methods encourage programmers to develop reusable libraries of code. However, multi-methods can pose obstacles to smoothly integrating code that was developed independently. Unlike with singly-dispatched systems, if two classes that subclass a common class are included into a program, it is possible for incompleteness or inconsistency to result. The additional expressiveness and flexibility of multi-methods creates new pitfalls for integration.

Encapsulation and modularity of multi-methods is a related problem. To enable easier program reuse and maintenance, it is often desirable to encapsulate a data structure's implementation. However, in a multiply-dispatched language achieving this encapsulation is less straightforward than it would be in either an abstract data type based language, such as CLU, or a singly dispatched object-oriented language, such as C++ or Smalltalk. In ADT-based or singly-dispatched languages, direct access to an object's representation can be limited to a statically-determined region of the program. An earlier approach to encapsulation in Cecil suffered from the problem that privileged access could always be gained by writing methods that specialized on the desired data structures [Chambers 92b].

The Cecil module system has been designed to support integration of separately developed code, encapsulation, and modular design. This system can restrict access to parts of an implementation to a bounded region of program text while preserving the flexibility of multi-methods. Individual modules can be reasoned about and typechecked in isolation from modules not explicitly imported. Modules can extend existing modules with subclasses, subtypes, and augmenting multi-methods. If any conflicts arise between independent extensions, they are resolved through resolving modules that extend each of the conflicting modules. A simple check for the presence of the necessary resolving modules is all that is needed at link-time to guarantee type safety. Chambers and Leavens describe the Cecil module system in more detail [Chambers and Leavens 94].

The syntax of declarations is extended to support modules as follows:

decl	::=	module_decl
	|	import_decl
	|	let_decl
	|	tp_decl
	|	type_ext_decl
	|	object_decl
	|	obj_ext_decl
	|	predicate_decl
	|	disjoint_decl
	|	cover_decl
	|	divide_decl	
	|	signature_decl
	|	method_decl
	|	field_sig_decl
	|	field_decl
	|	precedence_decl
	|	include_decl
	|	prim_decl
privacy	::=	"public" | "protected" | "private"
module_decl	::=	[privacy] "module" module_name [extension] "{"
		    {friendship | decl} "}" [";"]
extension	::=	"extends" module_names
friendship	::=	"friend" module_names ";"
module_names	::=	module_name {"," module_name}
module_name	::=	name
import_decl	::=	[privacy] "import" ["friend"] module_names ";"

Also, most declarations have an optional privacy annotation allowed.

[The precise semantics of modules is still under development.]