LIEBERMAN(ID:8131/)


Prototyping language based by Malenfant on Lieberman's design


Related languages
Lieberman => LIEBERMAN   Based on

References:
  • Malenfant, J. "On the semantic diversity of delegation-based programming languages" pp215-230 OOPSLA 95 1995 view details Abstract: The prototype-based programming model has always been difficult to characterize precisely. Its basic principle advocates concrete objects as the only mean to model concepts, yet current languages promote methodologies reintroducing abstract constructions to manage efficiently groups of similar objects. In this paper, we propose a rational reconstruction of delegation-based programming languages that identifies programming models going beyond traditional prototypes. We also introduce a new classification of delegation-based languages, which clarifies these models, and we discuss their relative merits. We finally bring to the fore the existence of more and more structured delegation-based languages forming a continuum between pure prototype-based languages and class-based ones. External link: Online copy Extract: Introduction
    Introduction
    Prototype-based programming languages have been proposed more than a decade ago, yet it has been quite difficult to clearly characterize their exact programming model. Part of the difficulty can be attributed to the different semantics they were attributing to the same primitive operations, a problem we dealt with in [5]. But another important source of confusion has been several programming techniques and mechanisms invented to manage groups of similar objects, either in their behavior (e.g. Self's traits objects) or in their representation (e.g. Self's maps). A traits object is a repository for methods (and "semi-global" variables) applying to the whole group of its delegating objects. A map is a descriptor that factors structural information out of objects in a clone family, i.e. a group of structurally identical objects obtained by cloning one another.
    Traits and maps are clearly going against the very notion of prototype-based programming as it has been originally defined, for example by Lieberman [9]. Traits introduce a kind of abstract object while prototype-based languages advocate a programming style based solely on concrete ones. Maps introduce structural descriptors akin to classes, while prototype-based languages were an attempt to build languages around standalone objects only. If indeed traits and maps are alien to pure prototype-based programming, from them emerge a much richer notion of delegation-based programming. In fact, we show that delegation-based languages exhibit much more diversity than it first appeared, because these new mechanisms impose slightly different programming models, which can hardly lie put under the same "prototype-based" hat.
    This paper proposes a new classification of delegation-based programming languages, a class of programming languages defined by Wegner [19]. Our new classification completes the one proposed by Wegner, but also the one presented in the Treaty of Orlando [15] as well as our previous one [5] dealing with the primitives of prototype-based programming. We classify delegation-based programming languages according to the number of different kinds of objects and the number of different kinds of links they manipulate. For example, the parent-of link of delegation is one link manipulated in all delegation-based programming languages. Similarly, a trait-based programming language manipulates two kinds of objects: concrete ones and traits. We propose that the number of kinds of links and objects manipulated in a. language bears important insights into the nature of its programming model. We explore four classes of delegations-based languages: languages with one kind of object and one kind of link, ones with two kinds of objects and one kind of link, ones with two kinds of objects and two kinds of links and finally ones with one kind of object and two kinds of links.
    But what constitutes a new kind of object, and what exactly constitutes a link? To answer these questions, our approach studies both the programming methodology and the semantics of four specific languages: a prototype-based language in the line of Lieberman's first proposal, a trait-based language, a map-based language and a descriptor-based language. Our observations allow us to point out exactly where in the semantics of a language differences appear (or do not appear) between subsets of objects. They also allow us to make clear the participation of a link to the semantics of the language.
    Prototype-based languages have always been criticized for their lack of manifest organization in programs. Our new classification brings to the fore the existence of delegation-based languages with a more and more structured programming model, forming a continuum between pure prototype-based languages and class-based ones. Not only this shows that the organization of a program can be made more explicit without sacrificing an object-centered programming model, it also suggests a step by step (possibly automatic) transformation of prototype-based programs into class-based ones, a programming methodology advocated before [19, 15].
    The rest of the paper is organized as follows. In Section 2. we come back in more details on the prototype-based programming model and justify the introduction of a new terminology, namely object-centered programming, to capture the essence of delegation-based languages. In Section 3. we introduce the basic category of languages with one kind of object and one kind of links, for which we propose a language based on Lieberman's basic assumptions. In this section, we develop the complete syntax and semantics of this language, which will serve as substrate to derive the three other languages. In Sections 4, 5 and 6, we introduce the three other classes in our classification and develop the semantics of three typical languages illustrating each of them. We summarize the classification in Section 7 and we finally close on conclusions and future work.

    Extract: Object-centered programmming
    Object-centered programmming
    Prototype-based programming puts forward the fundamental principle that people's natural way to grasp new concepts is generally to begin by creating concrete examples (objects) rather than abstract descriptions (classes). This philosophical statement led to languages that abandon the traditional view of object-oriented programming, namely class-based languages, in favor of an object-centered model. Prototypes are objects that exist on their own, without classes to describe and create them. They are collections of slots representing both instance variables and methods.
    For example, in Figure 1, a point object ol has four slots named x, y, display and add. The two first slots contain values, and their activation by a message simply returns that value, while the two last ones contain methods, and their activation executes the corresponding method. The chief although not unique way to create new prototypes is clomng, i.e. shallow copying an existing prototype. Cloning has the side effect that, as long as the two clones don't modify the value of their slots, they will share these values. In [5], we have called this form of sharing creation-time sharing, since it lasts for a slot from the cloning until one of the clones changes its value for this slot.
    But there is more to prototype-based languages than solely concrete objects. Inheritance is also traded for delegation, a. mechanism by which an object that cannot answer a message can delegate it to its parent. Delegation is to concrete objects what inheritance is to classes: a mechanism for sharing information. For example, consider the objects Clyde and Fred in Figure 2. If a message legs is sent to Fred, no corresponding slot is found in this object, which therefore delegates the message to Clyde. As with inheritance, delegation does not change the nature of the pseudo-variable self. i.e. the receiver of the message. When sending a message to Fred, a method found in Clyde is applied in the context, of the receiver Fred. In Lieberman's original proposal, delegation is used to make Clyde act as prototypical instance of elephant; using this prototypical instance, we can create Fred differentially by including only the slots that, differ from the prototypical instance and use delegation to share Clyde's default characteristics.
    The prototype-based model is dominated by the properties of delegation. It is tremendously important to understand that with delegation, we no longer share descriptions, as with class inheritance, but rather concrete representations, and so values of slots. In our previous example, if the state of Clyde is modified, so is the state of Fred, simply because Fred shares with Clyde (and with any other object delegating directly or indirectly to Clyde), the values of Clyde's slots. Because this form of sharing lasts as long as the two objects exist (if the delegation link cannot be modified), we have called it life-time sharing.
    Extract: Diversity in delegation-based languages
    Diversity in delegation-based languages
    Another important aspect of prototype-based languages that deserves a more complete treatment, is the lack of any notion of group of objects. Because there are no classes, we cannot speak about the instances of a, class, so there is no clear notion of similar objects, either by their behavior (responding to the same messages) or by their structure (having the same slots). All objects in prototype-based programming are one-of-a-kind. This is the direct consequence of its basic principle, which favors concrete objects over abstractions. But obviously, when similar objects are created, this lack of organization prevents one from making assumptions about them, such as their minimal protocol (something abstract classes nicely give in class-based programming). It also inhibits the efficient representation of families of objects with identical structure, such as the ones created by repeatedly cloning a single prototypical object.
    It's no surprise that facing such needs, mechanisms have been proposed to fill the gap. Self, the prototype-based language that has attracted the largest implementation efforts to date, tackled these issues by inventing traits and maps, as we pointed out earlier. Such constructions are a threat to traditional prototype-based programming because they reintroduce abstractness by the back door. A first reaction could be to say that if abstractness is needed, why not going back to class-ba.sed languages? Unfortunately, there is something no class-based language offers that delegation-based programming do. namely the value sharing among concrete objects. Even though they will not replace class-based languages as mainstream tools in object-oriented programming, delegation-based languages are a valuable addition to the field and have an interesting application niche (interaction languages, user interfaces, etc.). We take the point of view that concrete objects with delegation are the salient features much sought-after in delegation-based programming languages, and therefore we propose a more general notion of object-centered programming to be contrasted with traditional class-centered programming:
    object-centered programming: a programming paradigm where the main activity during program design revolves around the creation of concrete objects.
    class-centered programming: a programming paradigm where the main activity during program design revolves around the creation of classes.
    The important point here is that, designing an object-centered program really implies the creation of concrete objects as the major activity. In this sense, abstractions like traits and maps are to object-centered programming what assignments are to impure functional programing languages like Scheme and ML: an orthogonal feature which nevertheless leaves the programming model dominated by the major paradigm. As Scheme and ML are dominated by their pure functional subset, delegation-based languages must be dominated by their object-centered one. When introducing abstractions in a delegation-based programming language, the designer must be careful not to encourage (or worse, force) programmers to center their design efforts around them, therefore switching to an abstraction-centered programming model (of which class-based programming is simply an instance). We will see below that several strategies can be applied to ensure this: not adding a sharing mechanism among abstractions (no inheritance between maps for example), preventing abstract objects from receiving messages or, creating them automatically. Keeping these restrictions in mind, it becomes possible to introduce more structure in delegation-based programming languages without sacrificing their object-centered programming model. Extract: Languages based on one kind of object and one kind of link
    Languages based on one kind of object and one kind of link
    Wegner divides object-centered programming languages into two classes: object-based languages, corresponding to one kind of object, and no link, and delegation-based languages, i.e. '"classless objects with delegation", the quintessence of languages with one kind of object and one kind of link (the parent-of link). Wegner's classification underestimates the diversity of object-centered programming languages because it is an attempt to characterize the whole space of object-oriented language design. Moreover, at the time of his writing, delegation-based languages were still under-investigated. In this sense, we complete his classification, being more precise in one of his original class.
    Delegation-based languages where the space of objects is completely homogeneous and where delegation is used for sharing, correspond to the usual notion of prototype-based languages. All objects are equally first-class entities: they can be created dynamically, they can be sent a message, they are all mutable, they can be passed as parameters and returned as results. All of them can be used as parent and cloned. We categorize these languages as having one kind of object and one kind of link, namely the parent-of link.
    We illustrate this first category using a minimal language called LIEBERMAN, based on Lieberman's original proposal [9], whose (abstract) syntax appears in Figure 4. This language has standard expressions such as constants (truth values, numerals, characters, strings or symbols), identifiers (accessing the value of let-bound variables), let-expressions, set-expressions (to mutate let-bound variables) and if-expressions for alternatives. Concerning object-centered programming, message passing is accomplished by send-expressions (send e m F") which sends the message m to the object denoted by e with arguments denoted by the expressions list e*. We also have self- and super-expressions, which correspond to traditional message sending to self and super. Creation of objects is accomplished using a clone-expression (clone e), which shallow copies the object denoted by t and returns the new object as result. An alternative way to create objects is the newinitials-expression (newlnitials f (m*) (e*)), which creates a new object with slot names denoted by m* and slot values denoted by the expressions e"; this new object, which is returned as the result of the expression, will have the object denoted by f as parent. The root-expression (root) returns as result the object root, the first object in the system which serves as the root of the delegation tree. Finally, we have method-expressions, akin to lambda-expressions, to create methods.